mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-23 10:07:59 +02:00
Merge branch 'developer' into jf_h5reader
This commit is contained in:
@ -249,8 +249,8 @@ endif()
|
||||
if(SLS_USE_SANITIZER)
|
||||
target_compile_options(slsProjectOptions INTERFACE -fsanitize=address,undefined -fno-omit-frame-pointer)
|
||||
target_link_libraries(slsProjectOptions INTERFACE -fsanitize=address,undefined)
|
||||
# target_compile_options(slsProjectOptions INTERFACE -fsanitize=thread)
|
||||
# target_link_libraries(slsProjectOptions INTERFACE -fsanitize=thread)
|
||||
#target_compile_options(slsProjectOptions INTERFACE -fsanitize=thread -fno-omit-frame-pointer)
|
||||
#target_link_libraries(slsProjectOptions INTERFACE -fsanitize=thread)
|
||||
endif()
|
||||
|
||||
|
||||
|
@ -63,4 +63,4 @@ html_static_path = ['static']
|
||||
|
||||
|
||||
def setup(app):
|
||||
app.add_stylesheet('css/extra.css') # may also be an URL
|
||||
app.add_css_file('css/extra.css') # may also be an URL
|
||||
|
@ -4,11 +4,54 @@ Command line interface
|
||||
Usage
|
||||
-------------
|
||||
|
||||
Commands can be used either with sls_detector_get or sls_detector_put
|
||||
The syntax is *'[detector index]-[module index]:[command]'*, where the indices are by default '0', when not specified.
|
||||
|
||||
Module index
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Modules are indexed based on their order in the hostname command. They are used to configure a specific module within a detector and are followed by a ':' in syntax.
|
||||
|
||||
.. code-block::
|
||||
|
||||
# Applies to all modules of detector 0
|
||||
sls_detector_put exptime 5s
|
||||
|
||||
# Applies to only the 4th module
|
||||
sls_detector_put 3:exptime 5s
|
||||
|
||||
|
||||
Detector index
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
This index is useful when configuring multiple detectors from a single host. Each detector uses a unique shared memory identified by a detector index, derived again from the hostname command. It is followed by a '-'.
|
||||
|
||||
.. code-block::
|
||||
|
||||
# For detector with index 2 in shared memory
|
||||
sls_detector_put 2-hostname bchip133+bchip123+bchip456
|
||||
|
||||
# Without '-', the detector index defaults to 0
|
||||
sls_detector_put hostname bchip133+bchip123+bchip456
|
||||
|
||||
# Accessing all modules with detector index 2
|
||||
sls_detector_put 2-exptime
|
||||
|
||||
# Starting acquisition only for detector with index 2
|
||||
sls_detector_put 2-start
|
||||
|
||||
# Applies only to the 2nd detector, 4th module
|
||||
sls_detector_put 1-3:exptime 5s
|
||||
|
||||
|
||||
Command Execution
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Commands can be executed using:
|
||||
|
||||
* **sls_detector_put**: setting values
|
||||
* **sls_detector_get**: getting values
|
||||
* **sls_detector**: automatically infers based on the number of arguments.
|
||||
* **sls_detector_help**: gets help on the specific command
|
||||
* **sls_detector_acquire**: initiates acquisition with the detector. This command blocks until the entire acquisition process is completed.
|
||||
|
||||
.. code-block::
|
||||
|
||||
sls_detector_get exptime
|
||||
|
||||
Help
|
||||
--------
|
||||
@ -28,12 +71,15 @@ Help
|
||||
# list of deprecated commands
|
||||
list deprecated
|
||||
|
||||
# autocompletion
|
||||
# bash_autocomplete.sh or zsh_autocomplete.sh must be sourced from the
|
||||
# main package folder to enable auto completion of commands and arguments
|
||||
# for the command line on that shell.
|
||||
source bash_autocomplete.sh
|
||||
|
||||
Autocompletion
|
||||
---------------
|
||||
|
||||
bash_autocomplete.sh or zsh_autocomplete.sh must be sourced from the main package folder to enable auto completion of commands and arguments for the command line on that shell.
|
||||
|
||||
.. code-block::
|
||||
|
||||
source bash_autocomplete.sh
|
||||
|
||||
|
||||
Commands
|
||||
|
@ -13,7 +13,6 @@ containing results from all modules. (:ref:`Result class<Result Class>`)
|
||||
|
||||
Here are some :ref:`examples <Cplusplus Api Examples>` on how to use the API.
|
||||
|
||||
.. _Cplusplus Api Examples:
|
||||
.. doxygenclass:: sls::Detector
|
||||
:members:
|
||||
:undoc-members:
|
@ -39,7 +39,7 @@ Welcome to slsDetectorPackage's documentation!
|
||||
|
||||
.. toctree::
|
||||
:caption: Command line
|
||||
:maxdepth: 2
|
||||
:maxdepth: 1
|
||||
|
||||
commandline
|
||||
quick_start_guide
|
||||
|
@ -1,5 +1,6 @@
|
||||
|
||||
.. _master file attributes:
|
||||
|
||||
Master File Attributes
|
||||
=======================
|
||||
|
||||
|
@ -128,6 +128,10 @@ For Multiple Modules
|
||||
# set file path
|
||||
fpath /tmp
|
||||
|
||||
.. note ::
|
||||
The **hostname** and **detsize** command in a multi module system can affect the row and column values in the udp/zmq header. The modules are stacked row by row until they reach the y-axis limit set by detsize (if specified). Then, stacking continues in the next column and so on.
|
||||
|
||||
|
||||
Gui
|
||||
----
|
||||
|
||||
|
@ -39,13 +39,13 @@ Arguments
|
||||
|
||||
|
||||
.. _Automatic start servers:
|
||||
|
||||
Automatic start
|
||||
------------------
|
||||
|
||||
One can start the on-board detector server automatically upon powering on the board.
|
||||
|
||||
#. Create a soft link to the binary on board
|
||||
:
|
||||
#. Create a soft link to the binary on board:
|
||||
.. code-block:: bash
|
||||
|
||||
ln -sf someDetectorServervx.x.x someDetectorServer
|
||||
@ -87,8 +87,7 @@ One can start the on-board detector server automatically upon powering on the bo
|
||||
/root/xxxDetectorServer >> /dev/null &
|
||||
|
||||
|
||||
#. Sync, reboot and verify
|
||||
:
|
||||
#. Sync, reboot and verify:
|
||||
.. code-block:: bash
|
||||
|
||||
sync
|
||||
|
@ -73,9 +73,9 @@ Description
|
||||
|
||||
* **modId**: module ID picked up from det_id_[detector type].txt on the detector cpu.
|
||||
|
||||
* **row**: row position of the module in the detector system. It is calculated by the order of the module in hostname command, as well as the detsize command.
|
||||
* **row**: row position of the module in the detector system. It is calculated by the order of the module in hostname command, as well as the detsize command. The modules are stacked row by row until they reach the y-axis limit set by detsize (if specified). Then, stacking continues in the next column and so on.
|
||||
|
||||
* **column**: column position of the module in the detector system. It is calculated by the order of the module in hostname command, as well as the detsize command.
|
||||
* **column**: column position of the module in the detector system. It is calculated by the order of the module in hostname command, as well as the detsize command. The modules are stacked row by row until they reach the y-axis limit set by detsize (if specified). Then, stacking continues in the next column and so on.
|
||||
|
||||
* **detType**: detector type from enum of detectorType in the package.
|
||||
|
||||
|
19
python/scripts/frameSynchronizerPullSocket.py
Normal file
19
python/scripts/frameSynchronizerPullSocket.py
Normal file
@ -0,0 +1,19 @@
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
# Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
# Script to get combined zmq packets from frame synchronizer using pull zmq sockets
|
||||
import json
|
||||
import zmq
|
||||
|
||||
c = zmq.Context()
|
||||
s = c.socket(zmq.PULL)
|
||||
s.connect("tcp://127.0.0.1:5555")
|
||||
|
||||
while True:
|
||||
m = s.recv_multipart()
|
||||
for p in m:
|
||||
if p.startswith(b"{"):
|
||||
print(p.decode().strip())
|
||||
else:
|
||||
print("binary")
|
||||
print("--------")
|
||||
|
@ -123,6 +123,9 @@ def visit(node):
|
||||
if node.kind == cindex.CursorKind.CLASS_DECL:
|
||||
if node.displayname == "Detector":
|
||||
for child in node.get_children():
|
||||
# Skip assignment operators
|
||||
if child.kind == cindex.CursorKind.CXX_METHOD and child.spelling == "operator=":
|
||||
continue
|
||||
if (
|
||||
child.kind == cindex.CursorKind.CXX_METHOD
|
||||
and child.access_specifier == cindex.AccessSpecifier.PUBLIC
|
||||
|
@ -151,6 +151,10 @@ class Detector(CppDetectorApi):
|
||||
def hostname(self):
|
||||
"""Frees shared memory and sets hostname (or IP address) of all modules concatenated by +
|
||||
Virtual servers can already use the port in hostname separated by ':' and ports incremented by 2 to accomodate the stop server as well.
|
||||
|
||||
Note
|
||||
-----
|
||||
The row and column values in the udp/zmq header are affected by the order in this command and the detsize command. The modules are stacked row by row until they reach the y-axis limit set by detsize (if specified). Then, stacking continues in the next column and so on. This only affects row and column in udp/zmq header.
|
||||
|
||||
Example
|
||||
-------
|
||||
@ -2566,7 +2570,7 @@ class Detector(CppDetectorApi):
|
||||
|
||||
Note
|
||||
-----
|
||||
By default, the on-chip gain switching is active during the entire exposure. This mode disables the on-chip gain switching comparator automatically after 93.75% of exposure time (only for longer than 100us). The % is only for chipv1.0, the duration can be set for chipv1.1.\n
|
||||
By default, the on-chip gain switching is active during the entire exposure. This mode disables the on-chip gain switching comparator automatically and the duration is set using compdisabletime.\n
|
||||
Default is 0 or this mode disabled (comparator enabled throughout). 1 enables mode. 0 disables mode.
|
||||
"""
|
||||
return self.getAutoComparatorDisable()
|
||||
@ -2580,10 +2584,6 @@ class Detector(CppDetectorApi):
|
||||
def compdisabletime(self):
|
||||
"""[Jungfrau] Time before end of exposure when comparator is disabled.
|
||||
|
||||
Note
|
||||
-----
|
||||
It is only possible for chipv1.1.
|
||||
|
||||
:getter: always returns in seconds. To get in DurationWrapper, use getComparatorDisableTime
|
||||
|
||||
Example
|
||||
@ -2913,7 +2913,7 @@ class Detector(CppDetectorApi):
|
||||
@property
|
||||
@element
|
||||
def timing_info_decoder(self):
|
||||
"""[Jungfrau] [Jungfrau] Advanced Command and only for SWISSFEL and SHINE. Sets the bunch id or timing info decoder. Default is SWISSFEL.
|
||||
"""[Jungfrau] [Jungfrau] Advanced Command and only for SWISSFEL and SHINE. Sets the bunch id or timing info decoder. Default is SWISSFEL. Only allowed for pcbv2.0.
|
||||
Enum: timingInfoDecoder
|
||||
"""
|
||||
return self.getTimingInfoDecoder()
|
||||
|
1
serverBin/xilinx_ctbDetectorServer_developer
Symbolic link
1
serverBin/xilinx_ctbDetectorServer_developer
Symbolic link
@ -0,0 +1 @@
|
||||
../slsDetectorServers/xilinx_ctbDetectorServer/bin/xilinx_ctbDetectorServer_developer
|
@ -572,6 +572,7 @@ class singlePhotonDetector : public analogDetector<uint16_t> {
|
||||
}
|
||||
#endif
|
||||
if (ee == PHOTON && val[iy * nx + ix] == max) {
|
||||
good = 1;
|
||||
ee = PHOTON_MAX;
|
||||
// cout << "**" <<id<< " " << iframe << " " << nDark << " "
|
||||
// << ix << " " << iy << " " << rms << " " << max << " " <<
|
||||
@ -605,7 +606,6 @@ class singlePhotonDetector : public analogDetector<uint16_t> {
|
||||
cout << max << " " << val[iy * nx + ix] << endl;
|
||||
}
|
||||
//else (clusters + nph)->print();
|
||||
good = 1;
|
||||
if (eMin > 0 && tot < eMin)
|
||||
good = 0;
|
||||
if (eMax > 0 && tot > eMax)
|
||||
|
Binary file not shown.
@ -1974,9 +1974,6 @@ int autoCompDisable(int on) {
|
||||
}
|
||||
|
||||
int setComparatorDisableTime(int64_t val) {
|
||||
if (getChipVersion() != 11) {
|
||||
return FAIL;
|
||||
}
|
||||
if (val < 0) {
|
||||
LOG(logERROR,
|
||||
("Invalid comp disable time: %lld ns\n", (long long int)val));
|
||||
@ -2817,7 +2814,8 @@ void *start_timer(void *arg) {
|
||||
getNextFrameNumber(&frameNr);
|
||||
int iRxEntry = firstDest;
|
||||
for (int iframes = 0; iframes != numFrames; ++iframes) {
|
||||
usleep(transmissionDelayUs);
|
||||
if (transmissionDelayUs)
|
||||
usleep(transmissionDelayUs);
|
||||
|
||||
// check if manual stop
|
||||
if (sharedMemory_getStop() == 1) {
|
||||
|
@ -1927,7 +1927,8 @@ void *start_timer(void *arg) {
|
||||
getNextFrameNumber(&frameNr);
|
||||
int iRxEntry = firstDest;
|
||||
for (int iframes = 0; iframes != numFrames; ++iframes) {
|
||||
usleep(transmissionDelayUs);
|
||||
if (transmissionDelayUs)
|
||||
usleep(transmissionDelayUs);
|
||||
|
||||
// check if manual stop
|
||||
if (sharedMemory_getStop() == 1) {
|
||||
|
Binary file not shown.
@ -50,7 +50,7 @@
|
||||
#define DEFAULT_NUM_CYCLES (1)
|
||||
#define DEFAULT_GATE_WIDTH (100 * 1000 * 1000) // ns
|
||||
#define DEFAULT_GATE_DELAY (0)
|
||||
#define DEFAULT_PERIOD (2 * 1000 * 1000) // ns
|
||||
#define DEFAULT_PERIOD (0) // ns
|
||||
#define DEFAULT_DELAY_AFTER_TRIGGER (0)
|
||||
#define DEFAULT_HIGH_VOLTAGE (0)
|
||||
#define DEFAULT_TIMING_MODE (AUTO_TIMING)
|
||||
|
@ -197,6 +197,8 @@ int isChipConfigured();
|
||||
int powerChip(int on, char *mess);
|
||||
int getPowerChip();
|
||||
int configureChip(char *mess);
|
||||
int readConfigFile(char *mess, char *fileName, char *fileType);
|
||||
int resetChip(char *mess);
|
||||
#endif
|
||||
#if defined(JUNGFRAUD) || defined(MOENCHD) || defined(CHIPTESTBOARDD) || \
|
||||
defined(MYTHEN3D) || defined(GOTTHARD2D)
|
||||
@ -742,8 +744,7 @@ int softwareTrigger();
|
||||
#if defined(EIGERD) || defined(JUNGFRAUD) || defined(MOENCHD)
|
||||
int softwareTrigger(int block);
|
||||
#endif
|
||||
#if defined(EIGERD) || defined(MYTHEN3D) || defined(CHIPTESTBOARDD) || \
|
||||
defined(XILINX_CHIPTESTBOARDD)
|
||||
#if defined(EIGERD) || defined(MYTHEN3D) || defined(CHIPTESTBOARDD)
|
||||
int startReadOut();
|
||||
#endif
|
||||
enum runStatus getRunStatus();
|
||||
|
@ -853,7 +853,7 @@ int loadPattern(char *message, enum TLogLevel printLevel,
|
||||
}
|
||||
}
|
||||
// iocontrol
|
||||
#if !defined(MYTHEN3D) && !defined(XILINX_CHIPTESTBOARDD) // TODO
|
||||
#if !defined(MYTHEN3D)
|
||||
if (ret == OK) {
|
||||
ret = validate_writePatternIOControl(message, pat->ioctrl);
|
||||
}
|
||||
@ -914,7 +914,7 @@ int getPattern(char *message, patternParameters *pat) {
|
||||
pat->word[i] = retval64;
|
||||
}
|
||||
// iocontrol
|
||||
#if !defined(MYTHEN3D) && !defined(XILINX_CHIPTESTBOARDD) // TODO
|
||||
#if !defined(MYTHEN3D)
|
||||
if (ret == OK) {
|
||||
validate_readPatternIOControl();
|
||||
}
|
||||
@ -1051,12 +1051,12 @@ int loadPatternFile(char *patFname, char *errMessage) {
|
||||
}
|
||||
|
||||
// patioctrl
|
||||
#if !defined(MYTHEN3D) && !defined(XILINX_CHIPTESTBOARDD) // TODO
|
||||
#if !defined(MYTHEN3D) // TODO
|
||||
if (!strncmp(line, "patioctrl", strlen("patioctrl"))) {
|
||||
uint64_t arg = 0;
|
||||
|
||||
// cannot scan values
|
||||
#ifdef VIRTUAL
|
||||
#if defined(VIRTUAL) || defined(XILINX_CHIPTESTBOARDD)
|
||||
if (sscanf(line, "%s 0x%lx", command, &arg) != 2) {
|
||||
#else
|
||||
if (sscanf(line, "%s 0x%llx", command, &arg) != 2) {
|
||||
|
@ -8467,8 +8467,7 @@ int get_bursts_left(int file_des) {
|
||||
int start_readout(int file_des) {
|
||||
ret = OK;
|
||||
memset(mess, 0, sizeof(mess));
|
||||
#if !defined(MYTHEN3D) && !defined(CHIPTESTBOARDD) && \
|
||||
!defined(XILINX_CHIPTESTBOARDD)
|
||||
#if !defined(MYTHEN3D) && !defined(CHIPTESTBOARDD)
|
||||
functionNotImplemented();
|
||||
#else
|
||||
if (Server_VerifyLock() == OK) {
|
||||
@ -9098,16 +9097,9 @@ int get_comp_disable_time(int file_des) {
|
||||
functionNotImplemented();
|
||||
#else
|
||||
// get only
|
||||
if (getChipVersion() != 11) {
|
||||
ret = FAIL;
|
||||
strcpy(mess,
|
||||
"Cannot get comparator disable time. Only valid for chipv1.1\n");
|
||||
LOG(logERROR, (mess));
|
||||
} else {
|
||||
retval = getComparatorDisableTime();
|
||||
LOG(logDEBUG1,
|
||||
("retval comp disable time %lld ns\n", (long long int)retval));
|
||||
}
|
||||
retval = getComparatorDisableTime();
|
||||
LOG(logDEBUG1,
|
||||
("retval comp disable time %lld ns\n", (long long int)retval));
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT64, &retval, sizeof(retval));
|
||||
}
|
||||
@ -9125,23 +9117,16 @@ int set_comp_disable_time(int file_des) {
|
||||
#else
|
||||
// only set
|
||||
if (Server_VerifyLock() == OK) {
|
||||
if (getChipVersion() != 11) {
|
||||
ret = FAIL;
|
||||
strcpy(mess, "Cannot get comparator disable time. Only valid for "
|
||||
"chipv1.1\n");
|
||||
ret = setComparatorDisableTime(arg);
|
||||
int64_t retval = getComparatorDisableTime();
|
||||
LOG(logDEBUG1,
|
||||
("retval get comp disable time %lld ns\n", (long long int)retval));
|
||||
if (ret == FAIL) {
|
||||
sprintf(mess,
|
||||
"Could not set comp disable time. Set %lld ns, read "
|
||||
"%lld ns.\n",
|
||||
(long long int)arg, (long long int)retval);
|
||||
LOG(logERROR, (mess));
|
||||
} else {
|
||||
ret = setComparatorDisableTime(arg);
|
||||
int64_t retval = getComparatorDisableTime();
|
||||
LOG(logDEBUG1, ("retval get comp disable time %lld ns\n",
|
||||
(long long int)retval));
|
||||
if (ret == FAIL) {
|
||||
sprintf(mess,
|
||||
"Could not set comp disable time. Set %lld ns, read "
|
||||
"%lld ns.\n",
|
||||
(long long int)arg, (long long int)retval);
|
||||
LOG(logERROR, (mess));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -11144,6 +11129,12 @@ int set_timing_info_decoder(int file_des) {
|
||||
modeNotImplemented("Timing info decoder index", (int)arg);
|
||||
break;
|
||||
}
|
||||
if (ret == OK && isHardwareVersion_1_0()) {
|
||||
ret = FAIL;
|
||||
sprintf(mess, "Could not set timing info decoder. Not supported "
|
||||
"for hardware version 1.0\n");
|
||||
LOG(logERROR, (mess));
|
||||
}
|
||||
if (ret == OK) {
|
||||
ret = setTimingInfoDecoder(arg);
|
||||
if (ret == FAIL) {
|
||||
|
@ -40,3 +40,9 @@ set_target_properties(xilinx_ctbDetectorServer_virtual PROPERTIES
|
||||
install(TARGETS xilinx_ctbDetectorServer_virtual
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
|
||||
configure_file(chip_config_xilinx.txt ${CMAKE_BINARY_DIR}/bin/chip_config_xilinx.txt COPYONLY)
|
||||
configure_file(reset_chip_xilinx.txt ${CMAKE_BINARY_DIR}/bin/reset_chip_xilinx.txt COPYONLY)
|
||||
configure_file(enable_clock_pattern.pyat ${CMAKE_BINARY_DIR}/bin/enable_clock_pattern.pyat COPYONLY)
|
||||
configure_file(readout_pattern.pyat ${CMAKE_BINARY_DIR}/bin/readout_pattern.pyat COPYONLY)
|
||||
|
||||
|
@ -48,6 +48,10 @@ $(PROGS): $(OBJS)
|
||||
mkdir -p $(DESTDIR)
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LDLIBS)
|
||||
mv $(PROGS) $(DESTDIR)
|
||||
cp chip_config_xilinx.txt $(DESTDIR)
|
||||
cp reset_chip_xilinx.txt $(DESTDIR)
|
||||
cp enable_clock_pattern.pyat $(DESTDIR)
|
||||
cp readout_pattern.pyat $(DESTDIR)
|
||||
rm $(main_src)*.o $(md5_dir)*.o
|
||||
clean:
|
||||
rm -rf $(DESTDIR)/$(PROGS) *.o *.gdb $(main_src)*.o $(md5_dir)*.o
|
||||
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -0,0 +1,24 @@
|
||||
# Prepare MH02 configuration
|
||||
reg 0xB1B0 0x00000041
|
||||
reg 0xB1B4 0x01200004
|
||||
|
||||
# configure Matterhorn SPI
|
||||
setbit 0xB1B8 0
|
||||
|
||||
# wait till config is done
|
||||
pollbit 0xB1B8 3 0
|
||||
|
||||
# reset transceiver
|
||||
reg 0xB820 0x0
|
||||
reg 0xB820 0x1
|
||||
reg 0xB820 0x0
|
||||
|
||||
# set MSB LSB inversions and polarity for transceiver
|
||||
reg 0xB820 0x61e0
|
||||
|
||||
# Enable MH02 PLL clock
|
||||
pattern enable_clock_pattern.pyat
|
||||
# start the flow
|
||||
setbit 0xB004 0
|
||||
clearbit 0xB004 0
|
||||
sleep 1
|
@ -0,0 +1,8 @@
|
||||
patword 0x0000 0x0000000000000000
|
||||
patword 0x0001 0x0000000000008000
|
||||
patword 0x0002 0x0000000000008000
|
||||
patword 0x0003 0x0000000000008000
|
||||
patword 0x0004 0x0000000000008000
|
||||
patword 0x0005 0x0000000000008000
|
||||
patioctrl 0x01b3ffff
|
||||
patlimits 0x0000 0x0005
|
@ -0,0 +1,22 @@
|
||||
patword 0x0000 0x0000000000008000
|
||||
patword 0x0001 0x0000000000008000
|
||||
patword 0x0002 0x0000000000008000
|
||||
patword 0x0003 0x0000000000008000
|
||||
patword 0x0004 0x0000000000008000
|
||||
patword 0x0005 0x0000000000008000
|
||||
patword 0x0006 0x0000000000008000
|
||||
patword 0x0007 0x0000000000008000
|
||||
patword 0x0008 0x0000000000008000
|
||||
patword 0x0009 0x0000000000008000
|
||||
patword 0x000a 0x0000000000008000
|
||||
patword 0x000b 0x0000000000108000
|
||||
patword 0x000c 0x0000000000108000
|
||||
patword 0x000d 0x0000000000108000
|
||||
patword 0x000e 0x0000000000108000
|
||||
patword 0x000f 0x0000000000008000
|
||||
patword 0x0010 0x0000000000008000
|
||||
patword 0x0011 0x0000000000008000
|
||||
patword 0x0012 0x0000000000008000
|
||||
patword 0x0013 0x0000000000008000
|
||||
patioctrl 0x01b3ffff
|
||||
patlimits 0x0000 0x0013
|
@ -0,0 +1,40 @@
|
||||
|
||||
# turn off clock
|
||||
setbit 0xB1B0 16
|
||||
setbit 0xB1B8 0
|
||||
sleep 1
|
||||
|
||||
# reset Matterhorn periphery
|
||||
setbit 0xB1B8 1
|
||||
sleep 1
|
||||
|
||||
# turn on clock
|
||||
clearbit 0xB1B0 16
|
||||
setbit 0xB1B8 0
|
||||
sleep 1
|
||||
|
||||
# reset rx transceiver datapath
|
||||
setbit 0xB820 4
|
||||
sleep 1
|
||||
|
||||
# reset 8b10b counters
|
||||
setbit 0xB820 9
|
||||
setbit 0xB820 10
|
||||
setbit 0xB820 11
|
||||
setbit 0xB820 12
|
||||
sleep 1
|
||||
clearbit 0xB820 9
|
||||
clearbit 0xB820 10
|
||||
|
||||
# reset buffer fifos
|
||||
reg 0x9024 0xFFFFFFFF
|
||||
reg 0x9028 0xFFFFFFFF
|
||||
reg 0x902C 0xFFFFFFFF
|
||||
reg 0x9024 0x0
|
||||
reg 0x9028 0x0
|
||||
reg 0x902C 0x0
|
||||
setbit 0xA000 18
|
||||
|
||||
# load default pattern
|
||||
pattern readout_pattern.pyat
|
||||
|
@ -492,7 +492,16 @@ void setTransceiverAlignment(int align) {
|
||||
#endif
|
||||
|
||||
int isTransceiverAligned() {
|
||||
return (bus_r(TRANSCEIVERSTATUS) & RXBYTEISALIGNED_MSK);
|
||||
int times = 0;
|
||||
int retval = bus_r(TRANSCEIVERSTATUS2) & RXLOCKED_MSK;
|
||||
while (retval) {
|
||||
retval = bus_r(TRANSCEIVERSTATUS2) & RXLOCKED_MSK;
|
||||
times++;
|
||||
usleep(10);
|
||||
if (times == 5)
|
||||
return 1;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int waitTransceiverAligned(char *mess) {
|
||||
@ -511,7 +520,9 @@ int waitTransceiverAligned(char *mess) {
|
||||
int times = 0;
|
||||
while (transceiverWordAligned == 0) {
|
||||
if (times++ > WAIT_TIME_OUT_0US_TIMES) {
|
||||
sprintf(mess, "Transceiver alignment timed out\n");
|
||||
sprintf(mess, "Transceiver alignment timed out. Check connection, "
|
||||
"p-n inversions, LSB-MSB inversions, link error "
|
||||
"counters and channel enable settings\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
@ -587,34 +598,197 @@ int getPowerChip() {
|
||||
|
||||
int configureChip(char *mess) {
|
||||
LOG(logINFOBLUE, ("\tConfiguring chip\n"));
|
||||
|
||||
// enable correct endianness (Only for MH_PR_2)
|
||||
// uint32_t addr = MATTERHORNSPIREG1;
|
||||
// bus_w(addr, bus_r(addr) &~MATTERHORNSPI1_MSK);
|
||||
// bus_w(addr, bus_r(addr) | ((0x40000 << MATTERHORNSPI1_OFST) &
|
||||
// MATTERHORNSPI1_MSK));
|
||||
|
||||
// start configuration
|
||||
uint32_t addr = MATTERHORNSPICTRL;
|
||||
bus_w(addr, bus_r(addr) | CONFIGSTART_P_MSK);
|
||||
bus_w(addr, bus_r(addr) & ~CONFIGSTART_P_MSK);
|
||||
|
||||
// wait until configuration is done
|
||||
#ifndef VIRTUAL
|
||||
int configDone = (bus_r(MATTERHORNSPICTRL) & BUSY_MSK);
|
||||
int times = 0;
|
||||
while (configDone == 0) {
|
||||
if (times++ > WAIT_TIME_OUT_0US_TIMES) {
|
||||
sprintf(mess, "Configuration of chip timed out\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
usleep(0);
|
||||
configDone = (bus_r(MATTERHORNSPICTRL) & BUSY_MSK);
|
||||
chipConfigured = 0;
|
||||
if (readConfigFile(mess, CONFIG_CHIP_FILE, "chip config") == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
#endif
|
||||
if (readConfigFile(mess, RESET_CHIP_FILE, "reset chip") == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFOBLUE, ("Chip configured.\n"));
|
||||
chipConfigured = 1;
|
||||
LOG(logINFOBLUE, ("\tChip configured\n"));
|
||||
return OK;
|
||||
}
|
||||
|
||||
int readConfigFile(char *mess, char *fileName, char *fileType) {
|
||||
const int fileNameSize = 128;
|
||||
char fname[fileNameSize];
|
||||
if (getAbsPath(fname, fileNameSize, fileName) == FAIL) {
|
||||
sprintf(mess, "Could not get full path for %s file [%s].\n", fileType,
|
||||
fname);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
if (access(fname, F_OK) != 0) {
|
||||
sprintf(mess, "Could not find %s file [%s].\n", fileType, fname);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
FILE *fd = fopen(fname, "r");
|
||||
if (fd == NULL) {
|
||||
sprintf(mess, "Could not open on-board detector server %s file [%s].\n",
|
||||
fileType, fname);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFOBLUE, ("Reading %s file %s\n", fileType, fname));
|
||||
|
||||
const size_t LZ = 256;
|
||||
char line[LZ];
|
||||
memset(line, 0, LZ);
|
||||
char command[LZ];
|
||||
|
||||
// keep reading a line
|
||||
while (fgets(line, LZ, fd)) {
|
||||
|
||||
// ignore comments
|
||||
if (line[0] == '#') {
|
||||
LOG(logDEBUG1, ("Ignoring Comment\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
// ignore empty lines
|
||||
if (strlen(line) <= 1) {
|
||||
LOG(logDEBUG1, ("Ignoring Empty line\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
// removing leading spaces
|
||||
if (line[0] == ' ' || line[0] == '\t') {
|
||||
int len = strlen(line);
|
||||
// find first valid character
|
||||
int i = 0;
|
||||
for (i = 0; i < len; ++i) {
|
||||
if (line[i] != ' ' && line[i] != '\t') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// ignore the line full of spaces (last char \n)
|
||||
if (i >= len - 1) {
|
||||
LOG(logDEBUG1, ("Ignoring line full of spaces\n"));
|
||||
continue;
|
||||
}
|
||||
// copying only valid char
|
||||
char temp[LZ];
|
||||
memset(temp, 0, LZ);
|
||||
memcpy(temp, line + i, strlen(line) - i);
|
||||
memset(line, 0, LZ);
|
||||
memcpy(line, temp, strlen(temp));
|
||||
LOG(logDEBUG1, ("Removing leading spaces.\n"));
|
||||
}
|
||||
|
||||
LOG(logDEBUG1, ("Command to process: (size:%d) %.*s\n", strlen(line),
|
||||
strlen(line) - 1, line));
|
||||
memset(command, 0, LZ);
|
||||
|
||||
// reg command
|
||||
if (!strncmp(line, "reg", strlen("reg"))) {
|
||||
uint32_t addr = 0;
|
||||
uint32_t val = 0;
|
||||
if (sscanf(line, "%s %x %x", command, &addr, &val) != 3) {
|
||||
sprintf(mess, "Could not scan reg command. Line:[%s].\n", line);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
bus_w(addr, val);
|
||||
LOG(logINFOBLUE, ("Wrote 0x%x to 0x%x\n", val, addr));
|
||||
}
|
||||
|
||||
// setbit command
|
||||
else if (!strncmp(line, "setbit", strlen("setbit"))) {
|
||||
uint32_t addr = 0;
|
||||
uint32_t bit = 0;
|
||||
if (sscanf(line, "%s %x %d", command, &addr, &bit) != 3) {
|
||||
sprintf(mess, "Could not scan setbit command. Line:[%s].\n",
|
||||
line);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
bus_w(addr, bus_r(addr) | (1 << bit));
|
||||
LOG(logINFOBLUE, ("Set bit %d in 0x%x\n", bit, addr));
|
||||
}
|
||||
|
||||
// clearbit command
|
||||
else if (!strncmp(line, "clearbit", strlen("clearbit"))) {
|
||||
uint32_t addr = 0;
|
||||
uint32_t bit = 0;
|
||||
if (sscanf(line, "%s %x %d", command, &addr, &bit) != 3) {
|
||||
sprintf(mess, "Could not scan clearbit command. Line:[%s].\n",
|
||||
line);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
bus_w(addr, bus_r(addr) & ~(1 << bit));
|
||||
LOG(logINFOBLUE, ("Cleared bit %d in 0x%x\n", bit, addr));
|
||||
}
|
||||
|
||||
// pollbit command
|
||||
else if (!strncmp(line, "pollbit", strlen("pollbit"))) {
|
||||
uint32_t addr = 0;
|
||||
uint32_t bit = 0;
|
||||
uint32_t val = 0;
|
||||
if (sscanf(line, "%s %x %d %d", command, &addr, &bit, &val) != 4) {
|
||||
sprintf(mess, "Could not scan pollbit command. Line:[%s].\n",
|
||||
line);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
#ifndef VIRTUAL
|
||||
int times = 0;
|
||||
while (((bus_r(addr) >> bit) & 0x1) != val) {
|
||||
if (times++ > WAIT_TIME_OUT_0US_TIMES) {
|
||||
sprintf(mess, "Polling bit %d in 0x%x timed out\n", bit,
|
||||
addr);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
usleep(0);
|
||||
}
|
||||
#endif
|
||||
LOG(logINFOBLUE, ("Polled bit %d in 0x%x\n", bit, addr));
|
||||
}
|
||||
|
||||
// pattern command
|
||||
else if (!strncmp(line, "pattern", strlen("pattern"))) {
|
||||
// take a file name and call loadPatterFile
|
||||
char patternFileName[LZ];
|
||||
if (sscanf(line, "%s %s", command, patternFileName) != 2) {
|
||||
sprintf(mess, "Could not scan pattern command. Line:[%s].\n",
|
||||
line);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
if (loadPatternFile(patternFileName, mess) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFOBLUE, ("loaded pattern [%s].\n", patternFileName));
|
||||
}
|
||||
|
||||
// sleep command
|
||||
else if (!strncmp(line, "sleep", strlen("sleep"))) {
|
||||
int time = 0;
|
||||
if (sscanf(line, "%s %d", command, &time) != 2) {
|
||||
sprintf(mess, "Could not scan sleep command. Line:[%s].\n",
|
||||
line);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
usleep(time * 1000 * 1000);
|
||||
LOG(logINFOBLUE, ("Slept for %d s\n", time));
|
||||
}
|
||||
|
||||
// other commands
|
||||
else {
|
||||
sprintf(mess,
|
||||
"Could not scan command from on-board server "
|
||||
"%s file. Line:[%s].\n",
|
||||
fileType, line);
|
||||
break;
|
||||
}
|
||||
memset(line, 0, LZ);
|
||||
}
|
||||
fclose(fd);
|
||||
LOG(logINFOBLUE, ("Successfully read %s file.\n", fileType));
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -1328,31 +1502,13 @@ int startStateMachine() {
|
||||
return OK;
|
||||
#endif
|
||||
|
||||
LOG(logINFOBLUE, ("Starting State Machine\n"));
|
||||
// cleanFifos(); removing this for now as its done before readout pattern
|
||||
LOG(logINFOBLUE, ("Starting readout\n"));
|
||||
|
||||
// start state machine
|
||||
bus_w(FLOW_CONTROL_REG, bus_r(FLOW_CONTROL_REG) | START_F_MSK);
|
||||
|
||||
LOG(logINFORED, ("Waiting for exposing to be done\n"));
|
||||
int exposingDone = (bus_r(FLOW_STATUS_REG) & RSM_BUSY_MSK);
|
||||
while (exposingDone != 0) {
|
||||
usleep(0);
|
||||
exposingDone = (bus_r(FLOW_STATUS_REG) & RSM_BUSY_MSK);
|
||||
}
|
||||
|
||||
LOG(logINFORED, ("Starting readout of chip to fifo\n"));
|
||||
// MM:readout via pattern does not work right now due to firmware bug,
|
||||
// readout via MatterhornCTRL for the moment
|
||||
// bus_w(FLOW_CONTROL_REG, bus_r(FLOW_CONTROL_REG) | START_F_MSK);
|
||||
bus_w(MATTERHORNSPICTRL, bus_r(MATTERHORNSPICTRL) | STARTREAD_P_MSK);
|
||||
|
||||
LOG(logINFORED, ("Waiting until k-words or end of acquisition\n"));
|
||||
usleep(0);
|
||||
int commaDet = (bus_r(TRANSCEIVERSTATUS) & RXCOMMADET_MSK);
|
||||
while (commaDet == 0) {
|
||||
usleep(0);
|
||||
commaDet = (bus_r(TRANSCEIVERSTATUS) & RXCOMMADET_MSK);
|
||||
}
|
||||
LOG(logINFORED, ("Kwords or end of acquisition detected\n"));
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -1467,56 +1623,6 @@ int stopStateMachine() {
|
||||
return OK;
|
||||
}
|
||||
|
||||
int startReadOut() {
|
||||
LOG(logINFOBLUE, ("Starting Readout\n"));
|
||||
#ifdef VIRTUAL
|
||||
// cannot set #frames and exptiem temporarily to 1 and 0,
|
||||
// because have to set it back after readout (but this is non blocking)
|
||||
return startStateMachine();
|
||||
#endif
|
||||
// check if data in fifo
|
||||
int ret = FAIL;
|
||||
if (transceiverEnable) {
|
||||
if ((bus_r(X_FIFO_EMPTY_STATUS_REG) & X_FIFO_EMPTY_STATUS_MSK) !=
|
||||
X_FIFO_EMPTY_STATUS_MSK) {
|
||||
LOG(logINFO, ("Data in transceiver fifo\n"));
|
||||
ret = OK;
|
||||
}
|
||||
}
|
||||
if (analogEnable) {
|
||||
if (bus_r(A_FIFO_EMPTY_STATUS_REG) != BIT32_MSK) {
|
||||
LOG(logINFO, ("Data in analog fifo\n"));
|
||||
ret = OK;
|
||||
}
|
||||
}
|
||||
if (digitalEnable) {
|
||||
if ((bus_r(D_FIFO_EMPTY_STATUS_REG) & D_FIFO_EMPTY_STATUS_MSK) !=
|
||||
D_FIFO_EMPTY_STATUS_MSK) {
|
||||
LOG(logINFO, ("Data in digital fifo\n"));
|
||||
ret = OK;
|
||||
}
|
||||
}
|
||||
// if no module, dont check fifo empty
|
||||
if (checkModuleFlag && ret == FAIL) {
|
||||
LOG(logERROR, ("No data in fifo\n"));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
LOG(logINFOBLUE, ("Streaming data from fifo\n"));
|
||||
bus_w(FIFO_TO_GB_CONTROL_REG,
|
||||
bus_r(FIFO_TO_GB_CONTROL_REG) | START_STREAMING_P_MSK);
|
||||
|
||||
// wait until streaming is done (not same as fifo empty)
|
||||
int streamingBusy = (bus_r(STATUSREG1) & TRANSMISSIONBUSY_MSK);
|
||||
while (streamingBusy != 0) {
|
||||
usleep(0);
|
||||
streamingBusy = (bus_r(STATUSREG1) & TRANSMISSIONBUSY_MSK);
|
||||
}
|
||||
LOG(logINFORED, ("Streaming done\n"));
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int softwareTrigger() {
|
||||
#ifndef VIRTUAL
|
||||
// ready for trigger
|
||||
@ -1552,36 +1658,33 @@ enum runStatus getRunStatus() {
|
||||
LOG(logINFOBLUE, ("Status: IDLE\n"));
|
||||
return IDLE;
|
||||
#endif
|
||||
uint32_t retval = bus_r(FLOW_STATUS_REG);
|
||||
LOG(logINFO, ("Flow Status Register: %08x\n", retval));
|
||||
uint32_t retval = bus_r(STATUS_REG);
|
||||
LOG(logINFO, ("Status Register: %08x\n", retval));
|
||||
|
||||
if (retval & RSM_TRG_WAIT_MSK) {
|
||||
LOG(logINFOBLUE, ("Status: WAITING\n"));
|
||||
return WAITING;
|
||||
} else if (retval & RSM_BUSY_MSK) {
|
||||
LOG(logINFOBLUE, ("Status: RUNNING (exposing)\n"));
|
||||
return RUNNING;
|
||||
} else if (bus_r(MATTERHORNSPICTRL) & READOUTFROMASIC_MSK) {
|
||||
LOG(logINFOBLUE, ("Status: RUNNING (data from chip to fifo)\n"));
|
||||
return RUNNING;
|
||||
} else if (bus_r(STATUSREG1) & TRANSMISSIONBUSY_MSK) {
|
||||
LOG(logINFOBLUE, ("Status: TRANSMITTING\n"));
|
||||
return TRANSMITTING;
|
||||
if (retval == 0x0) {
|
||||
return IDLE;
|
||||
}
|
||||
|
||||
LOG(logINFOBLUE, ("Status: IDLE\n"));
|
||||
return IDLE;
|
||||
// TODO: STOPPED, ERROR?
|
||||
if (retval & RX_NOT_GOOD_MSK) {
|
||||
LOG(logINFOBLUE, ("Status: ERROR\n"));
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (retval & WAIT_FOR_TRIGGER_MSK) {
|
||||
LOG(logINFOBLUE, ("Status: WAITING\n"));
|
||||
return WAITING;
|
||||
}
|
||||
|
||||
LOG(logINFOBLUE, ("Status: RUNNING\n"));
|
||||
return RUNNING;
|
||||
// TODO: STOPPED?
|
||||
}
|
||||
|
||||
u_int32_t runBusy() {
|
||||
#ifdef VIRTUAL
|
||||
return ((sharedMemory_getStatus() == RUNNING) ? 1 : 0);
|
||||
#endif
|
||||
uint32_t exposingBusy = bus_r(FLOW_STATUS_REG) & RSM_BUSY_MSK;
|
||||
uint32_t fillingFifoBusy = bus_r(MATTERHORNSPICTRL) & READOUTFROMASIC_MSK;
|
||||
uint32_t streamingBusy = bus_r(STATUSREG1) & TRANSMISSIONBUSY_MSK;
|
||||
return (exposingBusy || fillingFifoBusy || streamingBusy);
|
||||
return (bus_r(STATUS_REG));
|
||||
}
|
||||
|
||||
void waitForAcquisitionEnd() {
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "RegisterDefs.h"
|
||||
#include "sls/sls_detector_defs.h"
|
||||
|
||||
#define REQRD_FRMWRE_VRSN (0x230710)
|
||||
#define REQRD_FRMWRE_VRSN (0x250203)
|
||||
#define KERNEL_DATE_VRSN "Wed Nov 29 17:32:14 CET 2023"
|
||||
|
||||
#define LINKED_SERVER_NAME "xilinx_ctbDetectorServer"
|
||||
@ -40,6 +40,9 @@
|
||||
#define SLOWADC_DRIVER_FILE_NAME CURRENT_BOARD_LINKS_FOLDER "/ai%d"
|
||||
#define TEMP_DRIVER_FILE_NAME DEVICE_TREE_DST "0/in_temp7_input"
|
||||
|
||||
#define CONFIG_CHIP_FILE "chip_config_xilinx.txt"
|
||||
#define RESET_CHIP_FILE "reset_chip_xilinx.txt"
|
||||
|
||||
/** Default Parameters */
|
||||
#define DEFAULT_NUM_FRAMES (1)
|
||||
#define DEFAULT_NUM_CYCLES (1)
|
||||
|
@ -80,7 +80,7 @@ _sd() {
|
||||
local IS_PATH=0
|
||||
|
||||
|
||||
local SLS_COMMANDS=" acquire activate adcclk adcenable adcenable10g adcindex adcinvert adclist adcname adcphase adcpipeline adcreg adcvpp apulse asamples autocompdisable badchannels blockingtrigger burstmode burstperiod bursts burstsl bustest cdsgain chipversion clearbit clearbusy clearroi clientversion clkdiv clkfreq clkphase collectionmode column compdisabletime confadc config configtransceiver counters currentsource dac dacindex daclist dacname dacvalues datastream dbitclk dbitphase dbitpipeline defaultdac defaultpattern delay delayl detectorserverversion detsize diodelay dpulse dr drlist dsamples execcommand exptime exptime1 exptime2 exptime3 exptimel extrastoragecells extsampling extsamplingsrc extsig fformat filtercells filterresistor findex firmwaretest firmwareversion fliprows flowcontrol10g fmaster fname foverwrite fpath framecounter frames framesl frametime free fwrite gaincaps gainmode gappixels gatedelay gatedelay1 gatedelay2 gatedelay3 gates getbit hardwareversion highvoltage hostname im_a im_b im_c im_d im_io imagetest initialchecks inj_ch interpolation interruptsubframe kernelversion lastclient led lock master maxadcphaseshift maxclkphaseshift maxdbitphaseshift measuredperiod measuredsubperiod moduleid nextframenumber nmod numinterfaces overflow packageversion parallel parameters partialreset patfname patioctrl patlimits patloop patloop0 patloop1 patloop2 patmask patnloop patnloop0 patnloop1 patnloop2 patsetbit patternX patternstart patwait patwait0 patwait1 patwait2 patwaittime patwaittime0 patwaittime1 patwaittime2 patword pedestalmode period periodl polarity port powerchip powerindex powerlist powername powervalues programfpga pulse pulsechip pulsenmove pumpprobe quad ratecorr readnrows readout readoutspeed readoutspeedlist rebootcontroller reg resetdacs resetfpga roi romode row runclk runtime rx_arping rx_clearroi rx_dbitlist rx_dbitoffset rx_discardpolicy rx_fifodepth rx_frameindex rx_framescaught rx_framesperfile rx_hostname rx_jsonaddheader rx_jsonpara rx_lastclient rx_lock rx_missingpackets rx_padding rx_printconfig rx_realudpsocksize rx_roi rx_silent rx_start rx_status rx_stop rx_tcpport rx_threads rx_udpsocksize rx_version rx_zmqfreq rx_zmqhwm rx_zmqip rx_zmqport rx_zmqstartfnum rx_zmqstream samples savepattern scan scanerrmsg selinterface serialnumber setbit settings settingslist settingspath signalindex signallist signalname sleep slowadc slowadcindex slowadclist slowadcname slowadcvalues start status stop stopport storagecell_delay storagecell_start subdeadtime subexptime sync syncclk temp_10ge temp_adc temp_control temp_dcdc temp_event temp_fpga temp_fpgaext temp_fpgafl temp_fpgafr temp_slowadc temp_sodl temp_sodr temp_threshold templist tempvalues tengiga threshold thresholdnotb timing timing_info_decoder timinglist timingsource top transceiverenable trigger triggers triggersl trimbits trimen trimval tsamples txdelay txdelay_frame txdelay_left txdelay_right type udp_cleardst udp_dstip udp_dstip2 udp_dstlist udp_dstmac udp_dstmac2 udp_dstport udp_dstport2 udp_firstdst udp_numdst udp_reconfigure udp_srcip udp_srcip2 udp_srcmac udp_srcmac2 udp_validate update updatedetectorserver updatekernel updatemode user v_a v_b v_c v_chip v_d v_io v_limit vchip_comp_adc vchip_comp_fe vchip_cs vchip_opa_1st vchip_opa_fd vchip_ref_comp_fe versions veto vetoalg vetofile vetophoton vetoref vetostream virtual vm_a vm_b vm_c vm_d vm_io zmqhwm zmqip zmqport "
|
||||
local SLS_COMMANDS=" acquire activate adcclk adcenable adcenable10g adcindex adcinvert adclist adcname adcphase adcpipeline adcreg adcvpp apulse asamples autocompdisable badchannels blockingtrigger burstmode burstperiod bursts burstsl bustest cdsgain chipversion clearbit clearbusy clearroi clientversion clkdiv clkfreq clkphase collectionmode column compdisabletime confadc config configtransceiver counters currentsource dac dacindex daclist dacname dacvalues datastream dbitclk dbitphase dbitpipeline defaultdac defaultpattern delay delayl detectorserverversion detsize diodelay dpulse dr drlist dsamples execcommand exptime exptime1 exptime2 exptime3 exptimel extrastoragecells extsampling extsamplingsrc extsig fformat filtercells filterresistor findex firmwaretest firmwareversion fliprows flowcontrol10g fmaster fname foverwrite fpath framecounter frames framesl frametime free fwrite gaincaps gainmode gappixels gatedelay gatedelay1 gatedelay2 gatedelay3 gates getbit hardwareversion highvoltage hostname im_a im_b im_c im_d im_io imagetest initialchecks inj_ch interpolation interruptsubframe kernelversion lastclient led lock master maxadcphaseshift maxclkphaseshift maxdbitphaseshift measuredperiod measuredsubperiod moduleid nextframenumber nmod numinterfaces overflow packageversion parallel parameters partialreset patfname patioctrl patlimits patloop patloop0 patloop1 patloop2 patmask patnloop patnloop0 patnloop1 patnloop2 patsetbit pattern patternstart patwait patwait0 patwait1 patwait2 patwaittime patwaittime0 patwaittime1 patwaittime2 patword pedestalmode period periodl polarity port powerchip powerindex powerlist powername powervalues programfpga pulse pulsechip pulsenmove pumpprobe quad ratecorr readnrows readout readoutspeed readoutspeedlist rebootcontroller reg resetdacs resetfpga roi romode row runclk runtime rx_arping rx_clearroi rx_dbitlist rx_dbitoffset rx_discardpolicy rx_fifodepth rx_frameindex rx_framescaught rx_framesperfile rx_hostname rx_jsonaddheader rx_jsonpara rx_lastclient rx_lock rx_missingpackets rx_padding rx_printconfig rx_realudpsocksize rx_roi rx_silent rx_start rx_status rx_stop rx_tcpport rx_threads rx_udpsocksize rx_version rx_zmqfreq rx_zmqhwm rx_zmqip rx_zmqport rx_zmqstartfnum rx_zmqstream samples savepattern scan scanerrmsg selinterface serialnumber setbit settings settingslist settingspath signalindex signallist signalname sleep slowadc slowadcindex slowadclist slowadcname slowadcvalues start status stop stopport storagecell_delay storagecell_start subdeadtime subexptime sync syncclk temp_10ge temp_adc temp_control temp_dcdc temp_event temp_fpga temp_fpgaext temp_fpgafl temp_fpgafr temp_slowadc temp_sodl temp_sodr temp_threshold templist tempvalues tengiga threshold thresholdnotb timing timing_info_decoder timinglist timingsource top transceiverenable trigger triggers triggersl trimbits trimen trimval tsamples txdelay txdelay_frame txdelay_left txdelay_right type udp_cleardst udp_dstip udp_dstip2 udp_dstlist udp_dstmac udp_dstmac2 udp_dstport udp_dstport2 udp_firstdst udp_numdst udp_reconfigure udp_srcip udp_srcip2 udp_srcmac udp_srcmac2 udp_validate update updatedetectorserver updatekernel updatemode user v_a v_b v_c v_chip v_d v_io v_limit vchip_comp_adc vchip_comp_fe vchip_cs vchip_opa_1st vchip_opa_fd vchip_ref_comp_fe versions veto vetoalg vetofile vetophoton vetoref vetostream virtual vm_a vm_b vm_c vm_d vm_io zmqhwm zmqip zmqport "
|
||||
__acquire() {
|
||||
FCN_RETURN=""
|
||||
return 0
|
||||
@ -1447,18 +1447,82 @@ return 0
|
||||
}
|
||||
__patloop() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "4" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__patloop0() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "4" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__patloop1() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "4" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__patloop2() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "4" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__patmask() {
|
||||
@ -1472,18 +1536,70 @@ return 0
|
||||
}
|
||||
__patnloop() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__patnloop0() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__patnloop1() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__patnloop2() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__patsetbit() {
|
||||
@ -1495,7 +1611,7 @@ fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__patternX() {
|
||||
__pattern() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
@ -1522,18 +1638,70 @@ return 0
|
||||
}
|
||||
__patwait() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__patwait0() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__patwait1() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__patwait2() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__patwaittime() {
|
||||
|
@ -4,7 +4,7 @@
|
||||
_sd() {
|
||||
|
||||
|
||||
local SLS_COMMANDS=" acquire activate adcclk adcenable adcenable10g adcindex adcinvert adclist adcname adcphase adcpipeline adcreg adcvpp apulse asamples autocompdisable badchannels blockingtrigger burstmode burstperiod bursts burstsl bustest cdsgain chipversion clearbit clearbusy clearroi clientversion clkdiv clkfreq clkphase collectionmode column compdisabletime confadc config configtransceiver counters currentsource dac dacindex daclist dacname dacvalues datastream dbitclk dbitphase dbitpipeline defaultdac defaultpattern delay delayl detectorserverversion detsize diodelay dpulse dr drlist dsamples execcommand exptime exptime1 exptime2 exptime3 exptimel extrastoragecells extsampling extsamplingsrc extsig fformat filtercells filterresistor findex firmwaretest firmwareversion fliprows flowcontrol10g fmaster fname foverwrite fpath framecounter frames framesl frametime free fwrite gaincaps gainmode gappixels gatedelay gatedelay1 gatedelay2 gatedelay3 gates getbit hardwareversion highvoltage hostname im_a im_b im_c im_d im_io imagetest initialchecks inj_ch interpolation interruptsubframe kernelversion lastclient led lock master maxadcphaseshift maxclkphaseshift maxdbitphaseshift measuredperiod measuredsubperiod moduleid nextframenumber nmod numinterfaces overflow packageversion parallel parameters partialreset patfname patioctrl patlimits patloop patloop0 patloop1 patloop2 patmask patnloop patnloop0 patnloop1 patnloop2 patsetbit patternX patternstart patwait patwait0 patwait1 patwait2 patwaittime patwaittime0 patwaittime1 patwaittime2 patword pedestalmode period periodl polarity port powerchip powerindex powerlist powername powervalues programfpga pulse pulsechip pulsenmove pumpprobe quad ratecorr readnrows readout readoutspeed readoutspeedlist rebootcontroller reg resetdacs resetfpga roi romode row runclk runtime rx_arping rx_clearroi rx_dbitlist rx_dbitoffset rx_discardpolicy rx_fifodepth rx_frameindex rx_framescaught rx_framesperfile rx_hostname rx_jsonaddheader rx_jsonpara rx_lastclient rx_lock rx_missingpackets rx_padding rx_printconfig rx_realudpsocksize rx_roi rx_silent rx_start rx_status rx_stop rx_tcpport rx_threads rx_udpsocksize rx_version rx_zmqfreq rx_zmqhwm rx_zmqip rx_zmqport rx_zmqstartfnum rx_zmqstream samples savepattern scan scanerrmsg selinterface serialnumber setbit settings settingslist settingspath signalindex signallist signalname sleep slowadc slowadcindex slowadclist slowadcname slowadcvalues start status stop stopport storagecell_delay storagecell_start subdeadtime subexptime sync syncclk temp_10ge temp_adc temp_control temp_dcdc temp_event temp_fpga temp_fpgaext temp_fpgafl temp_fpgafr temp_slowadc temp_sodl temp_sodr temp_threshold templist tempvalues tengiga threshold thresholdnotb timing timing_info_decoder timinglist timingsource top transceiverenable trigger triggers triggersl trimbits trimen trimval tsamples txdelay txdelay_frame txdelay_left txdelay_right type udp_cleardst udp_dstip udp_dstip2 udp_dstlist udp_dstmac udp_dstmac2 udp_dstport udp_dstport2 udp_firstdst udp_numdst udp_reconfigure udp_srcip udp_srcip2 udp_srcmac udp_srcmac2 udp_validate update updatedetectorserver updatekernel updatemode user v_a v_b v_c v_chip v_d v_io v_limit vchip_comp_adc vchip_comp_fe vchip_cs vchip_opa_1st vchip_opa_fd vchip_ref_comp_fe versions veto vetoalg vetofile vetophoton vetoref vetostream virtual vm_a vm_b vm_c vm_d vm_io zmqhwm zmqip zmqport "
|
||||
local SLS_COMMANDS=" acquire activate adcclk adcenable adcenable10g adcindex adcinvert adclist adcname adcphase adcpipeline adcreg adcvpp apulse asamples autocompdisable badchannels blockingtrigger burstmode burstperiod bursts burstsl bustest cdsgain chipversion clearbit clearbusy clearroi clientversion clkdiv clkfreq clkphase collectionmode column compdisabletime confadc config configtransceiver counters currentsource dac dacindex daclist dacname dacvalues datastream dbitclk dbitphase dbitpipeline defaultdac defaultpattern delay delayl detectorserverversion detsize diodelay dpulse dr drlist dsamples execcommand exptime exptime1 exptime2 exptime3 exptimel extrastoragecells extsampling extsamplingsrc extsig fformat filtercells filterresistor findex firmwaretest firmwareversion fliprows flowcontrol10g fmaster fname foverwrite fpath framecounter frames framesl frametime free fwrite gaincaps gainmode gappixels gatedelay gatedelay1 gatedelay2 gatedelay3 gates getbit hardwareversion highvoltage hostname im_a im_b im_c im_d im_io imagetest initialchecks inj_ch interpolation interruptsubframe kernelversion lastclient led lock master maxadcphaseshift maxclkphaseshift maxdbitphaseshift measuredperiod measuredsubperiod moduleid nextframenumber nmod numinterfaces overflow packageversion parallel parameters partialreset patfname patioctrl patlimits patloop patloop0 patloop1 patloop2 patmask patnloop patnloop0 patnloop1 patnloop2 patsetbit pattern patternstart patwait patwait0 patwait1 patwait2 patwaittime patwaittime0 patwaittime1 patwaittime2 patword pedestalmode period periodl polarity port powerchip powerindex powerlist powername powervalues programfpga pulse pulsechip pulsenmove pumpprobe quad ratecorr readnrows readout readoutspeed readoutspeedlist rebootcontroller reg resetdacs resetfpga roi romode row runclk runtime rx_arping rx_clearroi rx_dbitlist rx_dbitoffset rx_discardpolicy rx_fifodepth rx_frameindex rx_framescaught rx_framesperfile rx_hostname rx_jsonaddheader rx_jsonpara rx_lastclient rx_lock rx_missingpackets rx_padding rx_printconfig rx_realudpsocksize rx_roi rx_silent rx_start rx_status rx_stop rx_tcpport rx_threads rx_udpsocksize rx_version rx_zmqfreq rx_zmqhwm rx_zmqip rx_zmqport rx_zmqstartfnum rx_zmqstream samples savepattern scan scanerrmsg selinterface serialnumber setbit settings settingslist settingspath signalindex signallist signalname sleep slowadc slowadcindex slowadclist slowadcname slowadcvalues start status stop stopport storagecell_delay storagecell_start subdeadtime subexptime sync syncclk temp_10ge temp_adc temp_control temp_dcdc temp_event temp_fpga temp_fpgaext temp_fpgafl temp_fpgafr temp_slowadc temp_sodl temp_sodr temp_threshold templist tempvalues tengiga threshold thresholdnotb timing timing_info_decoder timinglist timingsource top transceiverenable trigger triggers triggersl trimbits trimen trimval tsamples txdelay txdelay_frame txdelay_left txdelay_right type udp_cleardst udp_dstip udp_dstip2 udp_dstlist udp_dstmac udp_dstmac2 udp_dstport udp_dstport2 udp_firstdst udp_numdst udp_reconfigure udp_srcip udp_srcip2 udp_srcmac udp_srcmac2 udp_validate update updatedetectorserver updatekernel updatemode user v_a v_b v_c v_chip v_d v_io v_limit vchip_comp_adc vchip_comp_fe vchip_cs vchip_opa_1st vchip_opa_fd vchip_ref_comp_fe versions veto vetoalg vetofile vetophoton vetoref vetostream virtual vm_a vm_b vm_c vm_d vm_io zmqhwm zmqip zmqport "
|
||||
__acquire() {
|
||||
FCN_RETURN=""
|
||||
return 0
|
||||
@ -1371,18 +1371,82 @@ return 0
|
||||
}
|
||||
__patloop() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "4" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__patloop0() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "4" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__patloop1() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "4" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__patloop2() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "4" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__patmask() {
|
||||
@ -1396,18 +1460,70 @@ return 0
|
||||
}
|
||||
__patnloop() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__patnloop0() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__patnloop1() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__patnloop2() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__patsetbit() {
|
||||
@ -1419,7 +1535,7 @@ fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__patternX() {
|
||||
__pattern() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
@ -1446,18 +1562,70 @@ return 0
|
||||
}
|
||||
__patwait() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__patwait0() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__patwait1() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__patwait2() {
|
||||
FCN_RETURN=""
|
||||
if [[ ${IS_GET} -eq 1 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
if [[ ${IS_GET} -eq 0 ]]; then
|
||||
if [[ "${cword}" == "2" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
if [[ "${cword}" == "3" ]]; then
|
||||
FCN_RETURN=""
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
__patwaittime() {
|
||||
|
@ -468,7 +468,7 @@ subdeadtime:
|
||||
function: setSubDeadTime
|
||||
|
||||
compdisabletime:
|
||||
help: "[duration] [(optional unit) ns|us|ms|s]\n\t[Jungfrau] Time before end of exposure when comparator is disabled. It is only possible for chipv1.1."
|
||||
help: "[duration] [(optional unit) ns|us|ms|s]\n\t[Jungfrau] Time before end of exposure when comparator is disabled."
|
||||
inherit_actions: TIME_COMMAND
|
||||
actions:
|
||||
GET:
|
||||
@ -1123,7 +1123,7 @@ temp_control:
|
||||
input_types: [ bool ]
|
||||
|
||||
autocompdisable:
|
||||
help: "[0, 1]\n\t[Jungfrau] Auto comparator disable mode. By default, the on-chip gain switching is active during the entire exposure.This mode disables the on - chip gain switching comparator automatically after 93.75% (only for chipv1.0) of exposure time (only for longer than 100us). It is possible to set the duration for chipv1.1 using compdisabletime command.\n\tDefault is 0 or this mode disabled(comparator enabled throughout). 1 enables mode. 0 disables mode. "
|
||||
help: "[0, 1]\n\t[Jungfrau] Auto comparator disable mode. By default, the on-chip gain switching is active during the entire exposure.This mode disables the on - chip gain switching comparator automatically and the duration is set using compdisabletime command.\n\tDefault is 0 or this mode disabled(comparator enabled throughout). 1 enables mode. 0 disables mode. "
|
||||
inherit_actions: INTEGER_COMMAND_VEC_ID
|
||||
actions:
|
||||
GET:
|
||||
@ -1210,7 +1210,7 @@ polarity:
|
||||
input_types: [ defs::polarity ]
|
||||
|
||||
timing_info_decoder:
|
||||
help: "[swissfel|shine]\n\t[Jungfrau] Advanced Command and only for Swissfel and Shine. Sets the bunch id or timing info decoder. Default is swissfel."
|
||||
help: "[swissfel|shine]\n\t[Jungfrau] Advanced Command and only for Swissfel and Shine. Sets the bunch id or timing info decoder. Default is swissfel. Only allowed for pcbv2.0."
|
||||
inherit_actions: INTEGER_COMMAND_VEC_ID
|
||||
actions:
|
||||
GET:
|
||||
@ -3467,7 +3467,7 @@ udp_dstlist:
|
||||
output: [ ToString(args) ]
|
||||
|
||||
txdelay:
|
||||
help: "[n_delay]\n\t[Eiger][Jungfrau][Moench][Mythen3] Set transmission delay for all modules in the detector using the step size provided.Sets up \n\t[Eiger] txdelay_left to (2 * mod_index * n_delay), \n\t[Eiger] txdelay_right to ((2 * mod_index + 1) * n_delay) and \n\t[Eiger] txdelay_frame to (2 *num_modules * n_delay)\n\t[Jungfrau][Moench][Mythen3] txdelay_frame to (num_modules * n_delay) for every module."
|
||||
help: "[n_delay]\n\t[Eiger][Jungfrau][Moench][Mythen3] Set transmission delay for all modules in the detector using the step size provided.Sets up \n\t[Eiger] txdelay_left to (2 * mod_index * n_delay), \n\t[Eiger] txdelay_right to ((2 * mod_index + 1) * n_delay) and \n\t[Eiger] txdelay_frame to (2 * num_modules * n_delay)\n\t[Jungfrau][Moench][Mythen3] txdelay_frame to (num_modules * n_delay) for every module."
|
||||
actions:
|
||||
GET:
|
||||
argc: 0
|
||||
@ -3912,8 +3912,7 @@ diodelay:
|
||||
cast_input: [ true, true ]
|
||||
output: [ ToString(args) ]
|
||||
|
||||
# pattern is a keyword in yaml, so patternX is used to avoid it
|
||||
patternX:
|
||||
pattern:
|
||||
help: "[fname]\n\t[Mythen3][Ctb][Xilinx Ctb] Loads ASCII pattern file directly to server (instead of executing line by line)"
|
||||
command_name: "pattern"
|
||||
actions:
|
||||
|
@ -164,6 +164,7 @@ i_d: im_d
|
||||
i_io: im_io
|
||||
|
||||
#Pattern
|
||||
patternX: pattern
|
||||
#Moench
|
||||
|
||||
#Advanced
|
||||
|
@ -762,10 +762,9 @@ autocompdisable:
|
||||
function_alias: autocompdisable
|
||||
help: "[0, 1]\n\t[Jungfrau] Auto comparator disable mode. By default, the on-chip\
|
||||
\ gain switching is active during the entire exposure.This mode disables the on\
|
||||
\ - chip gain switching comparator automatically after 93.75% (only for chipv1.0)\
|
||||
\ of exposure time (only for longer than 100us). It is possible to set the duration\
|
||||
\ for chipv1.1 using compdisabletime command.\n\tDefault is 0 or this mode disabled(comparator\
|
||||
\ enabled throughout). 1 enables mode. 0 disables mode. "
|
||||
\ - chip gain switching comparator automatically and the duration is set using\
|
||||
\ compdisabletime command.\n\tDefault is 0 or this mode disabled(comparator enabled\
|
||||
\ throughout). 1 enables mode. 0 disables mode. "
|
||||
infer_action: true
|
||||
template: true
|
||||
badchannels:
|
||||
@ -1607,7 +1606,7 @@ compdisabletime:
|
||||
command_name: compdisabletime
|
||||
function_alias: compdisabletime
|
||||
help: "[duration] [(optional unit) ns|us|ms|s]\n\t[Jungfrau] Time before end of\
|
||||
\ exposure when comparator is disabled. It is only possible for chipv1.1."
|
||||
\ exposure when comparator is disabled."
|
||||
infer_action: true
|
||||
template: true
|
||||
confadc:
|
||||
@ -6534,7 +6533,7 @@ patsetbit:
|
||||
\ pattern to the selected bits."
|
||||
infer_action: true
|
||||
template: true
|
||||
patternX:
|
||||
pattern:
|
||||
actions:
|
||||
PUT:
|
||||
args:
|
||||
@ -11386,7 +11385,8 @@ timing_info_decoder:
|
||||
command_name: timing_info_decoder
|
||||
function_alias: timing_info_decoder
|
||||
help: "[swissfel|shine]\n\t[Jungfrau] Advanced Command and only for Swissfel and\
|
||||
\ Shine. Sets the bunch id or timing info decoder. Default is swissfel."
|
||||
\ Shine. Sets the bunch id or timing info decoder. Default is swissfel. Only allowed\
|
||||
\ for pcbv2.0."
|
||||
infer_action: true
|
||||
template: true
|
||||
timinglist:
|
||||
@ -11813,7 +11813,7 @@ txdelay:
|
||||
help: "[n_delay]\n\t[Eiger][Jungfrau][Moench][Mythen3] Set transmission delay for\
|
||||
\ all modules in the detector using the step size provided.Sets up \n\t[Eiger]\
|
||||
\ txdelay_left to (2 * mod_index * n_delay), \n\t[Eiger] txdelay_right to ((2\
|
||||
\ * mod_index + 1) * n_delay) and \n\t[Eiger] txdelay_frame to (2 *num_modules\
|
||||
\ * mod_index + 1) * n_delay) and \n\t[Eiger] txdelay_frame to (2 * num_modules\
|
||||
\ * n_delay)\n\t[Jungfrau][Moench][Mythen3] txdelay_frame to (num_modules * n_delay)\
|
||||
\ for every module."
|
||||
infer_action: true
|
||||
|
@ -65,7 +65,12 @@ class Detector {
|
||||
|
||||
Result<std::string> getHostname(Positions pos = {}) const;
|
||||
|
||||
/**Frees shared memory, adds detectors to the list. */
|
||||
/**Frees shared memory, adds detectors to the list. The row and column
|
||||
* values in the udp/zmq header are affected by the order in this command
|
||||
* and the setDetectorSize function. The modules are stacked row by row
|
||||
* until they reach the y-axis limit set by detsize (if specified). Then,
|
||||
* stacking continues in the next column and so on. This only affects row
|
||||
* and column in udp/zmq header.*/
|
||||
void setHostname(const std::vector<std::string> &hostname);
|
||||
|
||||
/** connects to n servers at local host starting at specific control port.
|
||||
@ -1304,11 +1309,9 @@ class Detector {
|
||||
* //TODO naming
|
||||
* By default, the on-chip gain switching is active during the
|
||||
* entire exposure. This mode disables the on-chip gain switching comparator
|
||||
* automatically after 93.75% of exposure time (only for longer than 100us).
|
||||
* The % is for chipv1.0. One can set the duration for chipv1.1 using
|
||||
* setComparatorDisableTime\n Default is false or this mode
|
||||
* disabled(comparator enabled throughout). true enables mode. 0 disables
|
||||
* mode.
|
||||
* automatically and the duration is set using setComparatorDisableTime\n
|
||||
* Default is false or this mode disabled(comparator enabled throughout).
|
||||
* true enables mode. 0 disables mode.
|
||||
*/
|
||||
void setAutoComparatorDisable(bool value, Positions pos = {});
|
||||
|
||||
@ -1316,7 +1319,7 @@ class Detector {
|
||||
Result<ns> getComparatorDisableTime(Positions pos = {}) const;
|
||||
|
||||
/** [Jungfrau] Time before end of exposure when comparator is
|
||||
* disabled. It is only possible for chipv1.1.*/
|
||||
* disabled.*/
|
||||
void setComparatorDisableTime(ns t, Positions pos = {});
|
||||
|
||||
/** [Jungfrau] Advanced TODO naming */
|
||||
@ -1382,7 +1385,7 @@ class Detector {
|
||||
Result<defs::timingInfoDecoder>
|
||||
getTimingInfoDecoder(Positions pos = {}) const;
|
||||
|
||||
/** [Jungfrau] Advanced Command! */
|
||||
/** [Jungfrau] Advanced Command! Only for pcb v2.0 */
|
||||
void setTimingInfoDecoder(defs::timingInfoDecoder value,
|
||||
Positions pos = {});
|
||||
|
||||
|
@ -1018,7 +1018,7 @@ std::string Caller::autocompdisable(int action) {
|
||||
// print help
|
||||
if (action == slsDetectorDefs::HELP_ACTION) {
|
||||
os << R"V0G0N([0, 1]
|
||||
[Jungfrau] Auto comparator disable mode. By default, the on-chip gain switching is active during the entire exposure.This mode disables the on - chip gain switching comparator automatically after 93.75% (only for chipv1.0) of exposure time (only for longer than 100us). It is possible to set the duration for chipv1.1 using compdisabletime command.
|
||||
[Jungfrau] Auto comparator disable mode. By default, the on-chip gain switching is active during the entire exposure.This mode disables the on - chip gain switching comparator automatically and the duration is set using compdisabletime command.
|
||||
Default is 0 or this mode disabled(comparator enabled throughout). 1 enables mode. 0 disables mode. )V0G0N"
|
||||
<< std::endl;
|
||||
return os.str();
|
||||
@ -2108,7 +2108,7 @@ std::string Caller::compdisabletime(int action) {
|
||||
// print help
|
||||
if (action == slsDetectorDefs::HELP_ACTION) {
|
||||
os << R"V0G0N([duration] [(optional unit) ns|us|ms|s]
|
||||
[Jungfrau] Time before end of exposure when comparator is disabled. It is only possible for chipv1.1. )V0G0N"
|
||||
[Jungfrau] Time before end of exposure when comparator is disabled. )V0G0N"
|
||||
<< std::endl;
|
||||
return os.str();
|
||||
}
|
||||
@ -14655,7 +14655,7 @@ std::string Caller::timing_info_decoder(int action) {
|
||||
// print help
|
||||
if (action == slsDetectorDefs::HELP_ACTION) {
|
||||
os << R"V0G0N([swissfel|shine]
|
||||
[Jungfrau] Advanced Command and only for Swissfel and Shine. Sets the bunch id or timing info decoder. Default is swissfel. )V0G0N"
|
||||
[Jungfrau] Advanced Command and only for Swissfel and Shine. Sets the bunch id or timing info decoder. Default is swissfel. Only allowed for pcbv2.0. )V0G0N"
|
||||
<< std::endl;
|
||||
return os.str();
|
||||
}
|
||||
@ -15276,7 +15276,7 @@ std::string Caller::txdelay(int action) {
|
||||
[Eiger][Jungfrau][Moench][Mythen3] Set transmission delay for all modules in the detector using the step size provided.Sets up
|
||||
[Eiger] txdelay_left to (2 * mod_index * n_delay),
|
||||
[Eiger] txdelay_right to ((2 * mod_index + 1) * n_delay) and
|
||||
[Eiger] txdelay_frame to (2 *num_modules * n_delay)
|
||||
[Eiger] txdelay_frame to (2 * num_modules * n_delay)
|
||||
[Jungfrau][Moench][Mythen3] txdelay_frame to (num_modules * n_delay) for every module. )V0G0N"
|
||||
<< std::endl;
|
||||
return os.str();
|
||||
|
@ -543,7 +543,7 @@ class Caller {
|
||||
{"patnloop1", &Caller::patnloop1},
|
||||
{"patnloop2", &Caller::patnloop2},
|
||||
{"patsetbit", &Caller::patsetbit},
|
||||
{"patternX", &Caller::pattern},
|
||||
{"pattern", &Caller::pattern},
|
||||
{"patternstart", &Caller::patternstart},
|
||||
{"patwait", &Caller::patwait},
|
||||
{"patwait0", &Caller::patwait0},
|
||||
@ -872,6 +872,7 @@ class Caller {
|
||||
{"i_c", "im_c"},
|
||||
{"i_d", "im_d"},
|
||||
{"i_io", "im_io"},
|
||||
{"patternX", "pattern"},
|
||||
{"copydetectorserver", "updatedetectorserver"},
|
||||
{"nframes", "framecounter"},
|
||||
{"now", "runtime"},
|
||||
|
@ -198,7 +198,12 @@ std::string Caller::hostname(int action) {
|
||||
os << "\n\tFrees shared memory and sets hostname (or IP address) of "
|
||||
"all modules concatenated by +.\n\t Virtual servers can already "
|
||||
"use the port in hostname separated by ':' and ports incremented "
|
||||
"by 2 to accomodate the stop server as well."
|
||||
"by 2 to accomodate the stop server as well. The row and column "
|
||||
"values in the udp/zmq header are affected by the order in this "
|
||||
"command and the detsize command. The modules are stacked row by "
|
||||
"row until they reach the y-axis limit set by detsize (if "
|
||||
"specified). Then, stacking continues in the next column and so "
|
||||
"on. This only affects row and column in udp/zmq header."
|
||||
<< '\n';
|
||||
} else if (action == defs::GET_ACTION) {
|
||||
if (!args.empty()) {
|
||||
|
@ -99,6 +99,12 @@ void Detector::loadParameters(const std::vector<std::string> ¶meters) {
|
||||
CmdParser parser;
|
||||
for (const auto ¤t_line : parameters) {
|
||||
parser.Parse(current_line);
|
||||
if (parser.multi_id() != 0) {
|
||||
throw RuntimeError(
|
||||
"Multi-detector indices [" + std::to_string(parser.multi_id()) +
|
||||
"] are not allowed in the file. Instead, use the index for "
|
||||
"'config' or 'parameters' command?");
|
||||
}
|
||||
caller.call(parser.command(), parser.arguments(), parser.detector_id(),
|
||||
defs::PUT_ACTION, std::cout, parser.receiver_id());
|
||||
}
|
||||
|
@ -488,7 +488,7 @@ class InferAction {
|
||||
{"patnloop1", &InferAction::patnloop1},
|
||||
{"patnloop2", &InferAction::patnloop2},
|
||||
{"patsetbit", &InferAction::patsetbit},
|
||||
{"patternX", &InferAction::pattern},
|
||||
{"pattern", &InferAction::pattern},
|
||||
{"patternstart", &InferAction::patternstart},
|
||||
{"patwait", &InferAction::patwait},
|
||||
{"patwait0", &InferAction::patwait0},
|
||||
|
@ -262,8 +262,7 @@ TEST_CASE("compdisabletime", "[.cmdcall]") {
|
||||
Detector det;
|
||||
Caller caller(&det);
|
||||
auto det_type = det.getDetectorType().squash();
|
||||
if (det_type == defs::JUNGFRAU &&
|
||||
det.getChipVersion().squash() * 10 == 11) {
|
||||
if (det_type == defs::JUNGFRAU) {
|
||||
auto prev_val = det.getComparatorDisableTime();
|
||||
{
|
||||
std::ostringstream oss;
|
||||
@ -670,7 +669,8 @@ TEST_CASE("pedestalmode", "[.cmdcall]") {
|
||||
TEST_CASE("timing_info_decoder", "[.cmdcall]") {
|
||||
Detector det;
|
||||
Caller caller(&det);
|
||||
if (det.getDetectorType().squash() == defs::JUNGFRAU) {
|
||||
if (det.getDetectorType().squash() == defs::JUNGFRAU &&
|
||||
det.getHardwareVersion().squash() == "2.0") {
|
||||
auto prev_val = det.getTimingInfoDecoder();
|
||||
/*{
|
||||
std::ostringstream oss;
|
||||
|
@ -138,13 +138,34 @@ if (SLS_USE_RECEIVER_BINARIES)
|
||||
slsProjectWarnings
|
||||
)
|
||||
|
||||
install(TARGETS slsReceiver slsMultiReceiver
|
||||
add_executable(slsFrameSynchronizer
|
||||
src/FrameSynchronizerApp.cpp
|
||||
)
|
||||
|
||||
set_target_properties(slsFrameSynchronizer PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
|
||||
)
|
||||
if((CMAKE_BUILD_TYPE STREQUAL "Release") AND SLS_LTO_AVAILABLE)
|
||||
set_property(TARGET slsFrameSynchronizer PROPERTY INTERPROCEDURAL_OPTIMIZATION True)
|
||||
endif()
|
||||
|
||||
target_link_libraries(slsFrameSynchronizer
|
||||
PUBLIC
|
||||
slsReceiverStatic
|
||||
pthread
|
||||
rt
|
||||
PRIVATE
|
||||
slsProjectWarnings
|
||||
"$<BUILD_INTERFACE:libzmq-static>"
|
||||
)
|
||||
|
||||
install(TARGETS slsReceiver slsMultiReceiver slsFrameSynchronizer
|
||||
EXPORT "${TARGETS_EXPORT_NAME}"
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/sls
|
||||
)
|
||||
)
|
||||
|
||||
endif(SLS_USE_RECEIVER_BINARIES)
|
||||
|
||||
|
@ -45,9 +45,8 @@ class Receiver : private virtual slsDetectorDefs {
|
||||
* Call back arguments are:
|
||||
* - startCallbackHeader metadata
|
||||
*/
|
||||
void registerCallBackStartAcquisition(int (*func)(const startCallbackHeader,
|
||||
void *),
|
||||
void *arg);
|
||||
void registerCallBackStartAcquisition(
|
||||
void (*func)(const startCallbackHeader, void *), void *arg);
|
||||
|
||||
/**
|
||||
* Call back for acquisition finished
|
||||
|
@ -33,6 +33,8 @@ using Interface = ServerInterface;
|
||||
#define gettid() syscall(SYS_gettid)
|
||||
#endif
|
||||
|
||||
std::mutex ClientInterface::callbackMutex;
|
||||
|
||||
ClientInterface::~ClientInterface() {
|
||||
killTcpThread = true;
|
||||
LOG(logINFO) << "Shutting down TCP Socket on port " << portNumber;
|
||||
@ -54,13 +56,15 @@ std::string ClientInterface::getReceiverVersion() { return APIRECEIVER; }
|
||||
|
||||
/***callback functions***/
|
||||
void ClientInterface::registerCallBackStartAcquisition(
|
||||
int (*func)(const startCallbackHeader, void *), void *arg) {
|
||||
void (*func)(const startCallbackHeader, void *), void *arg) {
|
||||
std::lock_guard<std::mutex> lock(callbackMutex);
|
||||
startAcquisitionCallBack = func;
|
||||
pStartAcquisition = arg;
|
||||
}
|
||||
|
||||
void ClientInterface::registerCallBackAcquisitionFinished(
|
||||
void (*func)(const endCallbackHeader, void *), void *arg) {
|
||||
std::lock_guard<std::mutex> lock(callbackMutex);
|
||||
acquisitionFinishedCallBack = func;
|
||||
pAcquisitionFinished = arg;
|
||||
}
|
||||
@ -69,6 +73,7 @@ void ClientInterface::registerCallBackRawDataReady(
|
||||
void (*func)(sls_receiver_header &, dataCallbackHeader, char *, size_t &,
|
||||
void *),
|
||||
void *arg) {
|
||||
std::lock_guard<std::mutex> lock(callbackMutex);
|
||||
rawDataReadyCallBack = func;
|
||||
pRawDataReady = arg;
|
||||
}
|
||||
@ -461,15 +466,18 @@ void ClientInterface::setDetectorType(detectorType arg) {
|
||||
std::string(e.what()) + ']');
|
||||
}
|
||||
// callbacks after (in setdetectortype, the object is reinitialized)
|
||||
if (startAcquisitionCallBack != nullptr)
|
||||
impl()->registerCallBackStartAcquisition(startAcquisitionCallBack,
|
||||
pStartAcquisition);
|
||||
if (acquisitionFinishedCallBack != nullptr)
|
||||
impl()->registerCallBackAcquisitionFinished(acquisitionFinishedCallBack,
|
||||
pAcquisitionFinished);
|
||||
if (rawDataReadyCallBack != nullptr)
|
||||
impl()->registerCallBackRawDataReady(rawDataReadyCallBack,
|
||||
pRawDataReady);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(callbackMutex);
|
||||
if (startAcquisitionCallBack != nullptr)
|
||||
impl()->registerCallBackStartAcquisition(startAcquisitionCallBack,
|
||||
pStartAcquisition);
|
||||
if (acquisitionFinishedCallBack != nullptr)
|
||||
impl()->registerCallBackAcquisitionFinished(
|
||||
acquisitionFinishedCallBack, pAcquisitionFinished);
|
||||
if (rawDataReadyCallBack != nullptr)
|
||||
impl()->registerCallBackRawDataReady(rawDataReadyCallBack,
|
||||
pRawDataReady);
|
||||
}
|
||||
|
||||
impl()->setThreadIds(parentThreadId, tcpThreadId);
|
||||
}
|
||||
|
@ -34,9 +34,8 @@ class ClientInterface : private virtual slsDetectorDefs {
|
||||
|
||||
//***callback functions***
|
||||
/** params: file path, file name, file index, image size */
|
||||
void registerCallBackStartAcquisition(int (*func)(const startCallbackHeader,
|
||||
void *),
|
||||
void *arg);
|
||||
void registerCallBackStartAcquisition(
|
||||
void (*func)(const startCallbackHeader, void *), void *arg);
|
||||
|
||||
/** params: total frames caught */
|
||||
void registerCallBackAcquisitionFinished(
|
||||
@ -180,8 +179,8 @@ class ClientInterface : private virtual slsDetectorDefs {
|
||||
|
||||
//***callback parameters***
|
||||
|
||||
int (*startAcquisitionCallBack)(const startCallbackHeader,
|
||||
void *) = nullptr;
|
||||
void (*startAcquisitionCallBack)(const startCallbackHeader,
|
||||
void *) = nullptr;
|
||||
void *pStartAcquisition{nullptr};
|
||||
void (*acquisitionFinishedCallBack)(const endCallbackHeader,
|
||||
void *) = nullptr;
|
||||
@ -194,6 +193,8 @@ class ClientInterface : private virtual slsDetectorDefs {
|
||||
pid_t tcpThreadId{0};
|
||||
std::vector<std::string> udpips =
|
||||
std::vector<std::string>(MAX_NUMBER_OF_LISTENING_THREADS);
|
||||
// necessary if Receiver objects using threads with callbacks
|
||||
static std::mutex callbackMutex;
|
||||
};
|
||||
|
||||
} // namespace sls
|
||||
|
621
slsReceiverSoftware/src/FrameSynchronizerApp.cpp
Normal file
621
slsReceiverSoftware/src/FrameSynchronizerApp.cpp
Normal file
@ -0,0 +1,621 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
/* Creates the slsFrameSynchronizer for running multiple receivers in different
|
||||
* threads form a single binary that will spit out zmq streams without
|
||||
* reconstructing image. Sample python script for pull socket for this combiner
|
||||
* in python/scripts folder. TODO: Not handling empty frames from one socket
|
||||
*/
|
||||
#include "sls/Receiver.h"
|
||||
#include "sls/ToString.h"
|
||||
#include "sls/container_utils.h"
|
||||
#include "sls/logger.h"
|
||||
#include "sls/sls_detector_defs.h"
|
||||
|
||||
#include <csignal> //SIGINT
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <mutex>
|
||||
#include <ostream>
|
||||
#include <semaphore.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/wait.h> //wait
|
||||
#include <thread>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <zmq.h>
|
||||
|
||||
std::vector<std::thread> threads;
|
||||
std::vector<sem_t *> semaphores;
|
||||
sls::TLogLevel printHeadersLevel = sls::logDEBUG;
|
||||
|
||||
/** Define Colors to print data call back in different colors for different
|
||||
* recievers */
|
||||
#define PRINT_IN_COLOR(c, f, ...) \
|
||||
printf("\033[%dm" f RESET, 30 + c + 1, ##__VA_ARGS__)
|
||||
|
||||
/** Structure handling different threads */
|
||||
using ZmqMsgList = std::vector<zmq_msg_t *>;
|
||||
using FrameMap = std::map<uint64_t, ZmqMsgList>;
|
||||
using PortFrameMap = std::map<uint16_t, FrameMap>;
|
||||
struct FrameStatus {
|
||||
bool starting = true;
|
||||
bool terminate = false;
|
||||
int num_receivers;
|
||||
sem_t available;
|
||||
std::mutex mtx;
|
||||
ZmqMsgList headers;
|
||||
PortFrameMap frames;
|
||||
ZmqMsgList ends;
|
||||
|
||||
FrameStatus(bool start, bool term, int num_recv)
|
||||
: starting(start), terminate(term), num_receivers(num_recv) {
|
||||
sem_init(&available, 0, 0);
|
||||
}
|
||||
};
|
||||
FrameStatus *global_frame_status = nullptr;
|
||||
|
||||
/**
|
||||
* Control+C Interrupt Handler
|
||||
* to let all the processes know to exit properly
|
||||
*/
|
||||
void sigInterruptHandler(int p) {
|
||||
for (size_t i = 0; i != semaphores.size(); ++i) {
|
||||
sem_post(semaphores[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void cleanup() {
|
||||
if (global_frame_status) {
|
||||
std::lock_guard<std::mutex> lock(global_frame_status->mtx);
|
||||
for (auto &outer_pair : global_frame_status->frames) {
|
||||
for (auto &inner_pair : outer_pair.second) {
|
||||
for (zmq_msg_t *msg : inner_pair.second) {
|
||||
if (msg) {
|
||||
zmq_msg_close(msg);
|
||||
delete msg;
|
||||
}
|
||||
}
|
||||
inner_pair.second.clear();
|
||||
}
|
||||
outer_pair.second.clear();
|
||||
}
|
||||
global_frame_status->frames.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* prints usage of this example program
|
||||
*/
|
||||
std::string getHelpMessage() {
|
||||
std::ostringstream os;
|
||||
os << "\nUsage:\n"
|
||||
"./slsFrameSynchronizer [start tcp port] [num recevers] [print "
|
||||
"callback headers (optional)]\n"
|
||||
<< "\t - tcp port has to be non-zero and 16 bit\n"
|
||||
<< "\t - print callback headers option is 0 (disabled) by default\n";
|
||||
return os.str();
|
||||
}
|
||||
|
||||
void zmq_free(void *data, void *hint) { delete[] static_cast<char *>(data); }
|
||||
|
||||
void print_frames(const PortFrameMap &frame_port_map) {
|
||||
LOG(sls::logDEBUG) << "Printing frames";
|
||||
for (const auto &it : frame_port_map) {
|
||||
uint16_t udpPort = it.first;
|
||||
const auto &frame_map = it.second;
|
||||
LOG(sls::logDEBUG) << "UDP port: " << udpPort;
|
||||
for (const auto &frame : frame_map) {
|
||||
uint64_t fnum = frame.first;
|
||||
const auto &msg_list = frame.second;
|
||||
LOG(sls::logDEBUG)
|
||||
<< " acq index: " << fnum << '[' << msg_list.size() << ']';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Valid frame numbers mean they exist across all ports or
|
||||
* has at least a larger fnum in the port with the missing fnum **/
|
||||
std::set<uint64_t> get_valid_fnums(const PortFrameMap &port_frame_map) {
|
||||
// empty list
|
||||
std::set<uint64_t> valid_fnums;
|
||||
if (port_frame_map.empty()) {
|
||||
return valid_fnums;
|
||||
}
|
||||
|
||||
// collect all unique frame numbers from all ports
|
||||
std::set<uint64_t> unique_fnums;
|
||||
for (auto it = port_frame_map.begin(); it != port_frame_map.begin(); ++it) {
|
||||
const FrameMap &frame_map = it->second;
|
||||
for (auto frame = frame_map.begin(); frame != frame_map.end();
|
||||
++frame) {
|
||||
unique_fnums.insert(frame->first);
|
||||
}
|
||||
}
|
||||
|
||||
// collect valid frame numbers
|
||||
for (auto &fnum : unique_fnums) {
|
||||
bool is_valid = true;
|
||||
for (auto it = port_frame_map.begin(); it != port_frame_map.end();
|
||||
++it) {
|
||||
uint16_t port = it->first;
|
||||
const FrameMap &frame_map = it->second;
|
||||
auto frame = frame_map.find(fnum);
|
||||
// invalid: fnum missing in one port
|
||||
if (frame == frame_map.end()) {
|
||||
LOG(sls::logDEBUG)
|
||||
<< "Fnum " << fnum << " is missing in port " << port;
|
||||
// invalid: fnum greater than all in that port
|
||||
auto last_frame = std::prev(frame_map.end());
|
||||
auto last_fnum = last_frame->first;
|
||||
if (fnum > last_fnum) {
|
||||
LOG(sls::logDEBUG) << "And no larger fnum found. Fnum "
|
||||
<< fnum << " is invalid.\n";
|
||||
is_valid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (is_valid) {
|
||||
valid_fnums.insert(fnum);
|
||||
}
|
||||
}
|
||||
|
||||
return valid_fnums;
|
||||
}
|
||||
|
||||
int zmq_send_multipart(void *socket, const ZmqMsgList &messages) {
|
||||
size_t num_messages = messages.size();
|
||||
for (size_t i = 0; i != num_messages; ++i) {
|
||||
zmq_msg_t *msg = messages[i];
|
||||
// determine flags: ZMQ_SNDMORE for all messages except the last
|
||||
int flags = (i == num_messages - 1) ? 0 : ZMQ_SNDMORE;
|
||||
if (zmq_msg_send(msg, socket, flags) == -1) {
|
||||
LOG(sls::logERROR)
|
||||
<< "Error sending message: " << zmq_strerror(zmq_errno());
|
||||
return slsDetectorDefs::FAIL;
|
||||
}
|
||||
}
|
||||
return slsDetectorDefs::OK;
|
||||
}
|
||||
|
||||
void Correlate(FrameStatus *stat) {
|
||||
void *context = zmq_ctx_new();
|
||||
|
||||
void *socket = zmq_socket(context, ZMQ_PUSH);
|
||||
int rc = zmq_bind(socket, "tcp://*:5555");
|
||||
if (rc != 0) {
|
||||
LOG(sls::logERROR) << "failed to bind";
|
||||
}
|
||||
|
||||
while (true) {
|
||||
sem_wait(&(stat->available));
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(stat->mtx);
|
||||
|
||||
if (stat->terminate) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (stat->starting) {
|
||||
// sending all start packets
|
||||
if (static_cast<int>(stat->headers.size()) ==
|
||||
stat->num_receivers) {
|
||||
stat->starting = false;
|
||||
// clean up
|
||||
zmq_send_multipart(socket, stat->headers);
|
||||
for (zmq_msg_t *msg : stat->headers) {
|
||||
if (msg) {
|
||||
zmq_msg_close(msg);
|
||||
delete msg;
|
||||
}
|
||||
}
|
||||
stat->headers.clear();
|
||||
}
|
||||
} else {
|
||||
// print_frames(stat->frames);
|
||||
auto valid_fnums = get_valid_fnums(stat->frames);
|
||||
// sending all valid fnum data packets
|
||||
for (const auto &fnum : valid_fnums) {
|
||||
ZmqMsgList msg_list;
|
||||
PortFrameMap &port_frame_map = stat->frames;
|
||||
for (auto it = port_frame_map.begin();
|
||||
it != port_frame_map.end(); ++it) {
|
||||
uint16_t port = it->first;
|
||||
const FrameMap &frame_map = it->second;
|
||||
auto frame = frame_map.find(fnum);
|
||||
if (frame != frame_map.end()) {
|
||||
msg_list.insert(msg_list.end(),
|
||||
stat->frames[port][fnum].begin(),
|
||||
stat->frames[port][fnum].end());
|
||||
// clean up
|
||||
for (zmq_msg_t *msg : stat->frames[port][fnum]) {
|
||||
if (msg) {
|
||||
zmq_msg_close(msg);
|
||||
delete msg;
|
||||
}
|
||||
}
|
||||
stat->frames[port].erase(fnum);
|
||||
}
|
||||
}
|
||||
LOG(printHeadersLevel)
|
||||
<< "Sending data packets for fnum " << fnum;
|
||||
zmq_send_multipart(socket, msg_list);
|
||||
}
|
||||
}
|
||||
// sending all end packets
|
||||
if (static_cast<int>(stat->ends.size()) == stat->num_receivers) {
|
||||
zmq_send_multipart(socket, stat->ends);
|
||||
// clean up
|
||||
for (zmq_msg_t *msg : stat->ends) {
|
||||
if (msg) {
|
||||
zmq_msg_close(msg);
|
||||
delete msg;
|
||||
}
|
||||
}
|
||||
stat->ends.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
zmq_close(socket);
|
||||
zmq_ctx_destroy(context);
|
||||
}
|
||||
|
||||
void StartAcquisitionCallback(
|
||||
const slsDetectorDefs::startCallbackHeader callbackHeader,
|
||||
void *objectPointer) {
|
||||
LOG(printHeadersLevel)
|
||||
<< "Start Acquisition:"
|
||||
<< "\n\t["
|
||||
<< "\n\tUDP Port : " << sls::ToString(callbackHeader.udpPort)
|
||||
<< "\n\tDynamic Range : " << callbackHeader.dynamicRange
|
||||
<< "\n\tDetector Shape : "
|
||||
<< sls::ToString(callbackHeader.detectorShape)
|
||||
<< "\n\tImage Size : " << callbackHeader.imageSize
|
||||
<< "\n\tFile Path : " << callbackHeader.filePath
|
||||
<< "\n\tFile Name : " << callbackHeader.fileName
|
||||
<< "\n\tFile Index : " << callbackHeader.fileIndex
|
||||
<< "\n\tQuad Enable : " << callbackHeader.quad
|
||||
<< "\n\tAdditional Json Header : "
|
||||
<< sls::ToString(callbackHeader.addJsonHeader).c_str() << "\n\t]";
|
||||
std::ostringstream oss;
|
||||
oss << "{\"htype\":\"header\""
|
||||
<< ", \"udpPorts\":" << sls::ToString(callbackHeader.udpPort)
|
||||
<< ", \"bitmode\":" << callbackHeader.dynamicRange
|
||||
<< ", \"filePath\":\"" << callbackHeader.filePath
|
||||
<< "\", \"fileName\":\"" << callbackHeader.fileName
|
||||
<< "\", \"fileIndex\":" << callbackHeader.fileIndex
|
||||
<< ", \"detshape\":" << sls::ToString(callbackHeader.detectorShape)
|
||||
<< ", \"size\":" << callbackHeader.imageSize
|
||||
<< ", \"quad\":" << (callbackHeader.quad ? 1 : 0);
|
||||
|
||||
if (!callbackHeader.addJsonHeader.empty()) {
|
||||
oss << ", \"addJsonHeader\": {";
|
||||
for (auto it = callbackHeader.addJsonHeader.begin();
|
||||
it != callbackHeader.addJsonHeader.end(); ++it) {
|
||||
if (it != callbackHeader.addJsonHeader.begin()) {
|
||||
oss << ", ";
|
||||
}
|
||||
oss << "\"" << it->first.c_str() << "\":\"" << it->second.c_str()
|
||||
<< "\"";
|
||||
}
|
||||
oss << " } ";
|
||||
}
|
||||
oss << "}\n";
|
||||
|
||||
std::string message = oss.str();
|
||||
LOG(sls::logDEBUG) << "Start Acquisition message:" << std::endl << message;
|
||||
|
||||
int length = message.length();
|
||||
char *hdata = new char[length];
|
||||
memcpy(hdata, message.c_str(), length);
|
||||
zmq_msg_t *hmsg = new zmq_msg_t;
|
||||
zmq_msg_init_data(hmsg, hdata, length, zmq_free, NULL);
|
||||
|
||||
// push zmq msg into stat to be processed
|
||||
FrameStatus *stat = static_cast<FrameStatus *>(objectPointer);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(stat->mtx);
|
||||
stat->headers.push_back(hmsg);
|
||||
stat->starting = true;
|
||||
// clean up old frames
|
||||
for (int port : callbackHeader.udpPort) {
|
||||
for (auto &frame_map : stat->frames[port]) {
|
||||
for (zmq_msg_t *msg : frame_map.second) {
|
||||
if (msg) {
|
||||
zmq_msg_close(msg);
|
||||
delete msg;
|
||||
}
|
||||
}
|
||||
frame_map.second.clear();
|
||||
}
|
||||
stat->frames[port].clear();
|
||||
}
|
||||
}
|
||||
sem_post(&stat->available);
|
||||
}
|
||||
|
||||
void AcquisitionFinishedCallback(
|
||||
const slsDetectorDefs::endCallbackHeader callbackHeader,
|
||||
void *objectPointer) {
|
||||
LOG(printHeadersLevel) << "Acquisition Finished:"
|
||||
<< "\n\t["
|
||||
<< "\n\tUDP Port : "
|
||||
<< sls::ToString(callbackHeader.udpPort)
|
||||
<< "\n\tComplete Frames : "
|
||||
<< sls::ToString(callbackHeader.completeFrames)
|
||||
<< "\n\tLast Frame Index : "
|
||||
<< sls::ToString(callbackHeader.lastFrameIndex)
|
||||
<< "\n\t]";
|
||||
std::ostringstream oss;
|
||||
oss << "{\"htype\":\"series_end\""
|
||||
<< ", \"udpPorts\":" << sls::ToString(callbackHeader.udpPort)
|
||||
<< ", \"comleteFrames\":"
|
||||
<< sls::ToString(callbackHeader.completeFrames)
|
||||
<< ", \"lastFrameIndex\":"
|
||||
<< sls::ToString(callbackHeader.lastFrameIndex) << "}\n";
|
||||
std::string message = oss.str();
|
||||
int length = message.length();
|
||||
LOG(sls::logDEBUG) << "Acquisition Finished message:" << std::endl
|
||||
<< message;
|
||||
|
||||
char *hdata = new char[length];
|
||||
memcpy(hdata, message.c_str(), length);
|
||||
zmq_msg_t *hmsg = new zmq_msg_t;
|
||||
zmq_msg_init_data(hmsg, hdata, length, zmq_free, NULL);
|
||||
|
||||
// push zmq msg into stat to be processed
|
||||
FrameStatus *stat = static_cast<FrameStatus *>(objectPointer);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(stat->mtx);
|
||||
stat->ends.push_back(hmsg);
|
||||
}
|
||||
sem_post(&stat->available);
|
||||
}
|
||||
|
||||
void GetDataCallback(slsDetectorDefs::sls_receiver_header &header,
|
||||
slsDetectorDefs::dataCallbackHeader callbackHeader,
|
||||
char *dataPointer, size_t &imageSize,
|
||||
void *objectPointer) {
|
||||
|
||||
slsDetectorDefs::sls_detector_header detectorHeader = header.detHeader;
|
||||
|
||||
if (printHeadersLevel < sls::logDEBUG) {
|
||||
// print in different color for each udp port
|
||||
PRINT_IN_COLOR((callbackHeader.udpPort % 10),
|
||||
"Data: "
|
||||
"\n\tCallback Header: "
|
||||
"\n\t["
|
||||
"\n\tUDP Port: %u"
|
||||
"\n\tShape: [%u, %u]"
|
||||
"\n\tAcq Index : %lu"
|
||||
"\n\tFrame Index :%lu"
|
||||
"\n\tProgress : %.2f%%"
|
||||
"\n\tComplete Image :%s"
|
||||
"\n\tFlip Rows :%s"
|
||||
"\n\tAdditional Json Header : %s"
|
||||
"\n\t]"
|
||||
"\n\ttReceiver Header: "
|
||||
"\n\t["
|
||||
"\n\tFrame Number : %lu"
|
||||
"\n\tExposure Length :%u"
|
||||
"\n\tPackets Caught :%u"
|
||||
"\n\tDetector Specific 1: %lu"
|
||||
"\n\tTimestamp : %lu"
|
||||
"\n\tModule Id :%u"
|
||||
"\n\tRow : %u"
|
||||
"\n\tColumn :%u"
|
||||
"\n\tDetector Specific 2 : %u"
|
||||
"\n\tDetector Specific 3 : %u"
|
||||
"\n\tDetector Specific 4 : %u"
|
||||
"\n\tDetector Type : %s"
|
||||
"\n\tVersion: %u"
|
||||
"\n\t]"
|
||||
"\n\tFirst Byte Data: 0x%x"
|
||||
"\n\tImage Size: %zu\n\n",
|
||||
callbackHeader.udpPort, callbackHeader.shape.x,
|
||||
callbackHeader.shape.y, callbackHeader.acqIndex,
|
||||
callbackHeader.frameIndex, callbackHeader.progress,
|
||||
sls::ToString(callbackHeader.completeImage).c_str(),
|
||||
sls::ToString(callbackHeader.flipRows).c_str(),
|
||||
sls::ToString(callbackHeader.addJsonHeader).c_str(),
|
||||
detectorHeader.frameNumber, detectorHeader.expLength,
|
||||
detectorHeader.packetNumber, detectorHeader.detSpec1,
|
||||
detectorHeader.timestamp, detectorHeader.modId,
|
||||
detectorHeader.row, detectorHeader.column,
|
||||
detectorHeader.detSpec2, detectorHeader.detSpec3,
|
||||
detectorHeader.detSpec4,
|
||||
sls::ToString(detectorHeader.detType).c_str(),
|
||||
detectorHeader.version,
|
||||
// header->packetsMask.to_string().c_str(),
|
||||
((uint8_t)(*((uint8_t *)(dataPointer)))), imageSize);
|
||||
}
|
||||
std::ostringstream oss;
|
||||
oss << "{\"htype\":\"module\""
|
||||
<< ", \"port\":" << callbackHeader.udpPort
|
||||
<< ", \"shape\":" << sls::ToString(callbackHeader.shape)
|
||||
<< ", \"acqIndex\":" << callbackHeader.acqIndex
|
||||
<< ", \"frameIndex\":" << callbackHeader.frameIndex
|
||||
<< ", \"flipRows\":" << (callbackHeader.flipRows ? 1 : 0)
|
||||
<< ", \"progress\":" << callbackHeader.progress
|
||||
<< ", \"completeImage\":" << (callbackHeader.completeImage ? 1 : 0)
|
||||
<< ", \"imageSize\":" << imageSize
|
||||
<< ", \"frameNumber\":" << detectorHeader.frameNumber
|
||||
<< ", \"expLength\":" << detectorHeader.expLength
|
||||
<< ", \"packetNumber\":" << detectorHeader.packetNumber
|
||||
<< ", \"detSpec1\":" << detectorHeader.detSpec1
|
||||
<< ", \"timestamp\":" << detectorHeader.timestamp
|
||||
<< ", \"modId\":" << detectorHeader.modId
|
||||
<< ", \"row\":" << detectorHeader.row
|
||||
<< ", \"column\":" << detectorHeader.column
|
||||
<< ", \"detSpec2\":" << detectorHeader.detSpec2
|
||||
<< ", \"detSpec3\":" << detectorHeader.detSpec3
|
||||
<< ", \"detSpec4\":" << detectorHeader.detSpec4
|
||||
<< ", \"detType\":" << static_cast<int>(detectorHeader.detType)
|
||||
<< ", \"version\":" << static_cast<int>(detectorHeader.version);
|
||||
|
||||
if (!callbackHeader.addJsonHeader.empty()) {
|
||||
oss << ", \"addJsonHeader\": {";
|
||||
for (auto it = callbackHeader.addJsonHeader.begin();
|
||||
it != callbackHeader.addJsonHeader.end(); ++it) {
|
||||
if (it != callbackHeader.addJsonHeader.begin()) {
|
||||
oss << ", ";
|
||||
}
|
||||
oss << "\"" << it->first.c_str() << "\":\"" << it->second.c_str()
|
||||
<< "\"";
|
||||
}
|
||||
oss << " } ";
|
||||
}
|
||||
oss << "}\n";
|
||||
std::string message = oss.str();
|
||||
LOG(sls::logDEBUG) << "Data message:" << std::endl << message;
|
||||
|
||||
// creating header part of data packet
|
||||
int length = message.length();
|
||||
char *hdata = new char[length];
|
||||
memcpy(hdata, message.c_str(), length);
|
||||
zmq_msg_t *hmsg = new zmq_msg_t;
|
||||
zmq_msg_init_data(hmsg, hdata, length, zmq_free, NULL);
|
||||
|
||||
// created data part of data packet
|
||||
char *data = new char[imageSize];
|
||||
zmq_msg_t *msg = new zmq_msg_t;
|
||||
zmq_msg_init_data(msg, data, imageSize, zmq_free, NULL);
|
||||
|
||||
// push both parts into stat to be processed
|
||||
FrameStatus *stat = static_cast<FrameStatus *>(objectPointer);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(stat->mtx);
|
||||
stat->frames[callbackHeader.udpPort][header.detHeader.frameNumber]
|
||||
.push_back(hmsg);
|
||||
stat->frames[callbackHeader.udpPort][header.detHeader.frameNumber]
|
||||
.push_back(msg);
|
||||
}
|
||||
sem_post(&stat->available);
|
||||
}
|
||||
|
||||
/**
|
||||
* Example of main program using the Receiver class
|
||||
*
|
||||
* - Defines in file for:
|
||||
* - Default Number of receivers is 1
|
||||
* - Default Start TCP port is 1954
|
||||
*/
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
/** - set default values */
|
||||
int numReceivers = 1;
|
||||
uint16_t startTCPPort = DEFAULT_TCP_RX_PORTNO;
|
||||
bool printHeaders = false;
|
||||
|
||||
/** - get number of receivers and start tcp port from command line
|
||||
* arguments */
|
||||
if (argc > 1) {
|
||||
try {
|
||||
if (argc == 3 || argc == 4) {
|
||||
startTCPPort = sls::StringTo<uint16_t>(argv[1]);
|
||||
if (startTCPPort == 0) {
|
||||
throw std::runtime_error("Invalid start tcp port");
|
||||
}
|
||||
numReceivers = std::stoi(argv[2]);
|
||||
if (numReceivers > 1024) {
|
||||
cprintf(RED,
|
||||
"Did you mix up the order of the arguments?\n%s\n",
|
||||
getHelpMessage().c_str());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (numReceivers == 0) {
|
||||
cprintf(RED, "Invalid number of receivers.\n%s\n",
|
||||
getHelpMessage().c_str());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (argc == 4) {
|
||||
printHeaders = sls::StringTo<bool>(argv[3]);
|
||||
if (printHeaders) {
|
||||
printHeadersLevel = sls::logINFOBLUE;
|
||||
}
|
||||
}
|
||||
} else
|
||||
throw std::runtime_error("Invalid number of arguments");
|
||||
} catch (const std::exception &e) {
|
||||
cprintf(RED, "Error: %s\n%s\n", e.what(), getHelpMessage().c_str());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
cprintf(RESET, "Number of Receivers: %d\n", numReceivers);
|
||||
cprintf(RESET, "Start TCP Port: %hu\n", startTCPPort);
|
||||
cprintf(RESET, "Print Callback Headers: %s\n\n",
|
||||
(printHeaders ? "Enabled" : "Disabled"));
|
||||
|
||||
/** - Catch signal SIGINT to close files and call destructors properly */
|
||||
struct sigaction sa;
|
||||
sa.sa_flags = 0; // no flags
|
||||
sa.sa_handler = sigInterruptHandler; // handler function
|
||||
sigemptyset(&sa.sa_mask); // dont block additional signals during invocation
|
||||
// of handler
|
||||
if (sigaction(SIGINT, &sa, nullptr) == -1) {
|
||||
cprintf(RED, "Could not set handler function for SIGINT\n");
|
||||
}
|
||||
|
||||
/** - Ignore SIG_PIPE, prevents global signal handler, handle locally,
|
||||
instead of a server crashing due to client crash when writing, it just
|
||||
gives error */
|
||||
struct sigaction asa;
|
||||
asa.sa_flags = 0; // no flags
|
||||
asa.sa_handler = SIG_IGN; // handler function
|
||||
sigemptyset(&asa.sa_mask); // dont block additional signals during
|
||||
// invocation of handler
|
||||
if (sigaction(SIGPIPE, &asa, nullptr) == -1) {
|
||||
cprintf(RED, "Could not set handler function for SIGPIPE\n");
|
||||
}
|
||||
|
||||
FrameStatus stat{true, false, numReceivers};
|
||||
// store pointer for signal handler
|
||||
global_frame_status = &stat;
|
||||
|
||||
// thread synchronizing all packets
|
||||
void *user_data = static_cast<void *>(&stat);
|
||||
std::thread combinerThread(Correlate, &stat);
|
||||
|
||||
for (int i = 0; i != numReceivers; ++i) {
|
||||
sem_t *semaphore = new sem_t;
|
||||
sem_init(semaphore, 1, 0);
|
||||
semaphores.push_back(semaphore);
|
||||
|
||||
uint16_t port = startTCPPort + i;
|
||||
threads.emplace_back([i, semaphore, port, user_data]() {
|
||||
sls::Receiver receiver(port);
|
||||
receiver.registerCallBackStartAcquisition(StartAcquisitionCallback,
|
||||
user_data);
|
||||
receiver.registerCallBackAcquisitionFinished(
|
||||
AcquisitionFinishedCallback, user_data);
|
||||
receiver.registerCallBackRawDataReady(GetDataCallback, user_data);
|
||||
/** - as long as no Ctrl+C */
|
||||
sem_wait(semaphore);
|
||||
sem_destroy(semaphore);
|
||||
delete semaphore;
|
||||
|
||||
// clean up frames
|
||||
if (i == 0)
|
||||
cleanup();
|
||||
});
|
||||
}
|
||||
|
||||
for (auto &thread : threads) {
|
||||
thread.join();
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(stat.mtx);
|
||||
stat.terminate = true;
|
||||
sem_post(&stat.available);
|
||||
}
|
||||
combinerThread.join();
|
||||
sem_destroy(&stat.available);
|
||||
|
||||
LOG(sls::logINFOBLUE) << "Goodbye!";
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -1802,7 +1802,7 @@ void Implementation::setTransceiverEnableMask(uint32_t mask) {
|
||||
* *
|
||||
* ************************************************/
|
||||
void Implementation::registerCallBackStartAcquisition(
|
||||
int (*func)(const startCallbackHeader, void *), void *arg) {
|
||||
void (*func)(const startCallbackHeader, void *), void *arg) {
|
||||
startAcquisitionCallBack = func;
|
||||
pStartAcquisition = arg;
|
||||
}
|
||||
|
@ -265,9 +265,8 @@ class Implementation : private virtual slsDetectorDefs {
|
||||
* *
|
||||
* ************************************************/
|
||||
/** params: file path, file name, file index, image size */
|
||||
void registerCallBackStartAcquisition(int (*func)(const startCallbackHeader,
|
||||
void *),
|
||||
void *arg);
|
||||
void registerCallBackStartAcquisition(
|
||||
void (*func)(const startCallbackHeader, void *), void *arg);
|
||||
/** params: total frames caught */
|
||||
void registerCallBackAcquisitionFinished(
|
||||
void (*func)(const endCallbackHeader, void *), void *arg);
|
||||
@ -374,7 +373,8 @@ class Implementation : private virtual slsDetectorDefs {
|
||||
int ctbDbitOffset{0};
|
||||
|
||||
// callbacks
|
||||
int (*startAcquisitionCallBack)(const startCallbackHeader, void *){nullptr};
|
||||
void (*startAcquisitionCallBack)(const startCallbackHeader,
|
||||
void *){nullptr};
|
||||
void *pStartAcquisition{nullptr};
|
||||
void (*acquisitionFinishedCallBack)(const endCallbackHeader,
|
||||
void *){nullptr};
|
||||
|
@ -149,12 +149,12 @@ void Listener::CreateUDPSocket(int &actualSize) {
|
||||
packetSize = generalData->vetoPacketSize;
|
||||
}
|
||||
|
||||
std::string ip =
|
||||
(eth.length() ? InterfaceNameToIp(eth).str().c_str() : "");
|
||||
|
||||
std::string ip;
|
||||
if (eth.length() > 0)
|
||||
ip = InterfaceNameToIp(eth).str();
|
||||
udpSocket = nullptr;
|
||||
udpSocket = make_unique<UdpRxSocket>(
|
||||
udpPortNumber, packetSize, (ip.length() ? ip.c_str() : nullptr),
|
||||
udpPortNumber, packetSize, (ip.empty() ? nullptr : ip.c_str()),
|
||||
generalData->udpSocketBufferSize);
|
||||
LOG(logINFO) << index << ": UDP port opened at port " << udpPortNumber
|
||||
<< " (" << (ip.length() ? ip : "any") << ')';
|
||||
@ -213,10 +213,13 @@ void Listener::CreateDummySocketForUDPSocketBufferSize(int s, int &actualSize) {
|
||||
try {
|
||||
// to allowe ports to be bound from udpsocket
|
||||
udpSocket.reset();
|
||||
UdpRxSocket g(
|
||||
udpPortNumber, packetSize,
|
||||
(eth.length() ? InterfaceNameToIp(eth).str().c_str() : nullptr),
|
||||
generalData->udpSocketBufferSize);
|
||||
|
||||
std::string ip;
|
||||
if (eth.length() > 0)
|
||||
ip = InterfaceNameToIp(eth).str();
|
||||
UdpRxSocket g(udpPortNumber, packetSize,
|
||||
(ip.empty() ? nullptr : ip.c_str()),
|
||||
generalData->udpSocketBufferSize);
|
||||
|
||||
// doubled due to kernel bookkeeping (could also be less due to
|
||||
// permissions)
|
||||
|
@ -53,8 +53,8 @@ std::string getHelpMessage() {
|
||||
* enabled) if registerCallBackRawDataReady or
|
||||
* registerCallBackRawDataModifyReady registered, users get data
|
||||
*/
|
||||
int StartAcq(const slsDetectorDefs::startCallbackHeader callbackHeader,
|
||||
void *objectPointer) {
|
||||
void StartAcq(const slsDetectorDefs::startCallbackHeader callbackHeader,
|
||||
void *objectPointer) {
|
||||
LOG(sls::logINFOBLUE) << "#### Start Acquisition:"
|
||||
<< "\n\t["
|
||||
<< "\n\tUDP Port : "
|
||||
@ -71,7 +71,6 @@ int StartAcq(const slsDetectorDefs::startCallbackHeader callbackHeader,
|
||||
<< "\n\tAdditional Json Header : "
|
||||
<< sls::ToString(callbackHeader.addJsonHeader)
|
||||
<< "\n\t]";
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Acquisition Finished Call back */
|
||||
|
@ -134,7 +134,7 @@ std::string Receiver::getReceiverVersion() {
|
||||
}
|
||||
|
||||
void Receiver::registerCallBackStartAcquisition(
|
||||
int (*func)(const startCallbackHeader, void *), void *arg) {
|
||||
void (*func)(const startCallbackHeader, void *), void *arg) {
|
||||
tcpipInterface->registerCallBackStartAcquisition(func, arg);
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,8 @@ enum TLogLevel {
|
||||
logINFOBLUE,
|
||||
logINFOGREEN,
|
||||
logINFORED,
|
||||
logINFOCYAN,
|
||||
logINFOMAGENTA,
|
||||
logINFO,
|
||||
logDEBUG,
|
||||
logDEBUG1,
|
||||
@ -60,16 +62,25 @@ class Logger {
|
||||
// Danger this buffer need as many elements as TLogLevel
|
||||
static const char *Color(TLogLevel level) noexcept {
|
||||
static const char *const colors[] = {
|
||||
RED BOLD, YELLOW BOLD, BLUE, GREEN, RED, RESET,
|
||||
RESET, RESET, RESET, RESET, RESET, RESET};
|
||||
RED BOLD, YELLOW BOLD, BLUE, GREEN, RED, CYAN, MAGENTA,
|
||||
RESET, RESET, RESET, RESET, RESET, RESET, RESET};
|
||||
// out of bounds
|
||||
if (level < 0 || level >= sizeof(colors) / sizeof(colors[0])) {
|
||||
return RESET;
|
||||
}
|
||||
return colors[level];
|
||||
}
|
||||
|
||||
// Danger this buffer need as many elements as TLogLevel
|
||||
static std::string ToString(TLogLevel level) {
|
||||
static const char *const buffer[] = {
|
||||
"ERROR", "WARNING", "INFO", "INFO", "INFO", "INFO",
|
||||
"DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4", "DEBUG5"};
|
||||
"ERROR", "WARNING", "INFO", "INFO", "INFO",
|
||||
"INFO", "INFO", "INFO", "DEBUG", "DEBUG1",
|
||||
"DEBUG2", "DEBUG3", "DEBUG4", "DEBUG5"};
|
||||
// out of bounds
|
||||
if (level < 0 || level >= sizeof(buffer) / sizeof(buffer[0])) {
|
||||
return "UNKNOWN";
|
||||
}
|
||||
return buffer[level];
|
||||
}
|
||||
|
||||
|
@ -5,9 +5,9 @@
|
||||
#define APIGOTTHARD2 "developer 0x241107"
|
||||
#define APIMOENCH "developer 0x241107"
|
||||
#define APIEIGER "developer 0x241107"
|
||||
#define APIJUNGFRAU "developer 0x241120"
|
||||
#define APILIB "developer 0x241122"
|
||||
#define APIRECEIVER "developer 0x241122"
|
||||
#define APIXILINXCTB "developer 0x250131"
|
||||
#define APICTB "developer 0x250131"
|
||||
#define APIMYTHEN3 "developer 0x250131"
|
||||
#define APIXILINXCTB "developer 0x250213"
|
||||
#define APIJUNGFRAU "developer 0x250224"
|
||||
#define APIMYTHEN3 "developer 0x250304"
|
||||
|
Reference in New Issue
Block a user