mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-04-28 09:10:01 +02:00
merge fix
This commit is contained in:
commit
0b45fdfed8
@ -96,6 +96,20 @@ target_compile_options(slsProjectWarnings INTERFACE
|
||||
|
||||
)
|
||||
|
||||
#Settings for C code
|
||||
add_library(slsProjectCSettings INTERFACE)
|
||||
target_compile_features(slsProjectCSettings INTERFACE c_std_99)
|
||||
target_compile_options(slsProjectCSettings INTERFACE
|
||||
-Wall
|
||||
-Wextra
|
||||
-Wno-unused-parameter
|
||||
-Wdouble-promotion
|
||||
-Wformat=2
|
||||
-Wredundant-decls
|
||||
-Wdouble-promotion
|
||||
-Werror=return-type
|
||||
)
|
||||
|
||||
|
||||
#Testing for minimum version for compilers
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
|
65
RELEASE.txt
65
RELEASE.txt
@ -1,7 +1,7 @@
|
||||
SLS Detector Package 5.2.0 released on 28.07.2021 (Minor Release)
|
||||
SLS Detector Package 6.0.0 released on xx.10.2021 (Major Release)
|
||||
===================================================================
|
||||
|
||||
This document describes the differences between 5.2.0 and 5.1.0 releases.
|
||||
This document describes the differences between 6.0.0 and 5.2.0 releases.
|
||||
|
||||
|
||||
|
||||
@ -83,16 +83,71 @@ virtual server plots increasing values for every packet.. not every pixel
|
||||
3. Firmware Requirements
|
||||
========================
|
||||
|
||||
Gotthard2: 0x210201 ???
|
||||
Eiger
|
||||
=====
|
||||
Compatible version : 08.09.2020 (v27)
|
||||
|
||||
Jungfrau
|
||||
========
|
||||
Compatible version : 31.08.2021 (v1.2, PCB v1.0)
|
||||
: 10.09.2021 (v2.2, PCB v2.0)
|
||||
|
||||
Gotthard
|
||||
========
|
||||
Compatible version : 08.02.2018 (50um and 25um Master)
|
||||
: 09.02.2018 (25 um Slave)
|
||||
|
||||
Mythen3
|
||||
=======
|
||||
Compatible version : 10.09.2021 (development)
|
||||
|
||||
Gotthard2
|
||||
=========
|
||||
Compatible version : 27.05.2021 (v1.0)
|
||||
|
||||
Moench
|
||||
======
|
||||
Compatible version : 05.10.2020 (v1.0)
|
||||
|
||||
Ctb
|
||||
===
|
||||
Compatible version : 05.10.2020 (v1.0)
|
||||
|
||||
Detector Upgrade
|
||||
================
|
||||
|
||||
The following can be upgraded remotely:
|
||||
Eiger via bit files
|
||||
Jungfrau via command <.pof>
|
||||
Mythen3 via command <.rbf>
|
||||
Gotthard2 via command <.rbf>
|
||||
Moench via command <.pof>
|
||||
Ctb via command <.pof>
|
||||
|
||||
The following cannot be upgraded remotely:
|
||||
Gotthard
|
||||
|
||||
Instructions available at
|
||||
https://slsdetectorgroup.github.io/devdoc/firmware.html
|
||||
and
|
||||
https://slsdetectorgroup.github.io/devdoc/serverupgrade.html
|
||||
|
||||
Other detectors no updates from 5.1.0
|
||||
|
||||
|
||||
|
||||
5. Known Issues
|
||||
===============
|
||||
|
||||
No updates from 5.1.0
|
||||
Receiver
|
||||
--------
|
||||
1. It does not handle readnrows or partial readout. Only the summary
|
||||
is adjusted to print in red. However, it will still write complete
|
||||
images with missing data padded. Roi will be implemented in future
|
||||
that can be complimented with this feature to remove the additional
|
||||
data in files.
|
||||
|
||||
2. Round robin is not implemented in receiver side, ie. one cannot configure
|
||||
more than 1 receiver at a time. This will/might be done in the future.
|
||||
|
||||
|
||||
|
||||
|
@ -154,6 +154,8 @@ Upgrade (from v5.0.0)
|
||||
|
||||
Check :ref:`firmware troubleshooting <blackfin firmware troubleshooting>` if you run into issues while programming firmware.
|
||||
|
||||
Always ensure that the client and server software are of the same release.
|
||||
|
||||
|
||||
#. Program from console
|
||||
.. code-block:: bash
|
||||
@ -222,6 +224,8 @@ Download
|
||||
Upgrade (from v5.0.0)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Always ensure that the client and server software are of the same release.
|
||||
|
||||
#. Program from console
|
||||
.. code-block:: bash
|
||||
|
||||
@ -251,6 +255,8 @@ Download
|
||||
Upgrade (from v5.0.0)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Always ensure that the client and server software are of the same release.
|
||||
|
||||
#. Program from console
|
||||
.. code-block:: bash
|
||||
|
||||
@ -278,6 +284,8 @@ Upgrade (from v5.0.0)
|
||||
|
||||
Check :ref:`firmware troubleshooting <blackfin firmware troubleshooting>` if you run into issues while programming firmware.
|
||||
|
||||
Always ensure that the client and server software are of the same release.
|
||||
|
||||
#. Program from console
|
||||
.. code-block:: bash
|
||||
|
||||
@ -304,6 +312,8 @@ Upgrade (from v5.0.0)
|
||||
|
||||
Check :ref:`firmware troubleshooting <blackfin firmware troubleshooting>` if you run into issues while programming firmware.
|
||||
|
||||
Always ensure that the client and server software are of the same release.
|
||||
|
||||
#. Program from console
|
||||
.. code-block:: bash
|
||||
|
||||
@ -344,25 +354,42 @@ Firmware Troubleshooting with blackfin
|
||||
|
||||
5. If one can't list it, read the next section to try to get the blackfin to list it.
|
||||
|
||||
How to get back mtd3 drive remotely
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
This might take a few reruns (maybe even 10) until the mtd drive is accessed by the blackfin upon linux startup.
|
||||
How to get back mtd3 drive remotely (copying new kernel)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# step 1: connect to the board
|
||||
# step 1: get the kernel image (uImage.lzma) from slsdetectorgroup
|
||||
# and copy it to pc's tftp folder
|
||||
|
||||
# step 2: connect to the board
|
||||
telnet bchipxxx
|
||||
|
||||
# step 2: check if mtd3 drive listed
|
||||
more /proc/mtd
|
||||
#step 3: go to directory for space
|
||||
cd /var/tmp/
|
||||
|
||||
# step 3: tell fpga not to touch flash and reboot
|
||||
echo 9 > /sys/class/gpio/export;
|
||||
echo out > /sys/class/gpio/gpio9/direction;
|
||||
echo 0 > /sys/class/gpio/gpio9/value;
|
||||
# step 3: copy kernel to board
|
||||
tftp pcxxx -r uImage.lzma -g
|
||||
|
||||
# step 4: verify kernel copied properly
|
||||
ls -lrt
|
||||
|
||||
# step 5: erase flash
|
||||
flash_eraseall /dev/mtd1
|
||||
|
||||
# step 6: copy new image to kernel drive
|
||||
cat uImage.lzma > /dev/mtd1
|
||||
|
||||
# step 7:
|
||||
sync
|
||||
|
||||
# step 8:
|
||||
reboot
|
||||
|
||||
# step 4: repeat steps 1 - 3 until you see the mtd3 drive
|
||||
# step 9: verification
|
||||
telnet bchipxxx
|
||||
uname -a # verify kernel date
|
||||
more /proc/mtd # verify mtd3 is listed
|
||||
|
||||
|
||||
Last Resort using USB Blaster
|
||||
|
@ -41,14 +41,16 @@ Automatic start
|
||||
|
||||
One can start the on-board detector server automatically upon powering on the board.
|
||||
|
||||
First 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
|
||||
|
||||
Then, do the following depending on the detector type.
|
||||
|
||||
|
||||
#. Do the following depending on the detector type :
|
||||
|
||||
Eiger
|
||||
.. code-block:: bash
|
||||
|
||||
@ -67,16 +69,27 @@ Jungfrau | Moench | CTB | Gotthard I
|
||||
vi /etc/inittab
|
||||
|
||||
# enter the following line
|
||||
ttyS0::respawn:/./jungfrauDetectorServer
|
||||
ttyS0::respawn:/./xxxDetectorServer
|
||||
|
||||
|
||||
Gotthard II | Mythen III
|
||||
.. code-block:: bash
|
||||
|
||||
# create script in init.d on the board
|
||||
# create script in init.d on board
|
||||
vi /etc/init.d/S99detServer.sh
|
||||
|
||||
# enter the following (edit server name)
|
||||
#! /bin/sh
|
||||
cd /root >> /dev/null
|
||||
/root/mythen3DetectorServer >> /dev/null &
|
||||
/root/xxxDetectorServer >> /dev/null &
|
||||
|
||||
|
||||
#. Sync, reboot and verify
|
||||
:
|
||||
.. code-block:: bash
|
||||
|
||||
sync
|
||||
reboot
|
||||
|
||||
# verify
|
||||
ps -ef | grep xxxDetectorServer
|
@ -1,17 +1,5 @@
|
||||
|
||||
add_library(slsProjectCSettings INTERFACE)
|
||||
target_compile_features(slsProjectCSettings INTERFACE c_std_99)
|
||||
target_compile_options(slsProjectCSettings INTERFACE
|
||||
-Wall
|
||||
-Wextra
|
||||
-Wno-unused-parameter #Needs to be slowly mitigated
|
||||
-Wdouble-promotion
|
||||
-Wformat=2
|
||||
-Wredundant-decls
|
||||
# -Wconversion
|
||||
-Wdouble-promotion
|
||||
-Werror=return-type
|
||||
)
|
||||
|
||||
|
||||
# Install fake the library
|
||||
install(TARGETS slsProjectCSettings
|
||||
|
@ -18,6 +18,7 @@ add_executable(ctbDetectorServer_virtual
|
||||
../slsDetectorServer/src/programFpgaBlackfin.c
|
||||
../slsDetectorServer/src/sharedMemory.c
|
||||
../slsDetectorServer/src/loadPattern.c
|
||||
../../slsSupportLib/src/md5.c
|
||||
)
|
||||
|
||||
include_directories(
|
||||
|
@ -3,6 +3,7 @@ main_inc = ../slsDetectorServer/include/
|
||||
main_src = ../slsDetectorServer/src/
|
||||
support_lib = ../../slsSupportLib/include/
|
||||
det_lib = ../../slsDetectorSoftware/include/sls/
|
||||
md5_dir = ../../slsSupportLib/src/
|
||||
|
||||
CROSS = bfin-uclinux-
|
||||
CC = $(CROSS)gcc
|
||||
@ -13,7 +14,7 @@ DESTDIR ?= bin
|
||||
INSTMODE = 0777
|
||||
|
||||
SRCS = slsDetectorFunctionList.c
|
||||
SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)communication_funcs_UDP.c $(main_src)UDPPacketHeaderGenerator.c $(main_src)AD7689.c $(main_src)AD9257.c $(main_src)ALTERA_PLL.c $(main_src)I2C.c $(main_src)INA226.c $(main_src)LTC2620.c $(main_src)MAX1932.c $(main_src)programFpgaBlackfin.c $(main_src)/sharedMemory.c $(main_src)/loadPattern.c
|
||||
SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)communication_funcs_UDP.c $(main_src)UDPPacketHeaderGenerator.c $(main_src)AD7689.c $(main_src)AD9257.c $(main_src)ALTERA_PLL.c $(main_src)I2C.c $(main_src)INA226.c $(main_src)LTC2620.c $(main_src)MAX1932.c $(main_src)programFpgaBlackfin.c $(main_src)/sharedMemory.c $(main_src)/loadPattern.c $(md5_dir)md5.c
|
||||
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
|
||||
@ -34,10 +35,10 @@ $(PROGS): $(OBJS)
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LDLIBS)
|
||||
mv $(PROGS) $(DESTDIR)
|
||||
rm *.gdb
|
||||
rm $(main_src)*.o
|
||||
rm $(main_src)*.o $(md5_dir)*.o
|
||||
|
||||
clean:
|
||||
rm -rf $(DESTDIR)/$(PROGS) *.o *.gdb $(main_src)*.o
|
||||
rm -rf $(DESTDIR)/$(PROGS) *.o *.gdb $(main_src)*.o $(md5_dir)*.o
|
||||
|
||||
|
||||
|
||||
|
Binary file not shown.
@ -6,6 +6,7 @@ set(src
|
||||
../slsDetectorServer/src/communication_funcs_UDP.c
|
||||
../slsDetectorServer/src/common.c
|
||||
../slsDetectorServer/src/sharedMemory.c
|
||||
../../slsSupportLib/src/md5.c
|
||||
)
|
||||
|
||||
include_directories(
|
||||
|
@ -2,6 +2,7 @@ current_dir = $(shell pwd)
|
||||
main_inc = ../slsDetectorServer/include/
|
||||
main_src = ../slsDetectorServer/src/
|
||||
support_lib = ../../slsSupportLib/include/
|
||||
md5_dir = ../../slsSupportLib/src/
|
||||
|
||||
BLACKFIN_CC = bfin-uclinux-gcc
|
||||
CROSS = powerpc-4xx-softfloat-
|
||||
@ -13,7 +14,7 @@ DESTDIR = bin
|
||||
INSTMODE = 0777
|
||||
|
||||
SRCS = slsDetectorFunctionList.c HardwareIO.c LocalLinkInterface.c FebInterface.c FebControl.c Beb.c
|
||||
SRCS += $(main_src)communication_funcs.c $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs_UDP.c $(main_src)common.c $(main_src)/sharedMemory.c
|
||||
SRCS += $(main_src)communication_funcs.c $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs_UDP.c $(main_src)common.c $(main_src)/sharedMemory.c $(md5_dir)md5.c
|
||||
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
|
||||
@ -40,9 +41,9 @@ $(PROGS): $(OBJS)
|
||||
hv9m_blackfin_server:9mhvserial_bf.c
|
||||
$(BLACKFIN_CC) -o hv9m_blackfin_server 9mhvserial_bf.c -Wall #-DVERBOSE
|
||||
mv hv9m_blackfin_server $(DESTDIR)
|
||||
rm hv9m_blackfin_server.gdb $(main_server)*.o
|
||||
rm hv9m_blackfin_server.gdb $(main_src)*.o $(md5_dir)*.o
|
||||
|
||||
clean:
|
||||
rm -rf $(DESTDIR)/$(PROGS) *.o $(DESTDIR)/hv9m_blackfin_server $(main_server)*.o
|
||||
rm -rf $(DESTDIR)/$(PROGS) *.o $(DESTDIR)/hv9m_blackfin_server $(main_src)*.o $(md5_dir)*.o
|
||||
|
||||
|
||||
|
Binary file not shown.
@ -12,6 +12,7 @@ add_executable(gotthard2DetectorServer_virtual
|
||||
../slsDetectorServer/src/ASIC_Driver.c
|
||||
../slsDetectorServer/src/programFpgaNios.c
|
||||
../slsDetectorServer/src/sharedMemory.c
|
||||
../../slsSupportLib/src/md5.c
|
||||
)
|
||||
|
||||
include_directories(
|
||||
|
@ -2,6 +2,7 @@ current_dir = $(shell pwd)
|
||||
main_inc = ../slsDetectorServer/include/
|
||||
main_src = ../slsDetectorServer/src/
|
||||
support_lib = ../../slsSupportLib/include/
|
||||
md5_dir = ../../slsSupportLib/src/
|
||||
|
||||
CROSS = nios2-buildroot-linux-gnu-
|
||||
CC = $(CROSS)gcc
|
||||
@ -12,7 +13,7 @@ DESTDIR ?= bin
|
||||
INSTMODE = 0777
|
||||
|
||||
SRCS = slsDetectorFunctionList.c
|
||||
SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)nios.c $(main_src)common.c $(main_src)DAC6571.c $(main_src)LTC2620_Driver.c $(main_src)ALTERA_PLL_CYCLONE10.c $(main_src)ASIC_Driver.c $(main_src)/programFpgaNios.c $(main_src)/sharedMemory.c
|
||||
SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)nios.c $(main_src)common.c $(main_src)DAC6571.c $(main_src)LTC2620_Driver.c $(main_src)ALTERA_PLL_CYCLONE10.c $(main_src)ASIC_Driver.c $(main_src)/programFpgaNios.c $(main_src)/sharedMemory.c $(md5_dir)md5.c
|
||||
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
|
||||
@ -34,10 +35,10 @@ $(PROGS): $(OBJS)
|
||||
mv $(PROGS) $(DESTDIR)
|
||||
cp config_gotthard2.txt $(DESTDIR)
|
||||
cp detid_gotthard2.txt $(DESTDIR)
|
||||
rm $(main_src)*.o
|
||||
rm $(main_src)*.o $(md5_dir)*.o
|
||||
|
||||
clean:
|
||||
rm -rf $(DESTDIR)/$(PROGS) *.o *.gdb $(main_src)*.o
|
||||
rm -rf $(DESTDIR)/$(PROGS) *.o *.gdb $(main_src)*.o $(md5_dir)*.o
|
||||
|
||||
|
||||
|
@ -149,6 +149,10 @@
|
||||
#define ASIC_CONFIG_CURRENT_SRC_EN_MSK (0x00000001 << ASIC_CONFIG_CURRENT_SRC_EN_OFST)
|
||||
#define ASIC_CONFIG_RST_DAC_OFST (15)
|
||||
#define ASIC_CONFIG_RST_DAC_MSK (0x00000001 << ASIC_CONFIG_RST_DAC_OFST)
|
||||
#define ASIC_CONFIG_DOUT_RDY_SRC_OFST (16)
|
||||
#define ASIC_CONFIG_DOUT_RDY_SRC_MSK (0x0000000F << ASIC_CONFIG_DOUT_RDY_SRC_OFST)
|
||||
#define ASIC_CONFIG_DOUT_RDY_DLY_OFST (20)
|
||||
#define ASIC_CONFIG_DOUT_RDY_DLY_MSK (0x000000FF << ASIC_CONFIG_DOUT_RDY_DLY_OFST)
|
||||
#define ASIC_CONFIG_DONE_OFST (31)
|
||||
#define ASIC_CONFIG_DONE_MSK (0x00000001 << ASIC_CONFIG_DONE_OFST)
|
||||
|
||||
|
Binary file not shown.
@ -472,6 +472,11 @@ void setupDetector() {
|
||||
// power on chip
|
||||
powerChip(1);
|
||||
|
||||
setASICDefaults();
|
||||
|
||||
setPhase(READOUT_C1, DEFAULT_CLK1_PHASE_DEG, 1);
|
||||
setDBITPipeline(DEFAULT_DBIT_PIPELINE);
|
||||
|
||||
// also sets default dac and on chip dac values
|
||||
if (readConfigFile() == FAIL) {
|
||||
return;
|
||||
@ -503,6 +508,24 @@ void setupDetector() {
|
||||
setVetoAlgorithm(DEFAULT_ALGORITHM, ETHERNET_10GB);
|
||||
}
|
||||
|
||||
void setASICDefaults() {
|
||||
uint32_t addr = ASIC_CONFIG_REG;
|
||||
|
||||
// dout ready source
|
||||
bus_w(addr, bus_r(addr) & ~ASIC_CONFIG_DOUT_RDY_SRC_MSK);
|
||||
bus_w(addr, bus_r(addr) | ((DEFAULT_ASIC_DOUT_RDY_SRC
|
||||
<< ASIC_CONFIG_DOUT_RDY_SRC_OFST) &
|
||||
ASIC_CONFIG_DOUT_RDY_SRC_MSK));
|
||||
// dout ready delay
|
||||
bus_w(addr, bus_r(addr) & ~ASIC_CONFIG_DOUT_RDY_DLY_MSK);
|
||||
bus_w(addr, bus_r(addr) | ((DEFAULT_ASIC_DOUT_RDY_DLY
|
||||
<< ASIC_CONFIG_DOUT_RDY_DLY_OFST) &
|
||||
ASIC_CONFIG_DOUT_RDY_DLY_MSK));
|
||||
// config done
|
||||
bus_w(addr, bus_r(addr) | ASIC_CONFIG_DONE_MSK);
|
||||
LOG(logINFO, ("Setting ASIC Defaults (0x%x)\n", bus_r(addr)));
|
||||
}
|
||||
|
||||
int resetToDefaultDacs(int hardReset) {
|
||||
// reset defaults to hardcoded defaults
|
||||
if (hardReset) {
|
||||
|
@ -52,8 +52,8 @@
|
||||
#define DEFAULT_TIMING_SOURCE (TIMING_INTERNAL)
|
||||
#define DEFAULT_ALGORITHM (ALG_HITS)
|
||||
|
||||
#define DEFAULT_READOUT_C0 (6) //(144444448) // rdo_clk, 144 MHz
|
||||
#define DEFAULT_READOUT_C1 (6) //(144444448) // rdo_x2_clk, 144 MHz
|
||||
#define DEFAULT_READOUT_C0 (8) //(108333336) // rdo_clk, 144 MHz
|
||||
#define DEFAULT_READOUT_C1 (8) //(108333336) // rdo_x2_clk, 144 MHz
|
||||
#define DEFAULT_SYSTEM_C0 (5) //(144444448) // run_clk, 144 MHz
|
||||
#define DEFAULT_SYSTEM_C1 (10) //(72222224) // chip_clk, 72 MHz
|
||||
#define DEFAULT_SYSTEM_C2 (5) //(144444448) // sync_clk, 144 MHz
|
||||
@ -65,6 +65,11 @@
|
||||
#define READOUT_PLL_VCO_FREQ_HZ (866666688) // 866 MHz
|
||||
#define SYSTEM_PLL_VCO_FREQ_HZ (722222224) // 722 MHz
|
||||
|
||||
#define DEFAULT_CLK1_PHASE_DEG (270)
|
||||
#define DEFAULT_DBIT_PIPELINE (1)
|
||||
#define DEFAULT_ASIC_DOUT_RDY_SRC (0x5)
|
||||
#define DEFAULT_ASIC_DOUT_RDY_DLY (0x3)
|
||||
|
||||
#define VETO_DATA_SIZE (160)
|
||||
typedef struct {
|
||||
uint64_t frameNumber;
|
||||
|
@ -11,6 +11,7 @@ add_executable(gotthardDetectorServer_virtual
|
||||
../slsDetectorServer/src/commonServerFunctions.c
|
||||
../slsDetectorServer/src/communication_funcs_UDP.c
|
||||
../slsDetectorServer/src/sharedMemory.c
|
||||
../../slsSupportLib/src/md5.c
|
||||
)
|
||||
|
||||
include_directories(
|
||||
|
@ -2,6 +2,7 @@ current_dir = $(shell pwd)
|
||||
main_inc = ../slsDetectorServer/include/
|
||||
main_src = ../slsDetectorServer/src/
|
||||
support_lib = ../../slsSupportLib/include/
|
||||
md5_dir = ../../slsSupportLib/src/
|
||||
|
||||
CROSS = bfin-uclinux-
|
||||
CC = $(CROSS)gcc
|
||||
@ -12,7 +13,7 @@ DESTDIR ?= bin
|
||||
INSTMODE = 0777
|
||||
|
||||
SRCS = slsDetectorFunctionList.c
|
||||
SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)AD9252.c $(main_src)AD9257.c $(main_src)LTC2620.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)/sharedMemory.c
|
||||
SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)AD9252.c $(main_src)AD9257.c $(main_src)LTC2620.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)/sharedMemory.c $(md5_dir)md5.c
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
|
||||
all: clean $(PROGS)
|
||||
@ -33,10 +34,10 @@ $(PROGS): $(OBJS)
|
||||
mv $(PROGS) $(DESTDIR)
|
||||
cp config_gotthard.txt $(DESTDIR)
|
||||
rm *.gdb
|
||||
rm $(main_src)*.o
|
||||
rm $(main_src)*.o $(md5_dir)*.o
|
||||
|
||||
clean:
|
||||
rm -rf $(DESTDIR)/$(PROGS) *.o *.gdb $(main_src)*.o
|
||||
rm -rf $(DESTDIR)/$(PROGS) *.o *.gdb $(main_src)*.o $(md5_dir)*.o
|
||||
|
||||
|
||||
|
||||
|
Binary file not shown.
@ -13,6 +13,7 @@ add_executable(jungfrauDetectorServer_virtual
|
||||
../slsDetectorServer/src/programFpgaBlackfin.c
|
||||
../slsDetectorServer/src/communication_funcs_UDP.c
|
||||
../slsDetectorServer/src/sharedMemory.c
|
||||
../../slsSupportLib/src/md5.c
|
||||
)
|
||||
|
||||
target_include_directories(jungfrauDetectorServer_virtual
|
||||
|
@ -2,6 +2,7 @@ current_dir = $(shell pwd)
|
||||
main_inc = ../slsDetectorServer/include/
|
||||
main_src = ../slsDetectorServer/src/
|
||||
support_lib = ../../slsSupportLib/include/
|
||||
md5_dir = ../../slsSupportLib/src/
|
||||
|
||||
CROSS = bfin-uclinux-
|
||||
CC = $(CROSS)gcc
|
||||
@ -12,7 +13,7 @@ DESTDIR ?= bin
|
||||
INSTMODE = 0777
|
||||
|
||||
SRCS = slsDetectorFunctionList.c
|
||||
SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)AD9257.c $(main_src)ALTERA_PLL.c $(main_src)LTC2620.c $(main_src)MAX1932.c $(main_src)programFpgaBlackfin.c $(main_src)/sharedMemory.c
|
||||
SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)AD9257.c $(main_src)ALTERA_PLL.c $(main_src)LTC2620.c $(main_src)MAX1932.c $(main_src)programFpgaBlackfin.c $(main_src)/sharedMemory.c $(md5_dir)md5.c
|
||||
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
|
||||
@ -34,10 +35,10 @@ $(PROGS): $(OBJS)
|
||||
mv $(PROGS) $(DESTDIR)
|
||||
cp config_jungfrau.txt $(DESTDIR)
|
||||
rm *.gdb
|
||||
rm $(main_src)*.o
|
||||
rm $(main_src)*.o $(md5_dir)*.o
|
||||
|
||||
clean:
|
||||
rm -rf $(DESTDIR)/$(PROGS) *.o *.gdb $(main_src)*.o
|
||||
rm -rf $(DESTDIR)/$(PROGS) *.o *.gdb $(main_src)*.o $(md5_dir)*.o
|
||||
|
||||
|
||||
|
@ -343,6 +343,8 @@
|
||||
#define DAQ_FIX_GAIN_STG_2_VAL ((0x3 << DAQ_FIX_GAIN_OFST) & DAQ_FIX_GAIN_MSK)
|
||||
#define DAQ_CMP_RST_OFST (4)
|
||||
#define DAQ_CMP_RST_MSK (0x00000001 << DAQ_CMP_RST_OFST)
|
||||
#define DAQ_CHIP11_VRSN_OFST (7)
|
||||
#define DAQ_CHIP11_VRSN_MSK (0x00000001 << DAQ_CHIP11_VRSN_OFST)
|
||||
#define DAQ_STRG_CELL_SLCT_OFST (8)
|
||||
#define DAQ_STRG_CELL_SLCT_MSK (0x0000000F << DAQ_STRG_CELL_SLCT_OFST)
|
||||
#define DAQ_FRCE_SWTCH_GAIN_OFST (12)
|
||||
|
Binary file not shown.
@ -49,7 +49,6 @@ int defaultDacValue_G0[] = SPECIAL_DEFAULT_DYNAMIC_GAIN_VALS;
|
||||
int defaultDacValue_HG0[] = SPECIAL_DEFAULT_DYNAMICHG0_GAIN_VALS;
|
||||
int32_t clkPhase[NUM_CLOCKS] = {};
|
||||
int detPos[4] = {};
|
||||
int chipVersion = 10; // (1.0)
|
||||
int chipConfigured = 0;
|
||||
|
||||
int isInitCheckDone() { return initCheckDone; }
|
||||
@ -299,7 +298,24 @@ int isHardwareVersion2() {
|
||||
: 0);
|
||||
}
|
||||
|
||||
int getChipVersion() { return chipVersion; }
|
||||
int getChipVersion() {
|
||||
// chip v1.1
|
||||
if (bus_r(DAQ_REG | DAQ_CHIP11_VRSN_MSK)) {
|
||||
return 11;
|
||||
}
|
||||
// chip v1.0
|
||||
return 10;
|
||||
}
|
||||
|
||||
void setChipVersion(int version) {
|
||||
LOG(logINFO,
|
||||
("Setting chip version to %0.1f in FPGA\n", (double)version / 10.0));
|
||||
if (version == 11) {
|
||||
bus_w(DAQ_REG, bus_r(DAQ_REG) | DAQ_CHIP11_VRSN_MSK);
|
||||
} else {
|
||||
bus_w(DAQ_REG, bus_r(DAQ_REG) & ~DAQ_CHIP11_VRSN_MSK);
|
||||
}
|
||||
}
|
||||
|
||||
u_int32_t getDetectorNumber() {
|
||||
#ifdef VIRTUAL
|
||||
@ -397,11 +413,6 @@ void setupDetector() {
|
||||
setupUDPCommParameters();
|
||||
#endif
|
||||
|
||||
// get chip version
|
||||
if (readConfigFile() == FAIL) {
|
||||
return;
|
||||
}
|
||||
|
||||
ALTERA_PLL_ResetPLL();
|
||||
resetCore();
|
||||
resetPeripheral();
|
||||
@ -436,9 +447,16 @@ void setupDetector() {
|
||||
PLL_CNTRL_WR_PRMTR_MSK, PLL_CNTRL_PLL_RST_MSK, PLL_CNTRL_ADDR_MSK,
|
||||
PLL_CNTRL_ADDR_OFST, PLL_CNTRL_DBIT_WR_PRMTR_MSK, DBIT_CLK_INDEX);
|
||||
|
||||
bus_w(DAQ_REG, 0x0); /* Only once at server startup */
|
||||
/* Only once at server startup */
|
||||
bus_w(DAQ_REG, 0x0);
|
||||
|
||||
LOG(logINFOBLUE, ("Setting Default parameters\n"));
|
||||
|
||||
// get chip version
|
||||
if (readConfigFile() == FAIL) {
|
||||
return;
|
||||
}
|
||||
|
||||
setClockDivider(RUN_CLK, HALF_SPEED);
|
||||
cleanFifos();
|
||||
resetCore();
|
||||
@ -713,17 +731,14 @@ int readConfigFile() {
|
||||
version, line);
|
||||
break;
|
||||
}
|
||||
|
||||
// validations
|
||||
chipVersion = version;
|
||||
LOG(logINFOBLUE, ("Chip Version: v%.01f\n", chipVersion / 10.0));
|
||||
|
||||
// version 1.1 and HW 1.0 (version reg value = 2) is incompatible
|
||||
if (chipVersion == 11 && isHardwareVersion2()) {
|
||||
if (version == 11 && isHardwareVersion2()) {
|
||||
strcpy(initErrorMessage,
|
||||
"Chip version 1.1 (from on-board config file) is incompatible with old board (v1.0). Please update board or correct on-board config file.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
setChipVersion(version);
|
||||
}
|
||||
|
||||
memset(line, 0, LZ);
|
||||
@ -1735,11 +1750,13 @@ int isChipConfigured() {
|
||||
|
||||
void configureChip() {
|
||||
// only for chipv1.1
|
||||
if (chipVersion == 11) {
|
||||
if (getChipVersion() == 11) {
|
||||
LOG(logINFOBLUE, ("Configuring chip\n"));
|
||||
// write same register values back to configure chip
|
||||
uint32_t val = bus_r(CONFIG_V11_REG);
|
||||
bus_w(CONFIG_V11_REG, val);
|
||||
bus_w(CONFIG_V11_REG, bus_r(CONFIG_V11_REG));
|
||||
// default values for current source
|
||||
bus_w(CRRNT_SRC_COL_LSB_REG, BIT32_MASK);
|
||||
bus_w(CRRNT_SRC_COL_MSB_REG, BIT32_MASK);
|
||||
chipConfigured = 1;
|
||||
}
|
||||
}
|
||||
@ -1821,7 +1838,11 @@ int setClockDivider(enum CLKINDEX ind, int val) {
|
||||
}
|
||||
LOG(logINFO, ("Setting Full Speed (40 MHz):\n"));
|
||||
adcOfst = ADC_OFST_FULL_SPEED_VAL;
|
||||
if (getChipVersion() == 10) {
|
||||
sampleAdcSpeed = SAMPLE_ADC_FULL_SPEED_CHIP10;
|
||||
} else {
|
||||
sampleAdcSpeed = SAMPLE_ADC_FULL_SPEED;
|
||||
}
|
||||
adcPhase = ADC_PHASE_FULL_SPEED;
|
||||
dbitPhase = DBIT_PHASE_FULL_SPEED;
|
||||
config = CONFIG_FULL_SPEED_40MHZ_VAL;
|
||||
@ -1829,27 +1850,43 @@ int setClockDivider(enum CLKINDEX ind, int val) {
|
||||
|
||||
case HALF_SPEED:
|
||||
LOG(logINFO, ("Setting Half Speed (20 MHz):\n"));
|
||||
adcOfst = isHardwareVersion2() ? ADC_OFST_HALF_SPEED_BOARD2_VAL
|
||||
: ADC_OFST_HALF_SPEED_VAL;
|
||||
sampleAdcSpeed = isHardwareVersion2() ? SAMPLE_ADC_HALF_SPEED_BOARD2
|
||||
: SAMPLE_ADC_HALF_SPEED;
|
||||
adcPhase = isHardwareVersion2() ? ADC_PHASE_HALF_SPEED_BOARD2
|
||||
: ADC_PHASE_HALF_SPEED;
|
||||
dbitPhase = isHardwareVersion2() ? DBIT_PHASE_HALF_SPEED_BOARD2
|
||||
: DBIT_PHASE_HALF_SPEED;
|
||||
if (isHardwareVersion2()) {
|
||||
adcOfst = ADC_OFST_HALF_SPEED_BOARD2_VAL;
|
||||
sampleAdcSpeed = SAMPLE_ADC_HALF_SPEED_BOARD2;
|
||||
adcPhase = ADC_PHASE_HALF_SPEED_BOARD2;
|
||||
dbitPhase = DBIT_PHASE_HALF_SPEED_BOARD2;
|
||||
} else if (getChipVersion() == 10) {
|
||||
adcOfst = ADC_OFST_HALF_SPEED_VAL;
|
||||
sampleAdcSpeed = SAMPLE_ADC_HALF_SPEED_CHIP10;
|
||||
adcPhase = ADC_PHASE_HALF_SPEED;
|
||||
dbitPhase = DBIT_PHASE_HALF_SPEED;
|
||||
} else {
|
||||
adcOfst = ADC_OFST_HALF_SPEED_VAL;
|
||||
sampleAdcSpeed = SAMPLE_ADC_HALF_SPEED;
|
||||
adcPhase = ADC_PHASE_HALF_SPEED;
|
||||
dbitPhase = DBIT_PHASE_HALF_SPEED;
|
||||
}
|
||||
config = CONFIG_HALF_SPEED_20MHZ_VAL;
|
||||
break;
|
||||
|
||||
case QUARTER_SPEED:
|
||||
LOG(logINFO, ("Setting Half Speed (10 MHz):\n"));
|
||||
adcOfst = isHardwareVersion2() ? ADC_OFST_QUARTER_SPEED_BOARD2_VAL
|
||||
: ADC_OFST_QUARTER_SPEED_VAL;
|
||||
sampleAdcSpeed = isHardwareVersion2() ? SAMPLE_ADC_QUARTER_SPEED_BOARD2
|
||||
: SAMPLE_ADC_QUARTER_SPEED;
|
||||
adcPhase = isHardwareVersion2() ? ADC_PHASE_QUARTER_SPEED_BOARD2
|
||||
: ADC_PHASE_QUARTER_SPEED;
|
||||
dbitPhase = isHardwareVersion2() ? DBIT_PHASE_QUARTER_SPEED_BOARD2
|
||||
: DBIT_PHASE_QUARTER_SPEED;
|
||||
if (isHardwareVersion2()) {
|
||||
adcOfst = ADC_OFST_QUARTER_SPEED_BOARD2_VAL;
|
||||
sampleAdcSpeed = SAMPLE_ADC_QUARTER_SPEED_BOARD2;
|
||||
adcPhase = ADC_PHASE_QUARTER_SPEED_BOARD2;
|
||||
dbitPhase = DBIT_PHASE_QUARTER_SPEED_BOARD2;
|
||||
} else if (getChipVersion() == 10) {
|
||||
adcOfst = ADC_OFST_QUARTER_SPEED_VAL;
|
||||
sampleAdcSpeed = SAMPLE_ADC_QUARTER_SPEED_CHIP10;
|
||||
adcPhase = ADC_PHASE_QUARTER_SPEED;
|
||||
dbitPhase = DBIT_PHASE_QUARTER_SPEED;
|
||||
} else {
|
||||
adcOfst = ADC_OFST_QUARTER_SPEED_VAL;
|
||||
sampleAdcSpeed = SAMPLE_ADC_QUARTER_SPEED;
|
||||
adcPhase = ADC_PHASE_QUARTER_SPEED;
|
||||
dbitPhase = DBIT_PHASE_QUARTER_SPEED;
|
||||
}
|
||||
config = CONFIG_QUARTER_SPEED_10MHZ_VAL;
|
||||
break;
|
||||
|
||||
@ -2170,7 +2207,7 @@ void disableCurrentSource() {
|
||||
}
|
||||
|
||||
void enableCurrentSource(int fix, uint64_t select, int normal) {
|
||||
if (chipVersion == 11) {
|
||||
if (getChipVersion() == 11) {
|
||||
LOG(logINFO, ("Enabling current source [fix:%d, select:%lld]\n", fix,
|
||||
(long long int)select));
|
||||
} else {
|
||||
@ -2186,7 +2223,7 @@ void enableCurrentSource(int fix, uint64_t select, int normal) {
|
||||
} else {
|
||||
bus_w(DAQ_REG, bus_r(DAQ_REG) & ~DAQ_CRRNT_SRC_CLMN_FIX_MSK);
|
||||
}
|
||||
if (chipVersion == 10) {
|
||||
if (getChipVersion() == 10) {
|
||||
// select
|
||||
bus_w(DAQ_REG, bus_r(DAQ_REG) & ~DAQ_CRRNT_SRC_CLMN_SLCT_MSK);
|
||||
bus_w(DAQ_REG,
|
||||
@ -2240,7 +2277,7 @@ int getNormalCurrentSource() {
|
||||
}
|
||||
|
||||
uint64_t getSelectCurrentSource() {
|
||||
if (chipVersion == 10) {
|
||||
if (getChipVersion() == 10) {
|
||||
return ((bus_r(DAQ_REG) & DAQ_CRRNT_SRC_CLMN_SLCT_MSK) >>
|
||||
DAQ_CRRNT_SRC_CLMN_SLCT_OFST);
|
||||
} else {
|
||||
|
@ -3,8 +3,8 @@
|
||||
#include "sls/sls_detector_defs.h"
|
||||
|
||||
#define MIN_REQRD_VRSN_T_RD_API 0x171220
|
||||
#define REQRD_FRMWRE_VRSN_BOARD2 0x210621 // 1.0 pcb (version = 010)
|
||||
#define REQRD_FRMWRE_VRSN 0x210622 // 2.0 pcb (version = 011)
|
||||
#define REQRD_FRMWRE_VRSN_BOARD2 0x210831 // 1.0 pcb (version = 010)
|
||||
#define REQRD_FRMWRE_VRSN 0x210910 // 2.0 pcb (version = 011)
|
||||
|
||||
#define CTRL_SRVR_INIT_TIME_US (300 * 1000)
|
||||
|
||||
@ -67,9 +67,9 @@ enum DACINDEX {
|
||||
#define NSPECIALDACS (3)
|
||||
#define SPECIALDACINDEX {J_VREF_PRECH, J_VREF_DS, J_VREF_COMP};
|
||||
#define SPECIAL_DEFAULT_DYNAMIC_GAIN_VALS \
|
||||
{ 1000, 500, 400 }
|
||||
{ 1450, 480, 420 }
|
||||
#define SPECIAL_DEFAULT_DYNAMICHG0_GAIN_VALS \
|
||||
{ 1500, 550, 450 }
|
||||
{ 1450, 480, 420 }
|
||||
|
||||
enum NETWORKINDEX { TXN_FRAME, FLOWCTRL_10G };
|
||||
enum CLKINDEX { RUN_CLK, ADC_CLK, DBIT_CLK, NUM_CLOCKS };
|
||||
@ -141,16 +141,28 @@ enum CLKINDEX { RUN_CLK, ADC_CLK, DBIT_CLK, NUM_CLOCKS };
|
||||
#define ADC_PORT_INVERT_VAL (0x5A5A5A5A)
|
||||
#define ADC_PORT_INVERT_BOARD2_VAL (0x453b2a9c)
|
||||
|
||||
// 2.0 pcb
|
||||
// 2.0 pcb (chipv1.1)
|
||||
#define SAMPLE_ADC_FULL_SPEED \
|
||||
(SAMPLE_ADC_SAMPLE_0_VAL + SAMPLE_ADC_DECMT_FACTOR_0_VAL + \
|
||||
SAMPLE_DGTL_SAMPLE_1_VAL + SAMPLE_DECMT_FACTOR_FULL_VAL) // 0x100
|
||||
SAMPLE_DGTL_SAMPLE_0_VAL + SAMPLE_DECMT_FACTOR_FULL_VAL) // 0x0000
|
||||
#define SAMPLE_ADC_HALF_SPEED \
|
||||
(SAMPLE_ADC_SAMPLE_0_VAL + SAMPLE_ADC_DECMT_FACTOR_1_VAL + \
|
||||
SAMPLE_DGTL_SAMPLE_3_VAL + SAMPLE_DECMT_FACTOR_HALF_VAL) // 0x1310
|
||||
SAMPLE_DGTL_SAMPLE_1_VAL + SAMPLE_DECMT_FACTOR_HALF_VAL) // 0x1110
|
||||
#define SAMPLE_ADC_QUARTER_SPEED \
|
||||
(SAMPLE_ADC_SAMPLE_0_VAL + SAMPLE_ADC_DECMT_FACTOR_3_VAL + \
|
||||
SAMPLE_DGTL_SAMPLE_2_VAL + SAMPLE_DECMT_FACTOR_QUARTER_VAL) // 0x2230
|
||||
|
||||
// 2.0 pcb (chipv1.0)
|
||||
#define SAMPLE_ADC_FULL_SPEED_CHIP10 \
|
||||
(SAMPLE_ADC_SAMPLE_0_VAL + SAMPLE_ADC_DECMT_FACTOR_0_VAL + \
|
||||
SAMPLE_DGTL_SAMPLE_1_VAL + SAMPLE_DECMT_FACTOR_FULL_VAL) // 0x0100
|
||||
#define SAMPLE_ADC_HALF_SPEED_CHIP10 \
|
||||
(SAMPLE_ADC_SAMPLE_0_VAL + SAMPLE_ADC_DECMT_FACTOR_1_VAL + \
|
||||
SAMPLE_DGTL_SAMPLE_3_VAL + SAMPLE_DECMT_FACTOR_HALF_VAL) // 0x1310
|
||||
#define SAMPLE_ADC_QUARTER_SPEED_CHIP10 \
|
||||
(SAMPLE_ADC_SAMPLE_0_VAL + SAMPLE_ADC_DECMT_FACTOR_3_VAL + \
|
||||
SAMPLE_DGTL_SAMPLE_6_VAL + SAMPLE_DECMT_FACTOR_QUARTER_VAL) // 0x2630
|
||||
|
||||
// 1.0 pcb (2 resistor network)
|
||||
#define SAMPLE_ADC_HALF_SPEED_BOARD2 \
|
||||
(SAMPLE_ADC_SAMPLE_0_VAL + SAMPLE_ADC_DECMT_FACTOR_0_VAL + \
|
||||
@ -159,13 +171,13 @@ enum CLKINDEX { RUN_CLK, ADC_CLK, DBIT_CLK, NUM_CLOCKS };
|
||||
(SAMPLE_ADC_SAMPLE_0_VAL + SAMPLE_ADC_DECMT_FACTOR_1_VAL + \
|
||||
SAMPLE_DGTL_SAMPLE_6_VAL + SAMPLE_DECMT_FACTOR_QUARTER_VAL) // 0x2610
|
||||
|
||||
#define ADC_PHASE_FULL_SPEED (150) // 2.0 pcb
|
||||
#define ADC_PHASE_HALF_SPEED (200) // 2.0 pcb
|
||||
#define ADC_PHASE_QUARTER_SPEED (200) // 2.0 pcb
|
||||
#define ADC_PHASE_FULL_SPEED (175) // 2.0 pcb
|
||||
#define ADC_PHASE_HALF_SPEED (175) // 2.0 pcb
|
||||
#define ADC_PHASE_QUARTER_SPEED (175) // 2.0 pcb
|
||||
#define ADC_PHASE_HALF_SPEED_BOARD2 (110) // 1.0 pcb (2 resistor network)
|
||||
#define ADC_PHASE_QUARTER_SPEED_BOARD2 (220) // 1.0 pcb (2 resistor network)
|
||||
|
||||
#define DBIT_PHASE_FULL_SPEED (85) // 2.0 pcb
|
||||
#define DBIT_PHASE_FULL_SPEED (100) // 2.0 pcb
|
||||
#define DBIT_PHASE_HALF_SPEED (150) // 2.0 pcb
|
||||
#define DBIT_PHASE_QUARTER_SPEED (150) // 2.0 pcb
|
||||
#define DBIT_PHASE_HALF_SPEED_BOARD2 (150) // 1.0 pcb (2 resistor network)
|
||||
|
@ -15,6 +15,7 @@ add_executable(moenchDetectorServer_virtual
|
||||
../slsDetectorServer/src/programFpgaBlackfin.c
|
||||
../slsDetectorServer/src/loadPattern.c
|
||||
../slsDetectorServer/src/sharedMemory.c
|
||||
../../slsSupportLib/src/md5.c
|
||||
)
|
||||
|
||||
include_directories(
|
||||
|
@ -3,6 +3,7 @@ main_inc = ../slsDetectorServer/include/
|
||||
main_src = ../slsDetectorServer/src/
|
||||
support_lib = ../../slsSupportLib/include/
|
||||
det_lib = ../../slsDetectorSoftware/include/sls/
|
||||
md5_dir = ../../slsSupportLib/src/
|
||||
|
||||
CROSS = bfin-uclinux-
|
||||
CC = $(CROSS)gcc
|
||||
@ -13,7 +14,7 @@ DESTDIR ?= bin
|
||||
INSTMODE = 0777
|
||||
|
||||
SRCS = slsDetectorFunctionList.c
|
||||
SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)communication_funcs_UDP.c $(main_src)UDPPacketHeaderGenerator.c $(main_src)AD9257.c $(main_src)ALTERA_PLL.c $(main_src)LTC2620.c $(main_src)MAX1932.c $(main_src)programFpgaBlackfin.c $(main_src)loadPattern.c $(main_src)/sharedMemory.c
|
||||
SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)communication_funcs_UDP.c $(main_src)UDPPacketHeaderGenerator.c $(main_src)AD9257.c $(main_src)ALTERA_PLL.c $(main_src)LTC2620.c $(main_src)MAX1932.c $(main_src)programFpgaBlackfin.c $(main_src)loadPattern.c $(main_src)/sharedMemory.c $(md5_dir)md5.c
|
||||
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
|
||||
@ -36,10 +37,10 @@ $(PROGS): $(OBJS)
|
||||
cp DefaultPattern_moench.txt $(DESTDIR)
|
||||
rm *.gdb
|
||||
rm $(main_src)*.o
|
||||
rm *.o
|
||||
rm *.o $(md5_dir)*.o
|
||||
|
||||
clean:
|
||||
rm -rf $(DESTDIR)/$(PROGS) *.o *.gdb $(main_src)*.o
|
||||
rm -rf $(DESTDIR)/$(PROGS) *.o *.gdb $(main_src)*.o $(md5_dir)*.o
|
||||
|
||||
|
||||
|
Binary file not shown.
@ -13,6 +13,7 @@ add_executable(mythen3DetectorServer_virtual
|
||||
../slsDetectorServer/src/programFpgaNios.c
|
||||
../slsDetectorServer/src/loadPattern.c
|
||||
../slsDetectorServer/src/sharedMemory.c
|
||||
../../slsSupportLib/src/md5.c
|
||||
)
|
||||
|
||||
include_directories(
|
||||
|
@ -3,6 +3,7 @@ main_inc = ../slsDetectorServer/include/
|
||||
main_src = ../slsDetectorServer/src/
|
||||
support_lib = ../../slsSupportLib/include/
|
||||
det_lib = ../../slsDetectorSoftware/include/sls/
|
||||
md5_dir = ../../slsSupportLib/src/
|
||||
|
||||
CROSS = nios2-buildroot-linux-gnu-
|
||||
CC = $(CROSS)gcc
|
||||
@ -13,7 +14,7 @@ DESTDIR ?= bin
|
||||
INSTMODE = 0777
|
||||
|
||||
SRCS = slsDetectorFunctionList.c
|
||||
SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)nios.c $(main_src)DAC6571.c $(main_src)common.c $(main_src)LTC2620_Driver.c $(main_src)ALTERA_PLL_CYCLONE10.c $(main_src)/programFpgaNios.c $(main_src)/sharedMemory.c $(main_src)/loadPattern.c mythen3.c
|
||||
SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)nios.c $(main_src)DAC6571.c $(main_src)common.c $(main_src)LTC2620_Driver.c $(main_src)ALTERA_PLL_CYCLONE10.c $(main_src)/programFpgaNios.c $(main_src)/sharedMemory.c $(main_src)/loadPattern.c mythen3.c $(md5_dir)md5.c
|
||||
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
|
||||
@ -35,10 +36,10 @@ $(PROGS): $(OBJS)
|
||||
mv $(PROGS) $(DESTDIR)
|
||||
cp DefaultPattern_mythen3.txt $(DESTDIR)
|
||||
cp detid_mythen3.txt $(DESTDIR)
|
||||
rm $(main_src)*.o
|
||||
rm $(main_src)*.o $(md5_dir)*.o
|
||||
|
||||
clean:
|
||||
rm -rf $(DESTDIR)/$(PROGS) *.o *.gdb $(main_src)*.o
|
||||
rm -rf $(DESTDIR)/$(PROGS) *.o *.gdb $(main_src)*.o $(md5_dir)*.o
|
||||
|
||||
|
||||
|
||||
|
@ -113,6 +113,12 @@
|
||||
#define SYSTEM_STATUS_SLV_BRD_DTCT_MSK (0x00000001 << SYSTEM_STATUS_SLV_BRD_DTCT_OFST)
|
||||
|
||||
|
||||
#define MOD_ID_REG (0x0B * REG_OFFSET + BASE_CONTROL)
|
||||
|
||||
#define MOD_ID_OFST (0)
|
||||
#define MOD_ID_MSK (0x0000FFFF << MOD_ID_OFST)
|
||||
|
||||
|
||||
/* Config RW regiseter */
|
||||
#define CONFIG_REG (0x20 * REG_OFFSET + BASE_CONTROL)
|
||||
|
||||
|
Binary file not shown.
@ -283,7 +283,14 @@ u_int32_t getDetectorNumber() {
|
||||
|
||||
|
||||
int getModuleId(int *ret, char *mess) {
|
||||
return getModuleIdInFile(ret, mess, ID_FILE);
|
||||
return ((bus_r(MOD_ID_REG) & ~MOD_ID_MSK) >> MOD_ID_OFST);
|
||||
}
|
||||
|
||||
void setModuleId(int modid) {
|
||||
LOG(logINFOBLUE, ("Setting module id in fpga: %d\n", modid))
|
||||
bus_w(MOD_ID_REG, bus_r(MOD_ID_REG) & ~MOD_ID_MSK);
|
||||
bus_w(MOD_ID_REG,
|
||||
bus_r(MOD_ID_REG) | ((modid << MOD_ID_OFST) & MOD_ID_MSK));
|
||||
}
|
||||
|
||||
u_int64_t getDetectorMAC() {
|
||||
@ -445,12 +452,11 @@ void setupDetector() {
|
||||
setADIFDefaults();
|
||||
|
||||
// set module id in register
|
||||
getModuleIdInFile(&initError, initErrorMessage, ID_FILE);
|
||||
int modid = getModuleIdInFile(&initError, initErrorMessage, ID_FILE);
|
||||
if (initError == FAIL) {
|
||||
return;
|
||||
}
|
||||
// until firmware is done
|
||||
// setModuleId(modid);
|
||||
setModuleId(modid);
|
||||
|
||||
// set trigger flow for m3 (for all timing modes)
|
||||
bus_w(FLOW_TRIGGER_REG, bus_r(FLOW_TRIGGER_REG) | FLOW_TRIGGER_MSK);
|
||||
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#include "sls/sls_detector_defs.h"
|
||||
|
||||
#define REQRD_FRMWRE_VRSN (0x210201)
|
||||
#define REQRD_FRMWRE_VRSN (0x210910)
|
||||
#define KERNEL_DATE_VRSN "Wed May 20 13:58:38 CEST 2020"
|
||||
#define ID_FILE "detid_mythen3.txt"
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "sls/md5.h"
|
||||
#include <stdint.h> // int64_t
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
|
||||
enum numberMode { DEC, HEX };
|
||||
@ -31,3 +33,9 @@ void validate64(int *ret, char *mess, int64_t arg, int64_t retval,
|
||||
|
||||
int getModuleIdInFile(int *ret, char *mess, char *fileName);
|
||||
int setModuleIdInFile(char *mess, int arg, char *fileName);
|
||||
int verifyChecksumFromBuffer(char *mess, char *clientChecksum, char *buffer,
|
||||
ssize_t bytes);
|
||||
int verifyChecksumFromFile(char *mess, char *clientChecksum, char *fname);
|
||||
int verifyChecksumFromFlash(char *mess, char *clientChecksum, char *fname,
|
||||
ssize_t fsize);
|
||||
int verifyChecksum(char *mess, char *clientChecksum, MD5_CTX *c, char *msg);
|
@ -2,54 +2,29 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#define TEMP_PROG_FILE_NAME "/var/tmp/tmp.rawbin"
|
||||
|
||||
/**
|
||||
* Define GPIO pins if not defined
|
||||
*/
|
||||
void defineGPIOpins();
|
||||
|
||||
/**
|
||||
* Notify FPGA to not touch flash
|
||||
*/
|
||||
void FPGAdontTouchFlash();
|
||||
|
||||
/**
|
||||
* Notify FPGA to program from flash
|
||||
*/
|
||||
void FPGATouchFlash();
|
||||
|
||||
/**
|
||||
* Reset FPGA
|
||||
*/
|
||||
void resetFPGA();
|
||||
|
||||
int deleteOldFile(char *mess);
|
||||
/**
|
||||
* Erasing flash
|
||||
* deletes old file
|
||||
* verify memory available to copy
|
||||
* open file to copy
|
||||
*/
|
||||
void eraseFlash();
|
||||
|
||||
/**
|
||||
* Open the drive to copy program and
|
||||
* notify FPGA not to touch the program
|
||||
* @param filefp pointer to flash
|
||||
* @return 0 for success, 1 for fail (cannot open file for writing program)
|
||||
int preparetoCopyFPGAProgram(FILE **fd, uint64_t fsize, char *mess);
|
||||
int copyToFlash(ssize_t fsize, char *clientChecksum, char *mess);
|
||||
int getDrive(char *mess);
|
||||
/** Notify fpga not to touch flash, open src and flash drive to write */
|
||||
int openFileForFlash(FILE **flashfd, FILE **srcfd, char *mess);
|
||||
int eraseFlash(char *mess);
|
||||
/* write from tmp file to flash */
|
||||
int writeToFlash(ssize_t fsize, FILE *flashfd, FILE *srcfd, char *mess);
|
||||
/** Notify fpga to pick up firmware from flash and wait for status confirmation
|
||||
*/
|
||||
int startWritingFPGAprogram(FILE **filefp);
|
||||
|
||||
/**
|
||||
* When done writing the program, close file pointer and
|
||||
* notify FPGA to pick up the program from flash
|
||||
* @param filefp pointer to flash
|
||||
* @return 0 for success, 1 for fail (time taken for fpga to touch flash
|
||||
* exceeded)
|
||||
*/
|
||||
int stopWritingFPGAprogram(FILE *filefp);
|
||||
|
||||
/**
|
||||
* Write FPGA Program to flash
|
||||
* @param fpgasrc source program
|
||||
* @param fsize size of program
|
||||
* @param filefp pointer to flash
|
||||
* @return 0 for success, 1 for fail (cannot write)
|
||||
*/
|
||||
int writeFPGAProgram(char *fpgasrc, uint64_t fsize, FILE *filefp);
|
||||
int waitForFPGAtoTouchFlash(char *mess);
|
||||
|
@ -11,29 +11,8 @@ void NotifyServerStartSuccess();
|
||||
/** reset fpga and controller(only implemented for >= v1.1 boards) */
|
||||
void rebootControllerAndFPGA();
|
||||
|
||||
/** finds the right mtd drive
|
||||
* @param mess error message
|
||||
* @returns ok or fail
|
||||
*/
|
||||
int findFlash(char *mess);
|
||||
|
||||
/** erase flash */
|
||||
void eraseFlash();
|
||||
|
||||
/** erase and write flash
|
||||
* @param mess error message
|
||||
* @param fpgasrc program source
|
||||
* @param fsize file size
|
||||
* @returns ok or fail
|
||||
*/
|
||||
int eraseAndWriteToFlash(char *mess, char *fpgasrc, uint64_t fsize);
|
||||
|
||||
/**
|
||||
* Write FPGA Program to flash
|
||||
* @param mess error message
|
||||
* @param fpgasrc source program
|
||||
* @param fsize size of program
|
||||
* @param filefp pointer to flash
|
||||
* @return ok or fail
|
||||
*/
|
||||
int writeFPGAProgram(char *mess, char *fpgasrc, uint64_t fsize, FILE *filefp);
|
||||
int eraseAndWriteToFlash(char *mess, char *checksum, char *fpgasrc, uint64_t fsize);
|
||||
int getDrive(char *mess);
|
||||
int openFileForFlash(FILE **flashfd, char *mess);
|
||||
int eraseFlash(char *mess);
|
||||
int writeToFlash(ssize_t fsize, FILE *flashfd, char *buffer, char *mess);
|
@ -89,6 +89,7 @@ u_int16_t getHardwareSerialNumber();
|
||||
#ifdef JUNGFRAUD
|
||||
int isHardwareVersion2();
|
||||
int getChipVersion();
|
||||
void setChipVersion(int version);
|
||||
#endif
|
||||
#ifndef EIGERD
|
||||
u_int32_t getDetectorNumber();
|
||||
@ -96,7 +97,7 @@ u_int32_t getDetectorNumber();
|
||||
#if defined(GOTTHARD2D) || defined(EIGERD) || defined(MYTHEN3D)
|
||||
int getModuleId(int *ret, char *mess);
|
||||
#endif
|
||||
#ifdef GOTTHARD2D
|
||||
#if defined(GOTTHARD2D) || defined(MYTHEN3D)
|
||||
void setModuleId(int modid);
|
||||
#endif
|
||||
u_int64_t getDetectorMAC();
|
||||
@ -127,8 +128,10 @@ int resetToDefaultDacs(int hardReset);
|
||||
int getDefaultDac(enum DACINDEX index, enum detectorSettings sett, int *retval);
|
||||
int setDefaultDac(enum DACINDEX index, enum detectorSettings sett, int value);
|
||||
#endif
|
||||
#ifdef MYTHEN3D
|
||||
#if defined(MYTHEN3D) || defined(GOTTHARD2D)
|
||||
void setASICDefaults();
|
||||
#endif
|
||||
#ifdef MYTHEN3D
|
||||
void setADIFDefaults();
|
||||
#endif
|
||||
#if defined(GOTTHARD2D) || defined(EIGERD) || defined(JUNGFRAUD)
|
||||
|
@ -271,6 +271,6 @@ int get_module_id(int);
|
||||
int get_dest_udp_list(int);
|
||||
int set_dest_udp_list(int);
|
||||
int get_num_dest_list(int);
|
||||
int set_num_dest_list(int);
|
||||
int clear_all_udp_dst(int);
|
||||
int get_udp_first_dest(int);
|
||||
int set_udp_first_dest(int);
|
@ -7,6 +7,7 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h> // readlink
|
||||
|
||||
|
||||
int ConvertToDifferentRange(int inputMin, int inputMax, int outputMin,
|
||||
int outputMax, int inputValue, int *outputValue) {
|
||||
LOG(logDEBUG1, (" Input Value: %d (Input:(%d - %d), Output:(%d - %d))\n",
|
||||
@ -178,3 +179,147 @@ int setModuleIdInFile(char *mess, int arg, char *fileName) {
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int verifyChecksumFromBuffer(char *mess, char *clientChecksum, char *buffer,
|
||||
ssize_t bytes) {
|
||||
LOG(logINFO, ("\tVerifying Checksum...\n"));
|
||||
MD5_CTX c;
|
||||
if (!MD5_Init_SLS(&c)) {
|
||||
strcpy(mess, "Unable to calculate checksum (MD5_Init_SLS)\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
if (!MD5_Update_SLS(&c, buffer, bytes)) {
|
||||
strcpy(mess, "Unable to calculate checksum (MD5_Update_SLS)\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
return verifyChecksum(mess, clientChecksum, &c, "copied program");
|
||||
}
|
||||
|
||||
int verifyChecksumFromFile(char *mess, char *clientChecksum, char *fname) {
|
||||
LOG(logINFO, ("\tVerifying Checksum...\n"));
|
||||
|
||||
FILE *fp = fopen(fname, "r");
|
||||
if (fp == NULL) {
|
||||
sprintf(mess, "Unable to open %s in read mode to get checksum\n",
|
||||
fname);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
MD5_CTX c;
|
||||
if (!MD5_Init_SLS(&c)) {
|
||||
fclose(fp);
|
||||
strcpy(mess, "Unable to calculate checksum (MD5_Init_SLS)\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
const int readUnitSize = 128;
|
||||
char buf[readUnitSize];
|
||||
ssize_t bytes = fread(buf, 1, readUnitSize, fp);
|
||||
ssize_t totalBytesRead = bytes;
|
||||
while (bytes > 0) {
|
||||
if (!MD5_Update_SLS(&c, buf, bytes)) {
|
||||
fclose(fp);
|
||||
strcpy(mess, "Unable to calculate checksum (MD5_Update_SLS)\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
bytes = fread(buf, 1, readUnitSize, fp);
|
||||
totalBytesRead += bytes;
|
||||
}
|
||||
LOG(logINFO, ("\tRead %lu bytes to calculate checksum\n", totalBytesRead));
|
||||
fclose(fp);
|
||||
return verifyChecksum(mess, clientChecksum, &c, "copied program");
|
||||
}
|
||||
|
||||
int verifyChecksumFromFlash(char *mess, char *clientChecksum, char *fname,
|
||||
ssize_t fsize) {
|
||||
LOG(logINFO, ("\tVerifying FlashChecksum...\n"));
|
||||
|
||||
FILE *fp = fopen(fname, "r");
|
||||
if (fp == NULL) {
|
||||
sprintf(mess, "Unable to open %s in read mode to get checksum\n",
|
||||
fname);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
MD5_CTX c;
|
||||
if (!MD5_Init_SLS(&c)) {
|
||||
fclose(fp);
|
||||
strcpy(mess, "Unable to calculate checksum (MD5_Init_SLS)\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
const int readUnitSize = 128;
|
||||
char buf[readUnitSize];
|
||||
ssize_t bytes = fread(buf, 1, readUnitSize, fp);
|
||||
ssize_t totalBytesRead = bytes;
|
||||
int oldProgress = 0;
|
||||
|
||||
while (bytes > 0) {
|
||||
int progress = (int)(((double)(totalBytesRead) / fsize) * 100);
|
||||
if (oldProgress != progress) {
|
||||
printf("%d%%\r", progress);
|
||||
fflush(stdout);
|
||||
oldProgress = progress;
|
||||
}
|
||||
|
||||
if (!MD5_Update_SLS(&c, buf, bytes)) {
|
||||
fclose(fp);
|
||||
strcpy(mess, "Unable to calculate checksum (MD5_Update_SLS)\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// read only until a particular size (drive)
|
||||
if (fsize != 0 && totalBytesRead >= fsize) {
|
||||
LOG(logINFO, ("\tReached %lu bytes. Not reading more\n", totalBytesRead));
|
||||
break;
|
||||
}
|
||||
bytes = fread(buf, 1, readUnitSize, fp);
|
||||
totalBytesRead += bytes;
|
||||
}
|
||||
LOG(logINFO, ("\tRead %lu bytes to calculate checksum\n", totalBytesRead));
|
||||
fclose(fp);
|
||||
int ret = verifyChecksum(mess, clientChecksum, &c, "flash");
|
||||
if (ret == OK) {
|
||||
LOG(logINFO, ("Checksum in Flash verified\n"));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int verifyChecksum(char *mess, char *clientChecksum, MD5_CTX *c, char *msg) {
|
||||
unsigned char out[MD5_DIGEST_LENGTH];
|
||||
if (!MD5_Final_SLS(out, c)) {
|
||||
strcpy(mess, "Unable to calculate checksum (MD5_Final_SLS)\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
char checksum[512];
|
||||
memset(checksum, 0, 512);
|
||||
for (int i = 0; i != MD5_DIGEST_LENGTH; ++i) {
|
||||
char part[16];
|
||||
memset(part, 0, 16);
|
||||
sprintf(part, "%02x", out[i]);
|
||||
strcat(checksum, part);
|
||||
}
|
||||
|
||||
LOG(logDEBUG1,
|
||||
("\nC checksum: %s\nS checksum: %s\n", clientChecksum, checksum));
|
||||
|
||||
// compare checksum
|
||||
if (strcmp(clientChecksum, checksum)) {
|
||||
sprintf(mess,
|
||||
"Checksum of %s does not match. Client "
|
||||
"checksum:%s, copied checksum:%s\n",
|
||||
msg, clientChecksum, checksum);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tChecksum verified\n"));
|
||||
return OK;
|
||||
}
|
@ -1,19 +1,31 @@
|
||||
#include "programFpgaBlackfin.h"
|
||||
#include "clogger.h"
|
||||
#include "common.h"
|
||||
#include "sls/ansi.h"
|
||||
#include "slsDetectorServer_defs.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h> // usleep
|
||||
#include <sys/sysinfo.h>
|
||||
|
||||
/* global variables */
|
||||
#define MTDSIZE 10
|
||||
// clang-format off
|
||||
#define MAX_TIME_FPGA_TOUCH_FLASH_US (10 * 1000 * 1000) // 10s
|
||||
#define CMD_GET_FLASH "awk \'$4== \"\\\"bitfile(spi)\\\"\" {print $1}\' /proc/mtd"
|
||||
#define CMD_FPGA_PICKED_STATUS "cat /sys/class/gpio/gpio7/value"
|
||||
#define FLASH_BUFFER_MEMORY_SIZE (128 * 1024) // 500 KB
|
||||
// clang-format on
|
||||
|
||||
#define FLASH_DRIVE_NAME_SIZE 16
|
||||
char flashDriveName[FLASH_DRIVE_NAME_SIZE] = {0};
|
||||
int gpioDefined = 0;
|
||||
char mtdvalue[MTDSIZE] = {0};
|
||||
|
||||
extern int executeCommand(char *command, char *result, enum TLogLevel level);
|
||||
|
||||
void defineGPIOpins() {
|
||||
#ifdef VIRTUAL
|
||||
return;
|
||||
#endif
|
||||
if (!gpioDefined) {
|
||||
// define the gpio pins
|
||||
system("echo 7 > /sys/class/gpio/export");
|
||||
@ -28,35 +40,125 @@ void defineGPIOpins() {
|
||||
}
|
||||
|
||||
void FPGAdontTouchFlash() {
|
||||
#ifdef VIRTUAL
|
||||
return;
|
||||
#endif
|
||||
// tell FPGA to not touch flash
|
||||
system("echo 0 > /sys/class/gpio/gpio9/value");
|
||||
// usleep(100*1000);
|
||||
}
|
||||
|
||||
void FPGATouchFlash() {
|
||||
#ifdef VIRTUAL
|
||||
return;
|
||||
#endif
|
||||
// tell FPGA to touch flash to program itself
|
||||
system("echo 1 > /sys/class/gpio/gpio9/value");
|
||||
}
|
||||
|
||||
void resetFPGA() {
|
||||
LOG(logINFOBLUE, ("Reseting FPGA\n"));
|
||||
#ifdef VIRTUAL
|
||||
return;
|
||||
#endif
|
||||
FPGAdontTouchFlash();
|
||||
FPGATouchFlash();
|
||||
usleep(CTRL_SRVR_INIT_TIME_US);
|
||||
}
|
||||
|
||||
void eraseFlash() {
|
||||
LOG(logDEBUG1, ("Erasing Flash\n"));
|
||||
char command[255];
|
||||
memset(command, 0, 255);
|
||||
sprintf(command, "flash_eraseall %s", mtdvalue);
|
||||
system(command);
|
||||
LOG(logINFO, ("Flash erased\n"));
|
||||
int deleteOldFile(char *mess) {
|
||||
char cmd[MAX_STR_LENGTH] = {0};
|
||||
char retvals[MAX_STR_LENGTH] = {0};
|
||||
sprintf(cmd, "rm -fr %s", TEMP_PROG_FILE_NAME);
|
||||
if (FAIL == executeCommand(cmd, retvals, logDEBUG1)) {
|
||||
strcpy(mess,
|
||||
"Could not program fpga. (could not delete old file: ");
|
||||
strncat(mess, retvals, sizeof(mess) - strlen(mess) - 1);
|
||||
strcat(mess, "\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tDeleted old programming file (%s)\n", TEMP_PROG_FILE_NAME));
|
||||
return OK;
|
||||
}
|
||||
|
||||
int startWritingFPGAprogram(FILE **filefp) {
|
||||
LOG(logDEBUG1, ("Start Writing of FPGA program\n"));
|
||||
int preparetoCopyFPGAProgram(FILE **fd, uint64_t fsize, char *mess) {
|
||||
|
||||
if (deleteOldFile(mess) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// check available memory to copy program
|
||||
{
|
||||
struct sysinfo info;
|
||||
sysinfo(&info);
|
||||
if (fsize >= info.freeram) {
|
||||
sprintf(mess,
|
||||
"Could not program fpga. Not enough memory to copy "
|
||||
"program. [File size:%ldMB, free RAM: %ldMB]\n",
|
||||
(long int)(fsize / (1024 * 1024)),
|
||||
(long int)(info.freeram / (1024 * 1024)));
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
// open file to copy program
|
||||
*fd = fopen(TEMP_PROG_FILE_NAME, "w");
|
||||
if (*fd == NULL) {
|
||||
sprintf(mess, "Unable to open %s in write mode\n", TEMP_PROG_FILE_NAME);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tGoing to copy program to %s\n", TEMP_PROG_FILE_NAME));
|
||||
return OK;
|
||||
}
|
||||
|
||||
int copyToFlash(ssize_t fsize, char *clientChecksum, char *mess) {
|
||||
|
||||
if (getDrive(mess) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
FILE *flashfd = NULL;
|
||||
FILE *srcfd = NULL;
|
||||
if (openFileForFlash(&flashfd, &srcfd, mess) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (eraseFlash(mess) == FAIL) {
|
||||
fclose(flashfd);
|
||||
fclose(srcfd);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (writeToFlash(fsize, flashfd, srcfd, mess) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (deleteOldFile(mess) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
/* ignoring this until a consistent way to read from bfin flash
|
||||
if (verifyChecksumFromFlash(mess, clientChecksum, flashDriveName, fsize) ==
|
||||
FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
*/
|
||||
if (waitForFPGAtoTouchFlash(mess) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int getDrive(char *mess) {
|
||||
#ifdef VIRTUAL
|
||||
strcpy(flashDriveName, "/tmp/SLS_mtd3");
|
||||
return OK;
|
||||
#endif
|
||||
LOG(logDEBUG1, ("Finding flash drive...\n"));
|
||||
// getting the drive
|
||||
// root:/> cat /proc/mtd
|
||||
// dev: size erasesize name
|
||||
@ -64,86 +166,189 @@ int startWritingFPGAprogram(FILE **filefp) {
|
||||
// mtd1: 00100000 00020000 "linux kernel(nor)"
|
||||
// mtd2: 002c0000 00020000 "file system(nor)"
|
||||
// mtd3: 01000000 00010000 "bitfile(spi)"
|
||||
char output[255];
|
||||
memset(output, 0, 255);
|
||||
FILE *fp = popen(
|
||||
"awk \'$4== \"\\\"bitfile(spi)\\\"\" {print $1}\' /proc/mtd", "r");
|
||||
if (fp == NULL) {
|
||||
LOG(logERROR, ("popen returned NULL. Need that to get mtd drive.\n"));
|
||||
return 1;
|
||||
}
|
||||
if (fgets(output, sizeof(output), fp) == NULL) {
|
||||
LOG(logERROR, ("fgets returned NULL. Need that to get mtd drive.\n"));
|
||||
return 1;
|
||||
}
|
||||
pclose(fp);
|
||||
memset(mtdvalue, 0, MTDSIZE);
|
||||
strcpy(mtdvalue, "/dev/");
|
||||
char *pch = strtok(output, ":");
|
||||
if (pch == NULL) {
|
||||
LOG(logERROR, ("Could not get mtd value\n"));
|
||||
return 1;
|
||||
}
|
||||
strcat(mtdvalue, pch);
|
||||
LOG(logINFO, ("Flash drive found: %s\n", mtdvalue));
|
||||
|
||||
char cmd[MAX_STR_LENGTH] = {0};
|
||||
char retvals[MAX_STR_LENGTH] = {0};
|
||||
strcpy(cmd, CMD_GET_FLASH);
|
||||
if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
|
||||
strcpy(mess, "Could not program fpga. (could not get flash drive: ");
|
||||
strncat(mess, retvals, sizeof(mess) - strlen(mess) - 1);
|
||||
strcat(mess, "\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
char *pch = strtok(retvals, ":");
|
||||
if (pch == NULL) {
|
||||
strcpy(mess, "Could not get mtd drive to flash (strtok fail).\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
memset(flashDriveName, 0, sizeof(flashDriveName));
|
||||
strcpy(flashDriveName, "/dev/");
|
||||
strcat(flashDriveName, pch);
|
||||
LOG(logINFO, ("\tFlash drive found: %s\n", flashDriveName));
|
||||
return OK;
|
||||
}
|
||||
|
||||
int openFileForFlash(FILE **flashfd, FILE **srcfd, char *mess) {
|
||||
FPGAdontTouchFlash();
|
||||
|
||||
// writing the program to flash
|
||||
*filefp = fopen(mtdvalue, "w");
|
||||
if (*filefp == NULL) {
|
||||
LOG(logERROR, ("Unable to open %s in write mode\n", mtdvalue));
|
||||
return 1;
|
||||
// open src file
|
||||
*srcfd = fopen(TEMP_PROG_FILE_NAME, "r");
|
||||
if (*srcfd == NULL) {
|
||||
sprintf(mess,
|
||||
"Could not flash. Unable to open temp program file %s in read "
|
||||
"mode\n",
|
||||
TEMP_PROG_FILE_NAME);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("Flash ready for writing\n"));
|
||||
LOG(logDEBUG1, ("Temp file ready for reading\n"));
|
||||
|
||||
return 0;
|
||||
// open flash drive for writing
|
||||
*flashfd = fopen(flashDriveName, "w");
|
||||
if (*flashfd == NULL) {
|
||||
fclose(*srcfd);
|
||||
sprintf(mess, "Unable to open flash drive %s in write mode\n",
|
||||
flashDriveName);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tFlash ready for writing\n"));
|
||||
return OK;
|
||||
}
|
||||
|
||||
int stopWritingFPGAprogram(FILE *filefp) {
|
||||
LOG(logDEBUG1, ("Stopping of writing FPGA program\n"));
|
||||
int eraseFlash(char *mess) {
|
||||
LOG(logINFO, ("\tErasing Flash...\n"));
|
||||
|
||||
if (filefp != NULL) {
|
||||
fclose(filefp);
|
||||
#ifdef VIRTUAL
|
||||
return OK;
|
||||
#endif
|
||||
char cmd[MAX_STR_LENGTH] = {0};
|
||||
char retvals[MAX_STR_LENGTH] = {0};
|
||||
sprintf(cmd, "flash_eraseall %s", flashDriveName);
|
||||
if (FAIL == executeCommand(cmd, retvals, logDEBUG1)) {
|
||||
strcpy(mess, "Could not program fpga. (could not erase flash: ");
|
||||
strncat(mess, retvals, sizeof(mess) - strlen(mess) - 1);
|
||||
strcat(mess, "\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
LOG(logINFO, ("\tFlash erased\n"));
|
||||
return OK;
|
||||
}
|
||||
|
||||
int writeToFlash(ssize_t fsize, FILE *flashfd, FILE *srcfd, char *mess) {
|
||||
LOG(logDEBUG1, ("writing to flash\n"));
|
||||
|
||||
|
||||
char* buffer = malloc(FLASH_BUFFER_MEMORY_SIZE);
|
||||
if (buffer == NULL) {
|
||||
fclose(flashfd);
|
||||
fclose(srcfd);
|
||||
strcpy(mess, "Could not program fpga. Memory allocation to write to "
|
||||
"flash failed.\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tWriting to Flash...\n"));
|
||||
|
||||
int oldProgress = 0;
|
||||
ssize_t totalBytes = 0;
|
||||
ssize_t bytes = fread((void*)buffer, sizeof(char), FLASH_BUFFER_MEMORY_SIZE, srcfd);
|
||||
|
||||
while (bytes > 0) {
|
||||
|
||||
ssize_t bytesWritten =
|
||||
fwrite((void*)buffer, sizeof(char), bytes, flashfd);
|
||||
totalBytes += bytesWritten;
|
||||
|
||||
if (bytesWritten != bytes) {
|
||||
free(buffer);
|
||||
fclose(flashfd);
|
||||
fclose(srcfd);
|
||||
sprintf(mess,
|
||||
"Could not write to flash (bytes written:%ld, expected: "
|
||||
"%ld, total written:%ld)\n",
|
||||
(long int)bytesWritten, (long int)bytes,
|
||||
(long int)totalBytes);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// print progress
|
||||
if (fsize > 0) {
|
||||
int progress = (int)(((double)(totalBytes) / fsize) * 100);
|
||||
if (oldProgress != progress) {
|
||||
printf("%d%%\r", progress);
|
||||
fflush(stdout);
|
||||
oldProgress = progress;
|
||||
}
|
||||
} else printf(".");
|
||||
|
||||
bytes = fread((void*)buffer, sizeof(char), FLASH_BUFFER_MEMORY_SIZE, srcfd);
|
||||
}
|
||||
if (fsize <= 0) {
|
||||
printf("\n");
|
||||
}
|
||||
free(buffer);
|
||||
fclose(flashfd);
|
||||
fclose(srcfd);
|
||||
LOG(logINFO, ("\tWrote %ld bytes to flash\n", totalBytes));
|
||||
|
||||
if (totalBytes != fsize) {
|
||||
sprintf(mess, "Could not program fpga. Incorrect bytes written to flash %lu [expected: %lu]\n", totalBytes, fsize);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int waitForFPGAtoTouchFlash(char* mess) {
|
||||
// touch and program
|
||||
FPGATouchFlash();
|
||||
|
||||
LOG(logINFO, ("Waiting for FPGA to program from flash\n"));
|
||||
// waiting for success or done
|
||||
char output[255];
|
||||
int res = 0;
|
||||
#ifdef VIRTUAL
|
||||
return OK;
|
||||
#endif
|
||||
LOG(logINFO, ("\tWaiting for FPGA to program from flash\n"));
|
||||
int timeSpent = 0;
|
||||
while (res == 0) {
|
||||
|
||||
int result = 0;
|
||||
while (result == 0) {
|
||||
// time taken for fpga to pick up from flash
|
||||
usleep(1000);
|
||||
timeSpent += 1000;
|
||||
if (timeSpent >= MAX_TIME_FPGA_TOUCH_FLASH_US) {
|
||||
return 1;
|
||||
}
|
||||
FILE *sysFile = popen("cat /sys/class/gpio/gpio7/value", "r");
|
||||
fgets(output, sizeof(output), sysFile);
|
||||
pclose(sysFile);
|
||||
sscanf(output, "%d", &res);
|
||||
LOG(logDEBUG1, ("gpi07 returned %d\n", res));
|
||||
}
|
||||
LOG(logINFO, ("FPGA has picked up the program from flash\n"));
|
||||
return 0;
|
||||
sprintf(mess, "Could not program fpga. (exceeded max time allowed: %ds)\n",
|
||||
MAX_TIME_FPGA_TOUCH_FLASH_US/(1000 * 1000));
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
int writeFPGAProgram(char *fpgasrc, uint64_t fsize, FILE *filefp) {
|
||||
LOG(logDEBUG1,
|
||||
("Writing of FPGA Program\n"
|
||||
"\taddress of fpgasrc:%p\n"
|
||||
"\tfsize:%llu\n\tpointer:%p\n",
|
||||
(void *)fpgasrc, (long long unsigned int)fsize, (void *)filefp));
|
||||
// read gpio status
|
||||
char retvals[MAX_STR_LENGTH] = {0};
|
||||
if (FAIL == executeCommand(CMD_FPGA_PICKED_STATUS, retvals, logDEBUG1)) {
|
||||
strcpy(mess,
|
||||
"Could not program fpga. (could not read gpio status: ");
|
||||
strncat(mess, retvals, sizeof(mess) - strlen(mess) - 1);
|
||||
strcat(mess, "\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (fwrite((void *)fpgasrc, sizeof(char), fsize, filefp) != fsize) {
|
||||
LOG(logERROR, ("Could not write FPGA source to flash (size:%llu)\n",
|
||||
(long long unsigned int)fsize));
|
||||
return 1;
|
||||
// convert to int
|
||||
if (sscanf(retvals, "%d\n", &result) != 1) {
|
||||
sprintf(mess, "Could not program fpga. (could not scan int for gpio status: [%s])\n",
|
||||
retvals);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logDEBUG1, ("program written to flash\n"));
|
||||
return 0;
|
||||
LOG(logDEBUG1, ("gpi07 returned %d\n", result));
|
||||
}
|
||||
LOG(logINFO, ("\tFPGA has picked up the program from flash\n"));
|
||||
return OK;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "programFpgaNios.h"
|
||||
#include "clogger.h"
|
||||
#include "common.h"
|
||||
#include "sls/ansi.h"
|
||||
#include "slsDetectorServer_defs.h"
|
||||
|
||||
@ -7,10 +8,15 @@
|
||||
#include <unistd.h> // usleep
|
||||
|
||||
/* global variables */
|
||||
#define MTDSIZE 10
|
||||
char mtdvalue[MTDSIZE] = {0};
|
||||
|
||||
#define CMD_GET_FLASH "awk \'$5== \"Application\" {print $1}\' /proc/mtd"
|
||||
|
||||
#define FLASH_DRIVE_NAME_SIZE 16
|
||||
char flashDriveName[FLASH_DRIVE_NAME_SIZE] = {0};
|
||||
#define MICROCONTROLLER_FILE "/dev/ttyAL0"
|
||||
|
||||
extern int executeCommand(char *command, char *result, enum TLogLevel level);
|
||||
|
||||
void NotifyServerStartSuccess() {
|
||||
LOG(logINFOBLUE, ("Server started successfully\n"));
|
||||
char command[255];
|
||||
@ -27,7 +33,44 @@ void rebootControllerAndFPGA() {
|
||||
system(command);
|
||||
}
|
||||
|
||||
int findFlash(char *mess) {
|
||||
int eraseAndWriteToFlash(char *mess, char *checksum, char *fpgasrc,
|
||||
uint64_t fsize) {
|
||||
|
||||
if (verifyChecksumFromBuffer(mess, checksum, fpgasrc, fsize) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (getDrive(mess) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
FILE *flashfd = NULL;
|
||||
if (openFileForFlash(&flashfd, mess) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (eraseFlash(mess) == FAIL) {
|
||||
fclose(flashfd);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (writeToFlash(fsize, flashfd, fpgasrc, mess) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
/* ignoring this until a consistent way to read from nios flash
|
||||
if (verifyChecksumFromFlash(mess, checksum, flashDriveName, fsize) ==
|
||||
FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
*/
|
||||
return OK;
|
||||
}
|
||||
|
||||
int getDrive(char *mess) {
|
||||
#ifdef VIRTUAL
|
||||
strcpy(flashDriveName, "/tmp/SLS_mtd3");
|
||||
return OK;
|
||||
#endif
|
||||
LOG(logDEBUG1, ("Finding flash drive...\n"));
|
||||
// getting the drive
|
||||
// # cat /proc/mtd
|
||||
@ -38,82 +81,78 @@ int findFlash(char *mess) {
|
||||
// mtd3: 00800000 00010000 "qspi Linux Kernel with initramfs Backup"
|
||||
// mtd4: 02500000 00010000 "qspi ubi filesystem"
|
||||
// mtd5: 04000000 00010000 "qspi Complete Flash"
|
||||
char output[255];
|
||||
memset(output, 0, 255);
|
||||
FILE *fp = popen("awk \'$5== \"Application\" {print $1}\' /proc/mtd", "r");
|
||||
if (fp == NULL) {
|
||||
strcpy(mess, "popen returned NULL. Need that to get mtd drive.\n");
|
||||
|
||||
char cmd[MAX_STR_LENGTH] = {0};
|
||||
char retvals[MAX_STR_LENGTH] = {0};
|
||||
strcpy(cmd, CMD_GET_FLASH);
|
||||
if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
|
||||
strcpy(mess, "Could not program fpga. (could not get flash drive: ");
|
||||
strncat(mess, retvals, sizeof(mess) - strlen(mess) - 1);
|
||||
strcat(mess, "\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
if (fgets(output, sizeof(output), fp) == NULL) {
|
||||
strcpy(mess, "fgets returned NULL. Need that to get mtd drive.\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
pclose(fp);
|
||||
memset(mtdvalue, 0, MTDSIZE);
|
||||
strcpy(mtdvalue, "/dev/");
|
||||
char *pch = strtok(output, ":");
|
||||
|
||||
char *pch = strtok(retvals, ":");
|
||||
if (pch == NULL) {
|
||||
strcpy(mess, "Could not get mtd value\n");
|
||||
strcpy(mess, "Could not get mtd drive to flash (strtok fail).\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
strcat(mtdvalue, pch);
|
||||
LOG(logINFO, ("\tFlash drive found: %s\n", mtdvalue));
|
||||
|
||||
memset(flashDriveName, 0, sizeof(flashDriveName));
|
||||
strcpy(flashDriveName, "/dev/");
|
||||
strcat(flashDriveName, pch);
|
||||
LOG(logINFO, ("\tFlash drive found: %s\n", flashDriveName));
|
||||
return OK;
|
||||
}
|
||||
|
||||
void eraseFlash() {
|
||||
LOG(logDEBUG1, ("Erasing Flash...\n"));
|
||||
char command[255];
|
||||
memset(command, 0, 255);
|
||||
sprintf(command, "flash_erase %s 0 0", mtdvalue);
|
||||
system(command);
|
||||
LOG(logINFO, ("\tFlash erased\n"));
|
||||
}
|
||||
|
||||
int eraseAndWriteToFlash(char *mess, char *fpgasrc, uint64_t fsize) {
|
||||
if (findFlash(mess) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
eraseFlash();
|
||||
|
||||
// open file pointer to flash
|
||||
FILE *filefp = fopen(mtdvalue, "w");
|
||||
if (filefp == NULL) {
|
||||
sprintf(mess, "Unable to open %s in write mode\n", mtdvalue);
|
||||
int openFileForFlash(FILE **flashfd, char *mess) {
|
||||
*flashfd = fopen(flashDriveName, "w");
|
||||
if (*flashfd == NULL) {
|
||||
sprintf(mess, "Unable to open flash drive %s in write mode\n",
|
||||
flashDriveName);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tFlash ready for writing\n"));
|
||||
|
||||
// write to flash
|
||||
if (writeFPGAProgram(mess, fpgasrc, fsize, filefp) == FAIL) {
|
||||
fclose(filefp);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
fclose(filefp);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int writeFPGAProgram(char *mess, char *fpgasrc, uint64_t fsize, FILE *filefp) {
|
||||
LOG(logDEBUG1, ("Writing to flash...\n"
|
||||
"\taddress of fpgasrc:%p\n"
|
||||
"\tfsize:%lu\n\tpointer:%p\n",
|
||||
(void *)fpgasrc, fsize, (void *)filefp));
|
||||
int eraseFlash(char *mess) {
|
||||
LOG(logINFO, ("\tErasing Flash...\n"));
|
||||
|
||||
uint64_t retval = fwrite((void *)fpgasrc, sizeof(char), fsize, filefp);
|
||||
if (retval != fsize) {
|
||||
sprintf(
|
||||
mess,
|
||||
"Could not write FPGA source to flash (size:%llu), write %llu\n",
|
||||
(long long unsigned int)fsize, (long long unsigned int)retval);
|
||||
#ifdef VIRTUAL
|
||||
return OK;
|
||||
#endif
|
||||
char cmd[MAX_STR_LENGTH] = {0};
|
||||
char retvals[MAX_STR_LENGTH] = {0};
|
||||
sprintf(cmd, "flash_erase %s 0 0", flashDriveName);
|
||||
if (FAIL == executeCommand(cmd, retvals, logDEBUG1)) {
|
||||
strcpy(mess, "Could not program fpga. (could not erase flash: ");
|
||||
strncat(mess, retvals, sizeof(mess) - strlen(mess) - 1);
|
||||
strcat(mess, "\n");
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tProgram written to flash\n"));
|
||||
|
||||
LOG(logINFO, ("\tFlash erased\n"));
|
||||
return OK;
|
||||
}
|
||||
|
||||
int writeToFlash(ssize_t fsize, FILE *flashfd, char *buffer, char *mess) {
|
||||
LOG(logINFO, ("\tWriting to Flash...\n"));
|
||||
|
||||
ssize_t bytesWritten = fwrite((void *)buffer, sizeof(char), fsize, flashfd);
|
||||
if (bytesWritten != fsize) {
|
||||
fclose(flashfd);
|
||||
sprintf(
|
||||
mess,
|
||||
"Could not program fpga. Incorrect bytes written to flash %lu [expected: %lu]\n",
|
||||
(long int)bytesWritten, (long int)fsize);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("\tWritten to Flash\n"));
|
||||
return OK;
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/sysinfo.h>
|
||||
|
||||
// defined in the detector specific Makefile
|
||||
#ifdef GOTTHARDD
|
||||
@ -407,7 +408,7 @@ void function_table() {
|
||||
flist[F_GET_DEST_UDP_LIST] = &get_dest_udp_list;
|
||||
flist[F_SET_DEST_UDP_LIST] = &set_dest_udp_list;
|
||||
flist[F_GET_NUM_DEST_UDP] = &get_num_dest_list;
|
||||
flist[F_SET_NUM_DEST_UDP] = &set_num_dest_list;
|
||||
flist[F_CLEAR_ALL_UDP_DEST] = &clear_all_udp_dst;
|
||||
flist[F_GET_UDP_FIRST_DEST] = &get_udp_first_dest;
|
||||
flist[F_SET_UDP_FIRST_DEST] = &set_udp_first_dest;
|
||||
|
||||
@ -444,11 +445,13 @@ int executeCommand(char *command, char *result, enum TLogLevel level) {
|
||||
memset(temp, 0, tempsize);
|
||||
memset(result, 0, MAX_STR_LENGTH);
|
||||
|
||||
LOG(level, ("Executing command:\n[%s]\n", command));
|
||||
strcat(command, " 2>&1");
|
||||
// copy command
|
||||
char cmd[MAX_STR_LENGTH]= {0};
|
||||
sprintf(cmd, "%s 2>&1", command);
|
||||
LOG(level, ("Executing command:\n[%s]\n", cmd));
|
||||
|
||||
fflush(stdout);
|
||||
FILE *sysFile = popen(command, "r");
|
||||
FILE *sysFile = popen(cmd, "r");
|
||||
while (fgets(temp, tempsize, sysFile) != NULL) {
|
||||
// size left excludes terminating character
|
||||
size_t sizeleft = MAX_STR_LENGTH - strlen(result) - 1;
|
||||
@ -460,16 +463,19 @@ int executeCommand(char *command, char *result, enum TLogLevel level) {
|
||||
strncat(result, temp, tempsize);
|
||||
memset(temp, 0, tempsize);
|
||||
}
|
||||
int sucess = pclose(sysFile);
|
||||
result[MAX_STR_LENGTH - 1] = '\0';
|
||||
int success = pclose(sysFile);
|
||||
if (strlen(result)) {
|
||||
if (sucess) {
|
||||
sucess = FAIL;
|
||||
if (success) {
|
||||
success = FAIL;
|
||||
LOG(logERROR, ("%s\n", result));
|
||||
} else {
|
||||
LOG(level, ("Result:\n[%s]\n", result));
|
||||
}
|
||||
} else {
|
||||
LOG(level, ("No result\n"));
|
||||
}
|
||||
return sucess;
|
||||
return success;
|
||||
}
|
||||
|
||||
int M_nofunc(int file_des) {
|
||||
@ -1497,7 +1503,7 @@ int set_module(int file_des) {
|
||||
ret = OK;
|
||||
memset(mess, 0, sizeof(mess));
|
||||
|
||||
#if defined(CHIPTESTBOARDD) || defined(MOENCHD) || defined(GOTTHARD2D)
|
||||
#if !(defined(MYTHEN3D) || defined(EIGERD))
|
||||
functionNotImplemented();
|
||||
#else
|
||||
|
||||
@ -1518,7 +1524,6 @@ int set_module(int file_des) {
|
||||
} else
|
||||
module.dacs = myDac;
|
||||
|
||||
#if defined(EIGERD) || defined(MYTHEN3D)
|
||||
// allocate chans
|
||||
if (ret == OK) {
|
||||
myChan = malloc(getTotalNumberOfChannels() * sizeof(int));
|
||||
@ -1529,7 +1534,6 @@ int set_module(int file_des) {
|
||||
} else
|
||||
module.chanregs = myChan;
|
||||
}
|
||||
#endif
|
||||
// receive arguments
|
||||
if (ret == OK) {
|
||||
module.nchip = getNumberOfChips();
|
||||
@ -1567,6 +1571,7 @@ int set_module(int file_des) {
|
||||
|
||||
// setsettings
|
||||
#ifndef MYTHEN3D
|
||||
// m3 uses reg for chip (not settings)
|
||||
validate_settings((enum detectorSettings)(module.reg));
|
||||
#endif
|
||||
ret = setModule(module, mess);
|
||||
@ -3674,19 +3679,25 @@ int program_fpga(int file_des) {
|
||||
n = receiveData(file_des, mess, MAX_STR_LENGTH, OTHER);
|
||||
functionNotImplemented();
|
||||
#else
|
||||
#ifndef VIRTUAL
|
||||
// only set
|
||||
if (Server_VerifyLock() == OK) {
|
||||
|
||||
LOG(logINFOBLUE, ("Programming FPGA...\n"));
|
||||
|
||||
#if defined(MYTHEN3D) || defined(GOTTHARD2D)
|
||||
uint64_t filesize = 0;
|
||||
// filesize
|
||||
uint64_t filesize = 0;
|
||||
if (receiveData(file_des, &filesize, sizeof(filesize), INT64) < 0)
|
||||
return printSocketReadError();
|
||||
LOG(logDEBUG1, ("Total program size is: %llx\n",
|
||||
(long long unsigned int)filesize));
|
||||
LOG(logDEBUG1, ("Program size is: %lld\n", (long long int)filesize));
|
||||
|
||||
// checksum
|
||||
char checksum[MAX_STR_LENGTH];
|
||||
memset(checksum, 0, MAX_STR_LENGTH);
|
||||
if (receiveData(file_des, checksum, MAX_STR_LENGTH, OTHER) < 0)
|
||||
return printSocketReadError();
|
||||
LOG(logDEBUG1, ("checksum is: %s\n\n", checksum));
|
||||
|
||||
#if defined(MYTHEN3D) || defined(GOTTHARD2D)
|
||||
if (filesize > NIOS_MAX_APP_IMAGE_SIZE) {
|
||||
ret = FAIL;
|
||||
sprintf(mess,
|
||||
@ -3701,119 +3712,108 @@ int program_fpga(int file_des) {
|
||||
// receive program
|
||||
if (ret == OK) {
|
||||
char *fpgasrc = malloc(filesize);
|
||||
if (receiveData(file_des, fpgasrc, filesize, OTHER) < 0)
|
||||
return printSocketReadError();
|
||||
|
||||
ret = eraseAndWriteToFlash(mess, fpgasrc, filesize);
|
||||
Server_SendResult(file_des, INT32, NULL, 0);
|
||||
|
||||
// free resources
|
||||
if (receiveData(file_des, fpgasrc, filesize, OTHER) < 0) {
|
||||
free(fpgasrc);
|
||||
return printSocketReadError();
|
||||
}
|
||||
ret = eraseAndWriteToFlash(mess, checksum, fpgasrc, filesize);
|
||||
Server_SendResult(file_des, INT32, NULL, 0);
|
||||
free(fpgasrc);
|
||||
}
|
||||
if (ret == FAIL) {
|
||||
LOG(logERROR, ("Program FPGA FAIL!\n"));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
#else // jungfrau, ctb, moench
|
||||
uint64_t filesize = 0;
|
||||
uint64_t totalsize = 0;
|
||||
uint64_t unitprogramsize = 0;
|
||||
char *fpgasrc = NULL;
|
||||
FILE *fp = NULL;
|
||||
|
||||
// filesize
|
||||
if (receiveData(file_des, &filesize, sizeof(filesize), INT32) < 0)
|
||||
return printSocketReadError();
|
||||
totalsize = filesize;
|
||||
LOG(logDEBUG1, ("Total program size is: %lld\n",
|
||||
(long long unsigned int)totalsize));
|
||||
|
||||
// opening file pointer to flash and telling FPGA to not touch flash
|
||||
if (startWritingFPGAprogram(&fp) != OK) {
|
||||
ret = FAIL;
|
||||
sprintf(mess, "Could not write to flash. Error at startup.\n");
|
||||
// open file and allocate memory for part program
|
||||
FILE *fd = NULL;
|
||||
ret = preparetoCopyFPGAProgram(&fd, filesize, mess);
|
||||
char *src = NULL;
|
||||
if (ret == OK) {
|
||||
src = malloc(MAX_FPGAPROGRAMSIZE);
|
||||
if (src == NULL) {
|
||||
fclose(fd);
|
||||
struct sysinfo info;
|
||||
sysinfo(&info);
|
||||
sprintf(mess, "Could not allocate memory to get fpga program. Free space: %d MB\n", (int)(info.freeram/ (1024 * 1024)));
|
||||
LOG(logERROR, (mess));
|
||||
ret = FAIL;
|
||||
}
|
||||
}
|
||||
Server_SendResult(file_des, INT32, NULL, 0);
|
||||
|
||||
// erasing flash
|
||||
if (ret != FAIL) {
|
||||
eraseFlash();
|
||||
fpgasrc = malloc(MAX_FPGAPROGRAMSIZE);
|
||||
if (ret == FAIL) {
|
||||
LOG(logERROR, ("Program FPGA FAIL1!\n"));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// writing to flash part by part
|
||||
int clientSocketCrash = 0;
|
||||
while (ret != FAIL && filesize) {
|
||||
|
||||
unitprogramsize = MAX_FPGAPROGRAMSIZE; // 2mb
|
||||
// copying program part by part
|
||||
uint64_t totalsize = filesize;
|
||||
while (ret == OK && filesize) {
|
||||
uint64_t unitprogramsize = MAX_FPGAPROGRAMSIZE; // 2mb
|
||||
if (unitprogramsize > filesize) // less than 2mb
|
||||
unitprogramsize = filesize;
|
||||
LOG(logDEBUG1, ("unit size to receive is:%lld\nfilesize:%lld\n",
|
||||
LOG(logDEBUG1, ("unit size to receive is:%lld [filesize:%lld]\n",
|
||||
(long long unsigned int)unitprogramsize,
|
||||
(long long unsigned int)filesize));
|
||||
|
||||
// receive part of program
|
||||
if (receiveData(file_des, fpgasrc, unitprogramsize, OTHER) < 0) {
|
||||
if (receiveData(file_des, src, unitprogramsize, OTHER) < 0) {
|
||||
printSocketReadError();
|
||||
clientSocketCrash = 1;
|
||||
ret = FAIL;
|
||||
break;
|
||||
}
|
||||
// client has not crashed yet, so write to flash and send ret
|
||||
else {
|
||||
if (!(unitprogramsize - filesize)) {
|
||||
fpgasrc[unitprogramsize] = '\0';
|
||||
|
||||
if (unitprogramsize - filesize == 0) {
|
||||
// src[unitprogramsize] = '\0';
|
||||
filesize -= unitprogramsize;
|
||||
unitprogramsize++;
|
||||
// unitprogramsize++;
|
||||
} else
|
||||
filesize -= unitprogramsize;
|
||||
|
||||
// write part to flash
|
||||
ret = writeFPGAProgram(fpgasrc, unitprogramsize, fp);
|
||||
// copy program
|
||||
if (fwrite((void *)src, sizeof(char), unitprogramsize, fd) !=
|
||||
unitprogramsize) {
|
||||
ret = FAIL;
|
||||
sprintf(mess, "Could not copy program to /var/tmp (size:%ld)\n",
|
||||
(long int)unitprogramsize);
|
||||
LOG(logERROR, (mess));
|
||||
}
|
||||
Server_SendResult(file_des, INT32, NULL, 0);
|
||||
if (ret == FAIL) {
|
||||
strcpy(mess, "Could not write to flash. Breaking out of "
|
||||
"program receiving. Try to flash again "
|
||||
"without rebooting.\n");
|
||||
LOG(logERROR, (mess));
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
// print progress
|
||||
LOG(logINFO,
|
||||
("Writing to Flash:%d%%\r",
|
||||
(int)(((double)(totalsize - filesize) / totalsize) *
|
||||
100)));
|
||||
("\t%d%%\r",
|
||||
(int)(((double)(totalsize - filesize) / totalsize) * 100)));
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
}
|
||||
free(src);
|
||||
fclose(fd);
|
||||
|
||||
// checksum of copied program
|
||||
if (ret == OK) {
|
||||
LOG(logINFO, ("Done copying program\n"));
|
||||
// closing file pointer to flash and informing FPGA
|
||||
ret = stopWritingFPGAprogram(fp);
|
||||
if (ret == FAIL) {
|
||||
strcpy(mess, "Failed to program fpga. FPGA is taking too long "
|
||||
"to pick up program from flash! Try to flash "
|
||||
"again without rebooting!\n");
|
||||
LOG(logERROR, (mess));
|
||||
ret =
|
||||
verifyChecksumFromFile(mess, checksum, TEMP_PROG_FILE_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
// free resources
|
||||
free(fpgasrc);
|
||||
if (fp != NULL)
|
||||
fclose(fp);
|
||||
|
||||
// send final ret (if no client crash)
|
||||
if (clientSocketCrash == 0) {
|
||||
Server_SendResult(file_des, INT32, NULL, 0);
|
||||
if (ret == FAIL) {
|
||||
LOG(logERROR, ("Program FPGA FAIL!\n"));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// copy to flash
|
||||
ret = copyToFlash(totalsize, checksum, mess);
|
||||
Server_SendResult(file_des, INT32, NULL, 0);
|
||||
if (ret == FAIL) {
|
||||
LOG(logERROR, ("Program FPGA FAIL!\n"));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
#endif // end of Blackfin programming
|
||||
if (ret == FAIL) {
|
||||
LOG(logERROR, ("Program FPGA FAIL!\n"));
|
||||
} else {
|
||||
LOG(logINFOGREEN, ("Programming FPGA completed successfully\n"));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
@ -4322,11 +4322,19 @@ int reboot_controller(int file_des) {
|
||||
Server_SendResult(file_des, INT32, NULL, 0);
|
||||
return GOODBYE;
|
||||
}
|
||||
#ifdef VIRTUAL
|
||||
ret = GOODBYE;
|
||||
#else
|
||||
ret = REBOOT;
|
||||
#endif
|
||||
#elif EIGERD
|
||||
functionNotImplemented();
|
||||
#else
|
||||
#ifdef VIRTUAL
|
||||
ret = GOODBYE;
|
||||
#else
|
||||
ret = REBOOT;
|
||||
#endif
|
||||
#endif
|
||||
Server_SendResult(file_des, INT32, NULL, 0);
|
||||
return ret;
|
||||
@ -4783,7 +4791,7 @@ int set_read_n_rows(int file_des) {
|
||||
LOG(logERROR, (mess));
|
||||
} else
|
||||
#elif JUNGFRAUD
|
||||
if ((check_detector_idle("set nmber of rows") == OK) && (arg % READ_N_ROWS_MULTIPLE != 0)) {
|
||||
if ((check_detector_idle("set number of rows") == OK) && (arg % READ_N_ROWS_MULTIPLE != 0)) {
|
||||
ret = FAIL;
|
||||
sprintf(mess,
|
||||
"Could not set number of rows. %d must be a multiple "
|
||||
@ -8849,8 +8857,7 @@ int set_flip_rows(int file_des) {
|
||||
#else
|
||||
// only set
|
||||
if (Server_VerifyLock() == OK) {
|
||||
|
||||
if (arg != 0 && arg != 1) {
|
||||
if ((check_detector_idle("set flip rows") == OK) && (arg != 0 && arg != 1)) {
|
||||
ret = FAIL;
|
||||
sprintf(mess,
|
||||
"Could not set flip rows. Invalid argument %d.\n",
|
||||
@ -9191,10 +9198,35 @@ int set_dest_udp_list(int file_des) {
|
||||
}
|
||||
}
|
||||
}
|
||||
// find number of destinations
|
||||
int numdest = 0;
|
||||
for (int i = MAX_UDP_DESTINATION; i >= 0; --i) {
|
||||
if (udpDetails[i].dstip != 0) {
|
||||
numdest = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// atleast 1 destination
|
||||
if (numdest == 0) {
|
||||
numdest = 1;
|
||||
}
|
||||
// set number of destinations
|
||||
#if defined(JUNGFRAUD) || defined(EIGERD)
|
||||
if (setNumberofDestinations(numdest) == FAIL) {
|
||||
ret = FAIL;
|
||||
strcpy(mess, "Could not set number of udp destinations.\n");
|
||||
LOG(logERROR, (mess));
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
numUdpDestinations = numdest;
|
||||
LOG(logINFOBLUE, ("Number of UDP Destinations: %d\n",
|
||||
numUdpDestinations));
|
||||
configure_mac();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT32, NULL, 0);
|
||||
}
|
||||
@ -9203,10 +9235,13 @@ int get_num_dest_list(int file_des) {
|
||||
ret = OK;
|
||||
memset(mess, 0, sizeof(mess));
|
||||
int retval = -1;
|
||||
|
||||
#if !defined(JUNGFRAUD) && !defined(EIGERD)
|
||||
functionNotImplemented();
|
||||
#else
|
||||
retval = numUdpDestinations;
|
||||
LOG(logDEBUG1, ("numUdpDestinations retval: 0x%x\n", retval));
|
||||
|
||||
int retval1 = 0;
|
||||
if (getNumberofDestinations(&retval1) == FAIL || retval1 != retval) {
|
||||
ret = FAIL;
|
||||
@ -9216,42 +9251,23 @@ int get_num_dest_list(int file_des) {
|
||||
LOG(logERROR, (mess));
|
||||
}
|
||||
#endif
|
||||
LOG(logDEBUG1, ("numUdpDestinations retval: 0x%x\n", retval));
|
||||
|
||||
return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
|
||||
}
|
||||
|
||||
int set_num_dest_list(int file_des) {
|
||||
int clear_all_udp_dst(int file_des) {
|
||||
ret = OK;
|
||||
memset(mess, 0, sizeof(mess));
|
||||
int arg = -1;
|
||||
|
||||
if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0)
|
||||
return printSocketReadError();
|
||||
LOG(logDEBUG1, ("Setting number of udp destinations to %d\n", arg));
|
||||
|
||||
#if !defined(JUNGFRAUD) && !defined(EIGERD)
|
||||
functionNotImplemented();
|
||||
#else
|
||||
if (arg < 1 || arg > MAX_UDP_DESTINATION) {
|
||||
ret = FAIL;
|
||||
sprintf(mess,
|
||||
"Could not set number of udp destinations. Options: 1-%d\n",
|
||||
MAX_UDP_DESTINATION);
|
||||
LOG(logERROR, (mess));
|
||||
} else {
|
||||
if (check_detector_idle("set number of udp destinations") == OK) {
|
||||
if (setNumberofDestinations(arg) == FAIL) {
|
||||
ret = FAIL;
|
||||
strcpy(mess,
|
||||
"Could not set number of udp destinations.\n");
|
||||
LOG(logERROR, (mess));
|
||||
} else {
|
||||
numUdpDestinations = arg;
|
||||
LOG(logINFO, ("Clearing all udp destinations\n"));
|
||||
if (Server_VerifyLock() == OK) {
|
||||
if (check_detector_idle("clear all udp destinations") == OK) {
|
||||
memset(udpDetails, 0, sizeof(udpDetails));
|
||||
// minimum 1 destination in fpga
|
||||
numUdpDestinations = 1;
|
||||
configure_mac();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT32, NULL, 0);
|
||||
}
|
||||
|
||||
@ -9288,6 +9304,8 @@ int set_udp_first_dest(int file_des) {
|
||||
#ifndef JUNGFRAUD
|
||||
functionNotImplemented();
|
||||
#else
|
||||
// only set
|
||||
if (Server_VerifyLock() == OK) {
|
||||
if (arg < 0 || arg >= numUdpDestinations) {
|
||||
ret = FAIL;
|
||||
sprintf(mess, "Could not set first destination. Options: 0-%d\n",
|
||||
@ -9304,6 +9322,7 @@ int set_udp_first_dest(int file_des) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT32, NULL, 0);
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ class IpAddr;
|
||||
// Free function to avoid dependence on class
|
||||
// and avoid the option to free another objects
|
||||
// shm by mistake
|
||||
void freeSharedMemory(int multiId, int detPos = -1);
|
||||
void freeSharedMemory(int detectorIndex, int moduleIndex = -1);
|
||||
|
||||
/**
|
||||
* \class Detector
|
||||
@ -671,8 +671,7 @@ class Detector {
|
||||
/** [Jungfrau][Eiger] */
|
||||
Result<int> getNumberofUDPDestinations(Positions pos = {}) const;
|
||||
|
||||
/**[Jungfrau][Eiger] Options 1-32 */
|
||||
void setNumberofUDPDestinations(const int value, Positions pos = {});
|
||||
void clearUDPDestinations(Positions pos = {});
|
||||
|
||||
/** [Jungfrau] */
|
||||
Result<int> getFirstUDPDestination(Positions pos = {}) const;
|
||||
|
@ -67,7 +67,7 @@ int main(int argc, char *argv[]) {
|
||||
sls::Detector det(parser.multi_id());
|
||||
sls::CmdProxy proxy(&det);
|
||||
proxy.Call(parser.command(), parser.arguments(), parser.detector_id(),
|
||||
action);
|
||||
action, std::cout, parser.receiver_id());
|
||||
} catch (const sls::RuntimeError &e) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
@ -29,10 +29,11 @@ std::ostream &operator<<(std::ostream &os,
|
||||
|
||||
void CmdProxy::Call(const std::string &command,
|
||||
const std::vector<std::string> &arguments, int detector_id,
|
||||
int action, std::ostream &os) {
|
||||
int action, std::ostream &os, int receiver_id) {
|
||||
cmd = command;
|
||||
args = arguments;
|
||||
det_id = detector_id;
|
||||
rx_id = receiver_id;
|
||||
|
||||
std::string temp;
|
||||
while (temp != cmd) {
|
||||
@ -1381,16 +1382,13 @@ IpAddr CmdProxy::getIpFromAuto() {
|
||||
|
||||
UdpDestination CmdProxy::getUdpEntry() {
|
||||
UdpDestination udpDestination{};
|
||||
bool hasEntry = false;
|
||||
udpDestination.entry = rx_id;
|
||||
|
||||
for (auto it : args) {
|
||||
size_t pos = it.find('=');
|
||||
std::string key = it.substr(0, pos);
|
||||
std::string value = it.substr(pos + 1);
|
||||
if (key == "entry") {
|
||||
udpDestination.entry = StringTo<int>(value);
|
||||
hasEntry = true;
|
||||
} else if (key == "ip") {
|
||||
if (key == "ip") {
|
||||
if (value == "auto") {
|
||||
auto val = getIpFromAuto();
|
||||
LOG(logINFO) << "Setting udp_dstip of detector " << det_id
|
||||
@ -1418,9 +1416,6 @@ UdpDestination CmdProxy::getUdpEntry() {
|
||||
udpDestination.port2 = StringTo<uint32_t>(value);
|
||||
}
|
||||
}
|
||||
if (!hasEntry) {
|
||||
throw sls::RuntimeError("Found no entry argument.");
|
||||
}
|
||||
return udpDestination;
|
||||
}
|
||||
|
||||
@ -1437,16 +1432,29 @@ std::string CmdProxy::UDPDestinationList(int action) {
|
||||
"set to ip of rx_hostname."
|
||||
<< '\n';
|
||||
} else if (action == defs::GET_ACTION) {
|
||||
if (args.size() != 1) {
|
||||
WrongNumberOfParameters(1);
|
||||
if (!args.empty()) {
|
||||
WrongNumberOfParameters(0);
|
||||
}
|
||||
auto t = det->getDestinationUDPList(StringTo<int>(args[0]),
|
||||
std::vector<int>{det_id});
|
||||
if (det_id == -1) {
|
||||
throw sls::RuntimeError("udp_dstlist must be at module level.");
|
||||
}
|
||||
if (rx_id < 0 || rx_id >= MAX_UDP_DESTINATION) {
|
||||
throw sls::RuntimeError(
|
||||
"Invalid receiver index to get round robin entry.");
|
||||
}
|
||||
auto t = det->getDestinationUDPList(rx_id, std::vector<int>{det_id});
|
||||
os << OutString(t) << '\n';
|
||||
} else if (action == defs::PUT_ACTION) {
|
||||
if (args.empty()) {
|
||||
WrongNumberOfParameters(1);
|
||||
}
|
||||
if (det_id == -1) {
|
||||
throw sls::RuntimeError("udp_dstlist must be at module level.");
|
||||
}
|
||||
if (rx_id < 0 || rx_id >= MAX_UDP_DESTINATION) {
|
||||
throw sls::RuntimeError(
|
||||
"Invalid receiver index to set round robin entry.");
|
||||
}
|
||||
auto t = getUdpEntry();
|
||||
det->setDestinationUDPList(t, det_id);
|
||||
os << ToString(args) << std::endl;
|
||||
|
@ -529,7 +529,8 @@ class CmdProxy {
|
||||
|
||||
void Call(const std::string &command,
|
||||
const std::vector<std::string> &arguments, int detector_id = -1,
|
||||
int action = -1, std::ostream &os = std::cout);
|
||||
int action = -1, std::ostream &os = std::cout,
|
||||
int receiver_id = -1);
|
||||
|
||||
bool ReplaceIfDepreciated(std::string &command);
|
||||
size_t GetFunctionMapSize() const noexcept { return functions.size(); };
|
||||
@ -541,6 +542,7 @@ class CmdProxy {
|
||||
std::string cmd;
|
||||
std::vector<std::string> args;
|
||||
int det_id{-1};
|
||||
int rx_id{-1};
|
||||
|
||||
template <typename V> std::string OutStringHex(const V &value) {
|
||||
if (value.equal())
|
||||
@ -859,6 +861,7 @@ class CmdProxy {
|
||||
{"selinterface", &CmdProxy::selinterface},
|
||||
{"udp_dstlist", &CmdProxy::UDPDestinationList},
|
||||
{"udp_numdst", &CmdProxy::udp_numdst},
|
||||
{"udp_cleardst", &CmdProxy::udp_cleardst},
|
||||
{"udp_firstdst", &CmdProxy::udp_firstdst},
|
||||
{"udp_srcip", &CmdProxy::udp_srcip},
|
||||
{"udp_srcip2", &CmdProxy::udp_srcip2},
|
||||
@ -1535,11 +1538,13 @@ class CmdProxy {
|
||||
"[0, 1]\n\t[Jungfrau] The udp interface to stream data from detector. "
|
||||
"Effective only when number of interfaces is 1. Default: 0 (outer)");
|
||||
|
||||
INTEGER_COMMAND_VEC_ID(udp_numdst, getNumberofUDPDestinations,
|
||||
setNumberofUDPDestinations, StringTo<int>,
|
||||
"[1 - 32]\n\t[Jungfrau][Eiger] One can set upto 32 "
|
||||
GET_COMMAND(udp_numdst, getNumberofUDPDestinations,
|
||||
"\n\t[Jungfrau][Eiger] One can enter upto 32 "
|
||||
"destinations that the detector will stream images "
|
||||
"out in a round robin fashion. Default: 1");
|
||||
"out in a round robin fashion. This is get only command. Default: 1");
|
||||
|
||||
EXECUTE_SET_COMMAND(udp_cleardst, clearUDPDestinations,
|
||||
"\n\tClears udp destination details on the detector.");
|
||||
|
||||
INTEGER_COMMAND_VEC_ID(
|
||||
udp_firstdst, getFirstUDPDestination, setFirstUDPDestination,
|
||||
|
@ -17,29 +17,29 @@
|
||||
|
||||
namespace sls {
|
||||
|
||||
void freeSharedMemory(int multiId, int detPos) {
|
||||
// single
|
||||
if (detPos >= 0) {
|
||||
SharedMemory<sharedSlsDetector> temp_shm(multiId, detPos);
|
||||
if (temp_shm.IsExisting()) {
|
||||
temp_shm.RemoveSharedMemory();
|
||||
void freeSharedMemory(int detectorIndex, int moduleIndex) {
|
||||
// single module
|
||||
if (moduleIndex >= 0) {
|
||||
SharedMemory<sharedModule> moduleShm(detectorIndex, moduleIndex);
|
||||
if (moduleShm.IsExisting()) {
|
||||
moduleShm.RemoveSharedMemory();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// multi - get number of detectors from shm
|
||||
SharedMemory<sharedMultiSlsDetector> multiShm(multiId, -1);
|
||||
// detector - multi module - get number of detectors from shm
|
||||
SharedMemory<sharedDetector> detectorShm(detectorIndex, -1);
|
||||
int numDetectors = 0;
|
||||
|
||||
if (multiShm.IsExisting()) {
|
||||
multiShm.OpenSharedMemory();
|
||||
numDetectors = multiShm()->numberOfDetectors;
|
||||
multiShm.RemoveSharedMemory();
|
||||
if (detectorShm.IsExisting()) {
|
||||
detectorShm.OpenSharedMemory();
|
||||
numDetectors = detectorShm()->numberOfModules;
|
||||
detectorShm.RemoveSharedMemory();
|
||||
}
|
||||
|
||||
for (int i = 0; i < numDetectors; ++i) {
|
||||
SharedMemory<sharedSlsDetector> shm(multiId, i);
|
||||
shm.RemoveSharedMemory();
|
||||
SharedMemory<sharedModule> moduleShm(detectorIndex, i);
|
||||
moduleShm.RemoveSharedMemory();
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,7 +101,7 @@ void Detector::setVirtualDetectorServers(int numServers, int startingPort) {
|
||||
pimpl->setVirtualDetectorServers(numServers, startingPort);
|
||||
}
|
||||
|
||||
int Detector::getShmId() const { return pimpl->getMultiId(); }
|
||||
int Detector::getShmId() const { return pimpl->getDetectorIndex(); }
|
||||
|
||||
std::string Detector::getPackageVersion() const { return GITBRANCH; }
|
||||
|
||||
@ -136,7 +136,7 @@ int Detector::size() const { return pimpl->size(); }
|
||||
bool Detector::empty() const { return pimpl->size() == 0; }
|
||||
|
||||
defs::xy Detector::getModuleGeometry() const {
|
||||
return pimpl->getNumberOfDetectors();
|
||||
return pimpl->getNumberOfModules();
|
||||
}
|
||||
|
||||
Result<defs::xy> Detector::getModuleSize(Positions pos) const {
|
||||
@ -256,7 +256,7 @@ void Detector::setSettingsPath(const std::string &value, Positions pos) {
|
||||
}
|
||||
|
||||
void Detector::loadTrimbits(const std::string &fname, Positions pos) {
|
||||
pimpl->Parallel(&Module::loadSettingsFile, pos, fname);
|
||||
pimpl->Parallel(&Module::loadTrimbits, pos, fname);
|
||||
}
|
||||
|
||||
Result<int> Detector::getAllTrimbits(Positions pos) const {
|
||||
@ -921,8 +921,8 @@ Result<int> Detector::getNumberofUDPDestinations(Positions pos) const {
|
||||
return pimpl->Parallel(&Module::getNumberofUDPDestinations, pos);
|
||||
}
|
||||
|
||||
void Detector::setNumberofUDPDestinations(const int value, Positions pos) {
|
||||
pimpl->Parallel(&Module::setNumberofUDPDestinations, pos, value);
|
||||
void Detector::clearUDPDestinations(Positions pos) {
|
||||
pimpl->Parallel(&Module::clearUDPDestinations, pos);
|
||||
}
|
||||
|
||||
Result<int> Detector::getFirstUDPDestination(Positions pos) const {
|
||||
|
@ -28,14 +28,14 @@
|
||||
|
||||
namespace sls {
|
||||
|
||||
DetectorImpl::DetectorImpl(int multi_id, bool verify, bool update)
|
||||
: multiId(multi_id), multi_shm(multi_id, -1) {
|
||||
setupMultiDetector(verify, update);
|
||||
DetectorImpl::DetectorImpl(int detector_index, bool verify, bool update)
|
||||
: detectorIndex(detector_index), shm(detector_index, -1) {
|
||||
setupDetector(verify, update);
|
||||
}
|
||||
|
||||
DetectorImpl::~DetectorImpl() = default;
|
||||
|
||||
void DetectorImpl::setupMultiDetector(bool verify, bool update) {
|
||||
void DetectorImpl::setupDetector(bool verify, bool update) {
|
||||
initSharedMemory(verify);
|
||||
initializeMembers(verify);
|
||||
if (update) {
|
||||
@ -43,104 +43,100 @@ void DetectorImpl::setupMultiDetector(bool verify, bool update) {
|
||||
}
|
||||
}
|
||||
|
||||
void DetectorImpl::setAcquiringFlag(bool flag) {
|
||||
multi_shm()->acquiringFlag = flag;
|
||||
}
|
||||
void DetectorImpl::setAcquiringFlag(bool flag) { shm()->acquiringFlag = flag; }
|
||||
|
||||
int DetectorImpl::getMultiId() const { return multiId; }
|
||||
int DetectorImpl::getDetectorIndex() const { return detectorIndex; }
|
||||
|
||||
void DetectorImpl::freeSharedMemory(int multiId, int detPos) {
|
||||
void DetectorImpl::freeSharedMemory(int detectorIndex, int detPos) {
|
||||
// single
|
||||
if (detPos >= 0) {
|
||||
SharedMemory<sharedSlsDetector> temp_shm(multiId, detPos);
|
||||
if (temp_shm.IsExisting()) {
|
||||
temp_shm.RemoveSharedMemory();
|
||||
SharedMemory<sharedModule> moduleShm(detectorIndex, detPos);
|
||||
if (moduleShm.IsExisting()) {
|
||||
moduleShm.RemoveSharedMemory();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// multi - get number of detectors from shm
|
||||
SharedMemory<sharedMultiSlsDetector> multiShm(multiId, -1);
|
||||
int numDetectors = 0;
|
||||
// multi - get number of modules from shm
|
||||
SharedMemory<sharedDetector> detectorShm(detectorIndex, -1);
|
||||
int numModules = 0;
|
||||
|
||||
if (multiShm.IsExisting()) {
|
||||
multiShm.OpenSharedMemory();
|
||||
numDetectors = multiShm()->numberOfDetectors;
|
||||
multiShm.RemoveSharedMemory();
|
||||
if (detectorShm.IsExisting()) {
|
||||
detectorShm.OpenSharedMemory();
|
||||
numModules = detectorShm()->numberOfModules;
|
||||
detectorShm.RemoveSharedMemory();
|
||||
}
|
||||
|
||||
for (int i = 0; i < numDetectors; ++i) {
|
||||
SharedMemory<sharedSlsDetector> shm(multiId, i);
|
||||
shm.RemoveSharedMemory();
|
||||
for (int i = 0; i < numModules; ++i) {
|
||||
SharedMemory<sharedModule> moduleShm(detectorIndex, i);
|
||||
moduleShm.RemoveSharedMemory();
|
||||
}
|
||||
}
|
||||
|
||||
void DetectorImpl::freeSharedMemory() {
|
||||
zmqSocket.clear();
|
||||
for (auto &d : detectors) {
|
||||
d->freeSharedMemory();
|
||||
for (auto &module : modules) {
|
||||
module->freeSharedMemory();
|
||||
}
|
||||
detectors.clear();
|
||||
modules.clear();
|
||||
|
||||
// clear multi detector shm
|
||||
multi_shm.RemoveSharedMemory();
|
||||
// clear detector shm
|
||||
shm.RemoveSharedMemory();
|
||||
client_downstream = false;
|
||||
}
|
||||
|
||||
std::string DetectorImpl::getUserDetails() {
|
||||
if (detectors.empty()) {
|
||||
if (modules.empty()) {
|
||||
return std::string("none");
|
||||
}
|
||||
|
||||
std::ostringstream sstream;
|
||||
sstream << "\nHostname: ";
|
||||
for (auto &d : detectors) {
|
||||
sstream << (d->isFixedPatternSharedMemoryCompatible() ? d->getHostname()
|
||||
for (auto &module : modules) {
|
||||
sstream << (module->isFixedPatternSharedMemoryCompatible()
|
||||
? module->getHostname()
|
||||
: "Unknown")
|
||||
<< "+";
|
||||
}
|
||||
sstream << "\nType: ";
|
||||
// get type from multi shm
|
||||
if (multi_shm()->shmversion >= MULTI_SHMAPIVERSION) {
|
||||
sstream << ToString(multi_shm()->multiDetectorType);
|
||||
// get type from detector version shm
|
||||
if (shm()->shmversion >= DETECTOR_SHMAPIVERSION) {
|
||||
sstream << ToString(shm()->detType);
|
||||
}
|
||||
// get type from slsdet shm
|
||||
// get type from module shm
|
||||
else {
|
||||
for (auto &d : detectors) {
|
||||
sstream << (d->isFixedPatternSharedMemoryCompatible()
|
||||
? ToString(d->getDetectorType())
|
||||
for (auto &module : modules) {
|
||||
sstream << (module->isFixedPatternSharedMemoryCompatible()
|
||||
? ToString(module->getDetectorType())
|
||||
: "Unknown")
|
||||
<< "+";
|
||||
}
|
||||
}
|
||||
|
||||
sstream << "\nPID: " << multi_shm()->lastPID
|
||||
<< "\nUser: " << multi_shm()->lastUser
|
||||
<< "\nDate: " << multi_shm()->lastDate << std::endl;
|
||||
sstream << "\nPID: " << shm()->lastPID << "\nUser: " << shm()->lastUser
|
||||
<< "\nDate: " << shm()->lastDate << std::endl;
|
||||
|
||||
return sstream.str();
|
||||
}
|
||||
|
||||
bool DetectorImpl::getInitialChecks() const {
|
||||
return multi_shm()->initialChecks;
|
||||
}
|
||||
bool DetectorImpl::getInitialChecks() const { return shm()->initialChecks; }
|
||||
|
||||
void DetectorImpl::setInitialChecks(const bool value) {
|
||||
multi_shm()->initialChecks = value;
|
||||
shm()->initialChecks = value;
|
||||
}
|
||||
|
||||
void DetectorImpl::initSharedMemory(bool verify) {
|
||||
if (!multi_shm.IsExisting()) {
|
||||
multi_shm.CreateSharedMemory();
|
||||
if (!shm.IsExisting()) {
|
||||
shm.CreateSharedMemory();
|
||||
initializeDetectorStructure();
|
||||
} else {
|
||||
multi_shm.OpenSharedMemory();
|
||||
if (verify && multi_shm()->shmversion != MULTI_SHMVERSION) {
|
||||
LOG(logERROR) << "Multi shared memory (" << multiId
|
||||
shm.OpenSharedMemory();
|
||||
if (verify && shm()->shmversion != DETECTOR_SHMVERSION) {
|
||||
LOG(logERROR) << "Detector shared memory (" << detectorIndex
|
||||
<< ") version mismatch "
|
||||
"(expected 0x"
|
||||
<< std::hex << MULTI_SHMVERSION << " but got 0x"
|
||||
<< multi_shm()->shmversion << std::dec
|
||||
<< std::hex << DETECTOR_SHMVERSION << " but got 0x"
|
||||
<< shm()->shmversion << std::dec
|
||||
<< ". Clear Shared memory to continue.";
|
||||
throw SharedMemoryError("Shared memory version mismatch!");
|
||||
}
|
||||
@ -148,18 +144,18 @@ void DetectorImpl::initSharedMemory(bool verify) {
|
||||
}
|
||||
|
||||
void DetectorImpl::initializeDetectorStructure() {
|
||||
multi_shm()->shmversion = MULTI_SHMVERSION;
|
||||
multi_shm()->numberOfDetectors = 0;
|
||||
multi_shm()->multiDetectorType = GENERIC;
|
||||
multi_shm()->numberOfDetector.x = 0;
|
||||
multi_shm()->numberOfDetector.y = 0;
|
||||
multi_shm()->numberOfChannels.x = 0;
|
||||
multi_shm()->numberOfChannels.y = 0;
|
||||
multi_shm()->acquiringFlag = false;
|
||||
multi_shm()->initialChecks = true;
|
||||
multi_shm()->gapPixels = false;
|
||||
shm()->shmversion = DETECTOR_SHMVERSION;
|
||||
shm()->numberOfModules = 0;
|
||||
shm()->detType = GENERIC;
|
||||
shm()->numberOfModule.x = 0;
|
||||
shm()->numberOfModule.y = 0;
|
||||
shm()->numberOfChannels.x = 0;
|
||||
shm()->numberOfChannels.y = 0;
|
||||
shm()->acquiringFlag = false;
|
||||
shm()->initialChecks = true;
|
||||
shm()->gapPixels = false;
|
||||
// zmqlib default
|
||||
multi_shm()->zmqHwm = -1;
|
||||
shm()->zmqHwm = -1;
|
||||
}
|
||||
|
||||
void DetectorImpl::initializeMembers(bool verify) {
|
||||
@ -167,38 +163,39 @@ void DetectorImpl::initializeMembers(bool verify) {
|
||||
zmqSocket.clear();
|
||||
|
||||
// get objects from single det shared memory (open)
|
||||
for (int i = 0; i < multi_shm()->numberOfDetectors; i++) {
|
||||
for (int i = 0; i < shm()->numberOfModules; i++) {
|
||||
try {
|
||||
detectors.push_back(sls::make_unique<Module>(multiId, i, verify));
|
||||
modules.push_back(
|
||||
sls::make_unique<Module>(detectorIndex, i, verify));
|
||||
} catch (...) {
|
||||
detectors.clear();
|
||||
modules.clear();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DetectorImpl::updateUserdetails() {
|
||||
multi_shm()->lastPID = getpid();
|
||||
memset(multi_shm()->lastUser, 0, sizeof(multi_shm()->lastUser));
|
||||
memset(multi_shm()->lastDate, 0, sizeof(multi_shm()->lastDate));
|
||||
shm()->lastPID = getpid();
|
||||
memset(shm()->lastUser, 0, sizeof(shm()->lastUser));
|
||||
memset(shm()->lastDate, 0, sizeof(shm()->lastDate));
|
||||
try {
|
||||
sls::strcpy_safe(multi_shm()->lastUser, exec("whoami").c_str());
|
||||
sls::strcpy_safe(multi_shm()->lastDate, exec("date").c_str());
|
||||
sls::strcpy_safe(shm()->lastUser, exec("whoami").c_str());
|
||||
sls::strcpy_safe(shm()->lastDate, exec("date").c_str());
|
||||
} catch (...) {
|
||||
sls::strcpy_safe(multi_shm()->lastUser, "errorreading");
|
||||
sls::strcpy_safe(multi_shm()->lastDate, "errorreading");
|
||||
sls::strcpy_safe(shm()->lastUser, "errorreading");
|
||||
sls::strcpy_safe(shm()->lastDate, "errorreading");
|
||||
}
|
||||
}
|
||||
|
||||
bool DetectorImpl::isAcquireReady() {
|
||||
if (multi_shm()->acquiringFlag) {
|
||||
if (shm()->acquiringFlag) {
|
||||
LOG(logWARNING)
|
||||
<< "Acquire has already started. "
|
||||
"If previous acquisition terminated unexpectedly, "
|
||||
"reset busy flag to restart.(sls_detector_put clearbusy)";
|
||||
return false;
|
||||
}
|
||||
multi_shm()->acquiringFlag = true;
|
||||
shm()->acquiringFlag = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -233,22 +230,22 @@ void DetectorImpl::setVirtualDetectorServers(const int numdet, const int port) {
|
||||
|
||||
void DetectorImpl::setHostname(const std::vector<std::string> &name) {
|
||||
// this check is there only to allow the previous detsizechan command
|
||||
if (multi_shm()->numberOfDetectors != 0) {
|
||||
LOG(logWARNING) << "There are already detector(s) in shared memory."
|
||||
if (shm()->numberOfModules != 0) {
|
||||
LOG(logWARNING) << "There are already module(s) in shared memory."
|
||||
"Freeing Shared memory now.";
|
||||
bool initialChecks = multi_shm()->initialChecks;
|
||||
bool initialChecks = shm()->initialChecks;
|
||||
freeSharedMemory();
|
||||
setupMultiDetector();
|
||||
multi_shm()->initialChecks = initialChecks;
|
||||
setupDetector();
|
||||
shm()->initialChecks = initialChecks;
|
||||
}
|
||||
for (const auto &hostname : name) {
|
||||
addSlsDetector(hostname);
|
||||
addModule(hostname);
|
||||
}
|
||||
updateDetectorSize();
|
||||
}
|
||||
|
||||
void DetectorImpl::addSlsDetector(const std::string &hostname) {
|
||||
LOG(logINFO) << "Adding detector " << hostname;
|
||||
void DetectorImpl::addModule(const std::string &hostname) {
|
||||
LOG(logINFO) << "Adding module " << hostname;
|
||||
|
||||
int port = DEFAULT_PORTNO;
|
||||
std::string host = hostname;
|
||||
@ -259,11 +256,11 @@ void DetectorImpl::addSlsDetector(const std::string &hostname) {
|
||||
}
|
||||
|
||||
if (host != "localhost") {
|
||||
for (auto &d : detectors) {
|
||||
if (d->getHostname() == host) {
|
||||
for (auto &module : modules) {
|
||||
if (module->getHostname() == host) {
|
||||
LOG(logWARNING)
|
||||
<< "Detector " << host
|
||||
<< "already part of the multiDetector!" << std::endl
|
||||
<< "Module " << host << "already part of the Detector!"
|
||||
<< std::endl
|
||||
<< "Remove it before adding it back in a new position!";
|
||||
return;
|
||||
}
|
||||
@ -272,33 +269,33 @@ void DetectorImpl::addSlsDetector(const std::string &hostname) {
|
||||
|
||||
// get type by connecting
|
||||
detectorType type = Module::getTypeFromDetector(host, port);
|
||||
auto pos = detectors.size();
|
||||
detectors.emplace_back(sls::make_unique<Module>(type, multiId, pos, false));
|
||||
multi_shm()->numberOfDetectors = detectors.size();
|
||||
detectors[pos]->setControlPort(port);
|
||||
detectors[pos]->setStopPort(port + 1);
|
||||
detectors[pos]->setHostname(host, multi_shm()->initialChecks);
|
||||
// detector type updated by now
|
||||
multi_shm()->multiDetectorType =
|
||||
Parallel(&Module::getDetectorType, {})
|
||||
auto pos = modules.size();
|
||||
modules.emplace_back(
|
||||
sls::make_unique<Module>(type, detectorIndex, pos, false));
|
||||
shm()->numberOfModules = modules.size();
|
||||
modules[pos]->setControlPort(port);
|
||||
modules[pos]->setStopPort(port + 1);
|
||||
modules[pos]->setHostname(host, shm()->initialChecks);
|
||||
// module type updated by now
|
||||
shm()->detType = Parallel(&Module::getDetectorType, {})
|
||||
.tsquash("Inconsistent detector types.");
|
||||
// for moench and ctb
|
||||
detectors[pos]->updateNumberOfChannels();
|
||||
modules[pos]->updateNumberOfChannels();
|
||||
}
|
||||
|
||||
void DetectorImpl::updateDetectorSize() {
|
||||
LOG(logDEBUG) << "Updating Multi-Detector Size: " << size();
|
||||
LOG(logDEBUG) << "Updating Detector Size: " << size();
|
||||
|
||||
const slsDetectorDefs::xy det_size = detectors[0]->getNumberOfChannels();
|
||||
const slsDetectorDefs::xy det_size = modules[0]->getNumberOfChannels();
|
||||
|
||||
if (det_size.x == 0 || det_size.y == 0) {
|
||||
throw sls::RuntimeError("Module size for x or y dimensions is 0. Unable to proceed in updating detector size. ");
|
||||
}
|
||||
|
||||
int maxx = multi_shm()->numberOfChannels.x;
|
||||
int maxy = multi_shm()->numberOfChannels.y;
|
||||
int maxx = shm()->numberOfChannels.x;
|
||||
int maxy = shm()->numberOfChannels.y;
|
||||
int ndetx = 0, ndety = 0;
|
||||
// 1d, add detectors along x axis
|
||||
// 1d, add modules along x axis
|
||||
if (det_size.y == 1) {
|
||||
if (maxx == 0) {
|
||||
maxx = det_size.x * size();
|
||||
@ -309,7 +306,7 @@ void DetectorImpl::updateDetectorSize() {
|
||||
++ndety;
|
||||
}
|
||||
}
|
||||
// 2d, add detectors along y axis (due to eiger top/bottom)
|
||||
// 2d, add modules along y axis (due to eiger top/bottom)
|
||||
else {
|
||||
if (maxy == 0) {
|
||||
maxy = det_size.y * size();
|
||||
@ -321,33 +318,33 @@ void DetectorImpl::updateDetectorSize() {
|
||||
}
|
||||
}
|
||||
|
||||
multi_shm()->numberOfDetector.x = ndetx;
|
||||
multi_shm()->numberOfDetector.y = ndety;
|
||||
multi_shm()->numberOfChannels.x = det_size.x * ndetx;
|
||||
multi_shm()->numberOfChannels.y = det_size.y * ndety;
|
||||
shm()->numberOfModule.x = ndetx;
|
||||
shm()->numberOfModule.y = ndety;
|
||||
shm()->numberOfChannels.x = det_size.x * ndetx;
|
||||
shm()->numberOfChannels.y = det_size.y * ndety;
|
||||
|
||||
LOG(logDEBUG) << "\n\tNumber of Detectors in X direction:"
|
||||
<< multi_shm()->numberOfDetector.x
|
||||
<< "\n\tNumber of Detectors in Y direction:"
|
||||
<< multi_shm()->numberOfDetector.y
|
||||
LOG(logDEBUG) << "\n\tNumber of Modules in X direction:"
|
||||
<< shm()->numberOfModule.x
|
||||
<< "\n\tNumber of Modules in Y direction:"
|
||||
<< shm()->numberOfModule.y
|
||||
<< "\n\tNumber of Channels in X direction:"
|
||||
<< multi_shm()->numberOfChannels.x
|
||||
<< shm()->numberOfChannels.x
|
||||
<< "\n\tNumber of Channels in Y direction:"
|
||||
<< multi_shm()->numberOfChannels.y;
|
||||
<< shm()->numberOfChannels.y;
|
||||
|
||||
for (auto &d : detectors) {
|
||||
d->updateNumberOfDetector(multi_shm()->numberOfDetector);
|
||||
for (auto &module : modules) {
|
||||
module->updateNumberOfModule(shm()->numberOfModule);
|
||||
}
|
||||
}
|
||||
|
||||
int DetectorImpl::size() const { return detectors.size(); }
|
||||
int DetectorImpl::size() const { return modules.size(); }
|
||||
|
||||
slsDetectorDefs::xy DetectorImpl::getNumberOfDetectors() const {
|
||||
return multi_shm()->numberOfDetector;
|
||||
slsDetectorDefs::xy DetectorImpl::getNumberOfModules() const {
|
||||
return shm()->numberOfModule;
|
||||
}
|
||||
|
||||
slsDetectorDefs::xy DetectorImpl::getNumberOfChannels() const {
|
||||
return multi_shm()->numberOfChannels;
|
||||
return shm()->numberOfChannels;
|
||||
}
|
||||
|
||||
void DetectorImpl::setNumberOfChannels(const slsDetectorDefs::xy c) {
|
||||
@ -355,33 +352,31 @@ void DetectorImpl::setNumberOfChannels(const slsDetectorDefs::xy c) {
|
||||
throw RuntimeError(
|
||||
"Set the number of channels before setting hostname.");
|
||||
}
|
||||
multi_shm()->numberOfChannels = c;
|
||||
shm()->numberOfChannels = c;
|
||||
}
|
||||
|
||||
bool DetectorImpl::getGapPixelsinCallback() const {
|
||||
return multi_shm()->gapPixels;
|
||||
}
|
||||
bool DetectorImpl::getGapPixelsinCallback() const { return shm()->gapPixels; }
|
||||
|
||||
void DetectorImpl::setGapPixelsinCallback(const bool enable) {
|
||||
if (enable) {
|
||||
switch (multi_shm()->multiDetectorType) {
|
||||
switch (shm()->detType) {
|
||||
case JUNGFRAU:
|
||||
break;
|
||||
case EIGER:
|
||||
if (size() && detectors[0]->getQuad()) {
|
||||
if (size() && modules[0]->getQuad()) {
|
||||
break;
|
||||
}
|
||||
if (multi_shm()->numberOfDetector.y % 2 != 0) {
|
||||
if (shm()->numberOfModule.y % 2 != 0) {
|
||||
throw RuntimeError("Gap pixels can only be used "
|
||||
"for full modules.");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw RuntimeError("Gap Pixels is not implemented for " +
|
||||
ToString(multi_shm()->multiDetectorType));
|
||||
ToString(shm()->detType));
|
||||
}
|
||||
}
|
||||
multi_shm()->gapPixels = enable;
|
||||
shm()->gapPixels = enable;
|
||||
}
|
||||
|
||||
int DetectorImpl::destroyReceivingDataSockets() {
|
||||
@ -400,33 +395,33 @@ int DetectorImpl::createReceivingDataSockets() {
|
||||
}
|
||||
LOG(logINFO) << "Going to create data sockets";
|
||||
|
||||
size_t numSockets = detectors.size();
|
||||
size_t numSocketsPerDetector = 1;
|
||||
if (multi_shm()->multiDetectorType == EIGER) {
|
||||
numSocketsPerDetector = 2;
|
||||
size_t numSockets = modules.size();
|
||||
size_t numSocketsPerModule = 1;
|
||||
if (shm()->detType == EIGER) {
|
||||
numSocketsPerModule = 2;
|
||||
}
|
||||
// gotthard2 second interface is only for veto debugging
|
||||
else if (multi_shm()->multiDetectorType != GOTTHARD2) {
|
||||
else if (shm()->detType != GOTTHARD2) {
|
||||
if (Parallel(&Module::getNumberofUDPInterfacesFromShm, {}).squash() ==
|
||||
2) {
|
||||
numSocketsPerDetector = 2;
|
||||
numSocketsPerModule = 2;
|
||||
}
|
||||
}
|
||||
numSockets *= numSocketsPerDetector;
|
||||
numSockets *= numSocketsPerModule;
|
||||
|
||||
for (size_t iSocket = 0; iSocket < numSockets; ++iSocket) {
|
||||
uint32_t portnum = (detectors[iSocket / numSocketsPerDetector]
|
||||
->getClientStreamingPort());
|
||||
portnum += (iSocket % numSocketsPerDetector);
|
||||
uint32_t portnum =
|
||||
(modules[iSocket / numSocketsPerModule]->getClientStreamingPort());
|
||||
portnum += (iSocket % numSocketsPerModule);
|
||||
try {
|
||||
zmqSocket.push_back(sls::make_unique<ZmqSocket>(
|
||||
detectors[iSocket / numSocketsPerDetector]
|
||||
modules[iSocket / numSocketsPerModule]
|
||||
->getClientStreamingIP()
|
||||
.str()
|
||||
.c_str(),
|
||||
portnum));
|
||||
// set high water mark
|
||||
int hwm = multi_shm()->zmqHwm;
|
||||
int hwm = shm()->zmqHwm;
|
||||
if (hwm >= 0) {
|
||||
zmqSocket[iSocket]->SetReceiveHighWaterMark(hwm);
|
||||
if (zmqSocket[iSocket]->GetReceiveHighWaterMark() != hwm) {
|
||||
@ -451,7 +446,7 @@ int DetectorImpl::createReceivingDataSockets() {
|
||||
|
||||
void DetectorImpl::readFrameFromReceiver() {
|
||||
|
||||
bool gapPixels = multi_shm()->gapPixels;
|
||||
bool gapPixels = shm()->gapPixels;
|
||||
LOG(logDEBUG) << "Gap pixels: " << gapPixels;
|
||||
int nX = 0;
|
||||
int nY = 0;
|
||||
@ -461,7 +456,7 @@ void DetectorImpl::readFrameFromReceiver() {
|
||||
bool eiger = false;
|
||||
bool numInterfaces = 1;
|
||||
// gotthard2 second interface is veto debugging
|
||||
if (multi_shm()->multiDetectorType != GOTTHARD2) {
|
||||
if (shm()->detType != GOTTHARD2) {
|
||||
numInterfaces = Parallel(&Module::getNumberofUDPInterfacesFromShm, {})
|
||||
.squash(); // cannot pick up from zmq
|
||||
}
|
||||
@ -540,7 +535,7 @@ void DetectorImpl::readFrameFromReceiver() {
|
||||
// shape
|
||||
nPixelsX = zHeader.npixelsx;
|
||||
nPixelsY = zHeader.npixelsy;
|
||||
// detector shape
|
||||
// module shape
|
||||
nX = zHeader.ndetx;
|
||||
nY = zHeader.ndety;
|
||||
nY *= numInterfaces;
|
||||
@ -603,7 +598,7 @@ void DetectorImpl::readFrameFromReceiver() {
|
||||
uint32_t yoffset = coordY * nPixelsY;
|
||||
uint32_t singledetrowoffset = nPixelsX * bytesPerPixel;
|
||||
uint32_t rowoffset = nX * singledetrowoffset;
|
||||
if (multi_shm()->multiDetectorType == CHIPTESTBOARD) {
|
||||
if (shm()->detType == CHIPTESTBOARD) {
|
||||
singledetrowoffset = size;
|
||||
}
|
||||
LOG(logDEBUG1)
|
||||
@ -765,7 +760,7 @@ int DetectorImpl::InsertGapPixels(char *image, char *&gpImage, bool quadEnable,
|
||||
// eiger requires inter chip gap pixels are halved
|
||||
// jungfrau prefers same inter chip gap pixels as the boundary pixels
|
||||
int divisionValue = 2;
|
||||
slsDetectorDefs::detectorType detType = multi_shm()->multiDetectorType;
|
||||
slsDetectorDefs::detectorType detType = shm()->detType;
|
||||
if (detType == JUNGFRAU) {
|
||||
divisionValue = 1;
|
||||
}
|
||||
@ -1001,7 +996,7 @@ void DetectorImpl::setDataStreamingToClient(bool enable) {
|
||||
int DetectorImpl::getClientStreamingHwm() const {
|
||||
// disabled
|
||||
if (!client_downstream) {
|
||||
return multi_shm()->zmqHwm;
|
||||
return shm()->zmqHwm;
|
||||
}
|
||||
// enabled
|
||||
sls::Result<int> result;
|
||||
@ -1019,7 +1014,7 @@ void DetectorImpl::setClientStreamingHwm(const int limit) {
|
||||
"Cannot set hwm to less than -1 (-1 is lib default).");
|
||||
}
|
||||
// update shm
|
||||
multi_shm()->zmqHwm = limit;
|
||||
shm()->zmqHwm = limit;
|
||||
|
||||
// streaming enabled
|
||||
if (client_downstream) {
|
||||
@ -1028,7 +1023,7 @@ void DetectorImpl::setClientStreamingHwm(const int limit) {
|
||||
for (auto &it : zmqSocket) {
|
||||
it->SetReceiveHighWaterMark(limit);
|
||||
if (it->GetReceiveHighWaterMark() != limit) {
|
||||
multi_shm()->zmqHwm = -1;
|
||||
shm()->zmqHwm = -1;
|
||||
throw sls::ZmqSocketError("Could not set zmq rcv hwm to " +
|
||||
std::to_string(limit));
|
||||
}
|
||||
@ -1096,13 +1091,13 @@ int DetectorImpl::acquire() {
|
||||
|
||||
// start and read all
|
||||
try {
|
||||
if(detector_type == defs::MYTHEN3 && detectors.size() > 1){
|
||||
if (detector_type == defs::MYTHEN3 && modules.size() > 1) {
|
||||
//Multi module mythen
|
||||
std::vector<int> master;
|
||||
std::vector<int> slaves;
|
||||
auto is_master = Parallel(&Module::isMaster, {});
|
||||
slaves.reserve(detectors.size()-1); //check this one!!
|
||||
for (size_t i = 0; i<detectors.size(); ++i){
|
||||
slaves.reserve(modules.size() - 1); // check this one!!
|
||||
for (size_t i = 0; i < modules.size(); ++i) {
|
||||
if(is_master[i])
|
||||
master.push_back(i);
|
||||
else
|
||||
@ -1243,7 +1238,7 @@ int DetectorImpl::kbhit() {
|
||||
std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
|
||||
// validate type of file
|
||||
bool isPof = false;
|
||||
switch (multi_shm()->multiDetectorType) {
|
||||
switch (shm()->detType) {
|
||||
case JUNGFRAU:
|
||||
case CHIPTESTBOARD:
|
||||
case MOENCH:
|
||||
@ -1266,7 +1261,6 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
|
||||
<< "Updating Firmware. This can take awhile. Please be patient...";
|
||||
LOG(logDEBUG1) << "Programming FPGA with file name:" << fname;
|
||||
|
||||
size_t filesize = 0;
|
||||
// check if it exists
|
||||
struct stat st;
|
||||
if (stat(fname.c_str(), &st) != 0) {
|
||||
@ -1281,6 +1275,16 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
|
||||
fname);
|
||||
}
|
||||
|
||||
// get srcSize to print progress
|
||||
if (fseek(src, 0, SEEK_END) != 0) {
|
||||
throw RuntimeError("Program FPGA: Seek error in src file");
|
||||
}
|
||||
size_t srcSize = ftell(src);
|
||||
if (srcSize <= 0) {
|
||||
throw RuntimeError("Program FPGA: Could not get length of source file");
|
||||
}
|
||||
rewind(src);
|
||||
|
||||
// create temp destination file
|
||||
char destfname[] = "/tmp/SLS_DET_MCB.XXXXXX";
|
||||
int dst = mkstemp(destfname); // create temporary file and open it in r/w
|
||||
@ -1294,6 +1298,7 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
|
||||
|
||||
// convert src to dst rawbin
|
||||
LOG(logDEBUG1) << "Converting " << fname << " to " << destfname;
|
||||
LOG(logINFO) << "Converting program to rawbin";
|
||||
{
|
||||
constexpr int pofNumHeaderBytes = 0x11C;
|
||||
constexpr int pofFooterOfst = 0x1000000;
|
||||
@ -1312,7 +1317,15 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
|
||||
}
|
||||
}
|
||||
// Swap bits from source and write to dest
|
||||
int oldProgress = 0;
|
||||
while (!feof(src)) {
|
||||
// print progress
|
||||
int progress = (int)(((double)(dstFilePos) / srcSize) * 100);
|
||||
if (oldProgress != progress) {
|
||||
printf("%d%%\r", progress);
|
||||
fflush(stdout);
|
||||
oldProgress = progress;
|
||||
}
|
||||
// pof: exit early to discard footer
|
||||
if (isPof && dstFilePos >= pofFooterOfst) {
|
||||
break;
|
||||
@ -1342,9 +1355,10 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
|
||||
if (close(dst) != 0) {
|
||||
throw RuntimeError("Program FPGA: Could not close destination file");
|
||||
}
|
||||
LOG(logDEBUG1) << "File has been converted to " << destfname;
|
||||
LOG(logINFOBLUE) << "File has been converted to " << destfname;
|
||||
|
||||
// loading dst file to memory
|
||||
// FILE *fp = fopen("/tmp/SLS_DET_MCB.tzgmUT", "r");
|
||||
FILE *fp = fopen(destfname, "r");
|
||||
if (fp == nullptr) {
|
||||
throw RuntimeError("Program FPGA: Could not open rawbin file");
|
||||
@ -1352,7 +1366,7 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
|
||||
if (fseek(fp, 0, SEEK_END) != 0) {
|
||||
throw RuntimeError("Program FPGA: Seek error in rawbin file");
|
||||
}
|
||||
filesize = ftell(fp);
|
||||
size_t filesize = ftell(fp);
|
||||
if (filesize <= 0) {
|
||||
throw RuntimeError("Program FPGA: Could not get length of rawbin file");
|
||||
}
|
||||
@ -1367,9 +1381,10 @@ std::vector<char> DetectorImpl::readProgrammingFile(const std::string &fname) {
|
||||
throw RuntimeError(
|
||||
"Program FPGA: Could not close destination file after converting");
|
||||
}
|
||||
unlink(destfname); // delete temporary file
|
||||
|
||||
//unlink(destfname); // delete temporary file
|
||||
LOG(logDEBUG1) << "Successfully loaded the rawbin file to program memory";
|
||||
LOG(logINFO) << "Read file into memory";
|
||||
LOG(logDEBUG1) << "Read file into memory";
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
@ -15,8 +15,8 @@ class detectorData;
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#define MULTI_SHMAPIVERSION 0x190809
|
||||
#define MULTI_SHMVERSION 0x201007
|
||||
#define DETECTOR_SHMAPIVERSION 0x190809
|
||||
#define DETECTOR_SHMVERSION 0x201007
|
||||
#define SHORT_STRING_LENGTH 50
|
||||
|
||||
#include <future>
|
||||
@ -30,7 +30,7 @@ class Module;
|
||||
* @short structure allocated in shared memory to store detector settings
|
||||
* for IPC and cache
|
||||
*/
|
||||
struct sharedMultiSlsDetector {
|
||||
struct sharedDetector {
|
||||
|
||||
/* FIXED PATTERN FOR STATIC FUNCTIONS. DO NOT CHANGE, ONLY APPEND
|
||||
* ------*/
|
||||
@ -47,14 +47,14 @@ struct sharedMultiSlsDetector {
|
||||
/** last time stamp when accessing the shared memory */
|
||||
char lastDate[SHORT_STRING_LENGTH];
|
||||
|
||||
int numberOfDetectors;
|
||||
slsDetectorDefs::detectorType multiDetectorType;
|
||||
int numberOfModules;
|
||||
slsDetectorDefs::detectorType detType;
|
||||
|
||||
/** END OF FIXED PATTERN
|
||||
* -----------------------------------------------*/
|
||||
|
||||
/** Number of detectors operated at once */
|
||||
slsDetectorDefs::xy numberOfDetector;
|
||||
/** Number of modules operated at once */
|
||||
slsDetectorDefs::xy numberOfModule;
|
||||
|
||||
/** max number of channels for complete detector*/
|
||||
slsDetectorDefs::xy numberOfChannels;
|
||||
@ -69,13 +69,11 @@ struct sharedMultiSlsDetector {
|
||||
class DetectorImpl : public virtual slsDetectorDefs {
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
* @param multi_id multi detector id
|
||||
* @param verify true to verify if shared memory version matches existing
|
||||
* one
|
||||
* @param update true to update last user pid, date etc
|
||||
*/
|
||||
explicit DetectorImpl(int multi_id = 0, bool verify = true,
|
||||
explicit DetectorImpl(int detector_index = 0, bool verify = true,
|
||||
bool update = true);
|
||||
|
||||
/**
|
||||
@ -89,20 +87,20 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
std::vector<int> positions,
|
||||
typename NonDeduced<CT>::type... Args) {
|
||||
|
||||
if (detectors.empty())
|
||||
throw sls::RuntimeError("No detectors added");
|
||||
if (modules.empty())
|
||||
throw sls::RuntimeError("No modules added");
|
||||
if (positions.empty() ||
|
||||
(positions.size() == 1 && positions[0] == -1)) {
|
||||
positions.resize(detectors.size());
|
||||
positions.resize(modules.size());
|
||||
std::iota(begin(positions), end(positions), 0);
|
||||
}
|
||||
std::vector<std::future<RT>> futures;
|
||||
futures.reserve(positions.size());
|
||||
for (size_t i : positions) {
|
||||
if (i >= detectors.size())
|
||||
throw sls::RuntimeError("Detector out of range");
|
||||
if (i >= modules.size())
|
||||
throw sls::RuntimeError("Module out of range");
|
||||
futures.push_back(std::async(std::launch::async, somefunc,
|
||||
detectors[i].get(), Args...));
|
||||
modules[i].get(), Args...));
|
||||
}
|
||||
sls::Result<RT> result;
|
||||
result.reserve(positions.size());
|
||||
@ -117,20 +115,20 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
std::vector<int> positions,
|
||||
typename NonDeduced<CT>::type... Args) const {
|
||||
|
||||
if (detectors.empty())
|
||||
throw sls::RuntimeError("No detectors added");
|
||||
if (modules.empty())
|
||||
throw sls::RuntimeError("No modules added");
|
||||
if (positions.empty() ||
|
||||
(positions.size() == 1 && positions[0] == -1)) {
|
||||
positions.resize(detectors.size());
|
||||
positions.resize(modules.size());
|
||||
std::iota(begin(positions), end(positions), 0);
|
||||
}
|
||||
std::vector<std::future<RT>> futures;
|
||||
futures.reserve(positions.size());
|
||||
for (size_t i : positions) {
|
||||
if (i >= detectors.size())
|
||||
throw sls::RuntimeError("Detector out of range");
|
||||
if (i >= modules.size())
|
||||
throw sls::RuntimeError("Module out of range");
|
||||
futures.push_back(std::async(std::launch::async, somefunc,
|
||||
detectors[i].get(), Args...));
|
||||
modules[i].get(), Args...));
|
||||
}
|
||||
sls::Result<RT> result;
|
||||
result.reserve(positions.size());
|
||||
@ -145,20 +143,20 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
std::vector<int> positions,
|
||||
typename NonDeduced<CT>::type... Args) {
|
||||
|
||||
if (detectors.empty())
|
||||
throw sls::RuntimeError("No detectors added");
|
||||
if (modules.empty())
|
||||
throw sls::RuntimeError("No modules added");
|
||||
if (positions.empty() ||
|
||||
(positions.size() == 1 && positions[0] == -1)) {
|
||||
positions.resize(detectors.size());
|
||||
positions.resize(modules.size());
|
||||
std::iota(begin(positions), end(positions), 0);
|
||||
}
|
||||
std::vector<std::future<void>> futures;
|
||||
futures.reserve(positions.size());
|
||||
for (size_t i : positions) {
|
||||
if (i >= detectors.size())
|
||||
throw sls::RuntimeError("Detector out of range");
|
||||
if (i >= modules.size())
|
||||
throw sls::RuntimeError("Module out of range");
|
||||
futures.push_back(std::async(std::launch::async, somefunc,
|
||||
detectors[i].get(), Args...));
|
||||
modules[i].get(), Args...));
|
||||
}
|
||||
for (auto &i : futures) {
|
||||
i.get();
|
||||
@ -170,20 +168,20 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
std::vector<int> positions,
|
||||
typename NonDeduced<CT>::type... Args) const {
|
||||
|
||||
if (detectors.empty())
|
||||
throw sls::RuntimeError("No detectors added");
|
||||
if (modules.empty())
|
||||
throw sls::RuntimeError("No modules added");
|
||||
if (positions.empty() ||
|
||||
(positions.size() == 1 && positions[0] == -1)) {
|
||||
positions.resize(detectors.size());
|
||||
positions.resize(modules.size());
|
||||
std::iota(begin(positions), end(positions), 0);
|
||||
}
|
||||
std::vector<std::future<void>> futures;
|
||||
futures.reserve(positions.size());
|
||||
for (size_t i : positions) {
|
||||
if (i >= detectors.size())
|
||||
throw sls::RuntimeError("Detector out of range");
|
||||
if (i >= modules.size())
|
||||
throw sls::RuntimeError("Module out of range");
|
||||
futures.push_back(std::async(std::launch::async, somefunc,
|
||||
detectors[i].get(), Args...));
|
||||
modules[i].get(), Args...));
|
||||
}
|
||||
for (auto &i : futures) {
|
||||
i.get();
|
||||
@ -193,12 +191,12 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
/** set acquiring flag in shared memory */
|
||||
void setAcquiringFlag(bool flag);
|
||||
|
||||
/** return multi detector shared memory ID */
|
||||
int getMultiId() const;
|
||||
/** return detector index in shared memory */
|
||||
int getDetectorIndex() const;
|
||||
|
||||
/** Free specific shared memory from the command line without creating
|
||||
* object */
|
||||
static void freeSharedMemory(int multiId, int detPos = -1);
|
||||
static void freeSharedMemory(int detectorIndex, int detPos = -1);
|
||||
|
||||
/** Free all modules from current multi Id shared memory and delete members
|
||||
*/
|
||||
@ -215,24 +213,24 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
|
||||
/**
|
||||
* Connect to Virtual Detector Servers at local host
|
||||
* @param numdet number of detectors
|
||||
* @param numdet number of modules
|
||||
* @param port starting port number
|
||||
*/
|
||||
void setVirtualDetectorServers(const int numdet, const int port);
|
||||
|
||||
/** Sets the hostname of all sls detectors in shared memory and updates
|
||||
/** Sets the hostname of all sls modules in shared memory and updates
|
||||
* local cache */
|
||||
void setHostname(const std::vector<std::string> &name);
|
||||
|
||||
/** Gets the total number of detectors */
|
||||
/** Gets the total number of modules */
|
||||
int size() const;
|
||||
|
||||
slsDetectorDefs::xy getNumberOfDetectors() const;
|
||||
slsDetectorDefs::xy getNumberOfModules() const;
|
||||
|
||||
slsDetectorDefs::xy getNumberOfChannels() const;
|
||||
|
||||
/** Must be set before setting hostname
|
||||
* Sets maximum number of channels of all sls detectors */
|
||||
* Sets maximum number of channels of all sls modules */
|
||||
void setNumberOfChannels(const slsDetectorDefs::xy c);
|
||||
|
||||
/** [Eiger][Jungfrau] */
|
||||
@ -248,14 +246,14 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
/**
|
||||
* register callback for accessing acquisition final data
|
||||
* @param func function to be called at the end of the acquisition.
|
||||
* gets detector status and progress index as arguments
|
||||
* gets module status and progress index as arguments
|
||||
* @param pArg argument
|
||||
*/
|
||||
void registerAcquisitionFinishedCallback(void (*func)(double, int, void *),
|
||||
void *pArg);
|
||||
|
||||
/**
|
||||
* register calbback for accessing detector final data,
|
||||
* register calbback for accessing module final data,
|
||||
* also enables data streaming in client and receiver
|
||||
* @param userCallback function for plotting/analyzing the data.
|
||||
* Its arguments are
|
||||
@ -307,7 +305,7 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
* one
|
||||
* @param update true to update last user pid, date etc
|
||||
*/
|
||||
void setupMultiDetector(bool verify = true, bool update = true);
|
||||
void setupDetector(bool verify = true, bool update = true);
|
||||
|
||||
/**
|
||||
* Creates shm and initializes shm structure OR
|
||||
@ -319,7 +317,7 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
/** Initialize detector structure for the shared memory just created */
|
||||
void initializeDetectorStructure();
|
||||
|
||||
/** Initialize members (eg. slsDetectors from shm, zmqsockets)
|
||||
/** Initialize members (eg. modules from shm, zmqsockets)
|
||||
* @param verify true to verify if shm size matches existing one
|
||||
*/
|
||||
void initializeMembers(bool verify = true);
|
||||
@ -332,7 +330,7 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
/** Execute command in terminal and return result */
|
||||
std::string exec(const char *cmd);
|
||||
|
||||
void addSlsDetector(const std::string &hostname);
|
||||
void addModule(const std::string &hostname);
|
||||
|
||||
void updateDetectorSize();
|
||||
|
||||
@ -380,22 +378,13 @@ class DetectorImpl : public virtual slsDetectorDefs {
|
||||
*/
|
||||
int kbhit();
|
||||
|
||||
/** Multi detector Id */
|
||||
const int multiId{0};
|
||||
|
||||
/** Shared Memory object */
|
||||
sls::SharedMemory<sharedMultiSlsDetector> multi_shm{0, -1};
|
||||
|
||||
/** pointers to the Module structures */
|
||||
std::vector<std::unique_ptr<sls::Module>> detectors;
|
||||
const int detectorIndex{0};
|
||||
sls::SharedMemory<sharedDetector> shm{0, -1};
|
||||
std::vector<std::unique_ptr<sls::Module>> modules;
|
||||
|
||||
/** data streaming (down stream) enabled in client (zmq sckets created) */
|
||||
bool client_downstream{false};
|
||||
|
||||
/** ZMQ Socket - Receiver to Client */
|
||||
std::vector<std::unique_ptr<ZmqSocket>> zmqSocket;
|
||||
|
||||
/** number of zmq sockets running currently */
|
||||
volatile int numZmqRunning{0};
|
||||
|
||||
/** mutex to synchronize main and data processing threads */
|
||||
|
@ -5,11 +5,13 @@
|
||||
#include "sls/bit_utils.h"
|
||||
#include "sls/container_utils.h"
|
||||
#include "sls/file_utils.h"
|
||||
#include "sls/md5_helper.h"
|
||||
#include "sls/network_utils.h"
|
||||
#include "sls/sls_detector_exceptions.h"
|
||||
#include "sls/sls_detector_funcs.h"
|
||||
#include "sls/string_utils.h"
|
||||
#include "sls/versionAPI.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <bitset>
|
||||
@ -57,7 +59,7 @@ void Module::freeSharedMemory() {
|
||||
}
|
||||
|
||||
bool Module::isFixedPatternSharedMemoryCompatible() const {
|
||||
return (shm()->shmversion >= SLS_SHMAPIVERSION);
|
||||
return (shm()->shmversion >= MODULE_SHMAPIVERSION);
|
||||
}
|
||||
|
||||
std::string Module::getHostname() const { return shm()->hostname; }
|
||||
@ -69,7 +71,7 @@ void Module::setHostname(const std::string &hostname,
|
||||
client.close();
|
||||
try {
|
||||
checkDetectorVersionCompatibility();
|
||||
LOG(logINFO) << "Detector Version Compatibility - Success";
|
||||
LOG(logINFO) << "Module Version Compatibility - Success";
|
||||
} catch (const DetectorError &e) {
|
||||
if (!initialChecks) {
|
||||
LOG(logWARNING) << "Bypassing Initial Checks at your own risk!";
|
||||
@ -77,7 +79,7 @@ void Module::setHostname(const std::string &hostname,
|
||||
throw;
|
||||
}
|
||||
}
|
||||
if (shm()->myDetectorType == EIGER) {
|
||||
if (shm()->detType == EIGER) {
|
||||
setActivate(true);
|
||||
}
|
||||
}
|
||||
@ -107,22 +109,21 @@ int64_t Module::getReceiverSoftwareVersion() const {
|
||||
// static function
|
||||
slsDetectorDefs::detectorType
|
||||
Module::getTypeFromDetector(const std::string &hostname, int cport) {
|
||||
LOG(logDEBUG1) << "Getting detector type ";
|
||||
LOG(logDEBUG1) << "Getting Module type ";
|
||||
sls::ClientSocket socket("Detector", hostname, cport);
|
||||
socket.Send(F_GET_DETECTOR_TYPE);
|
||||
socket.Receive<int>(); // TODO! Should we look at this OK/FAIL?
|
||||
auto retval = socket.Receive<detectorType>();
|
||||
LOG(logDEBUG1) << "Detector type is " << retval;
|
||||
LOG(logDEBUG1) << "Module type is " << retval;
|
||||
return retval;
|
||||
}
|
||||
|
||||
slsDetectorDefs::detectorType Module::getDetectorType() const {
|
||||
return shm()->myDetectorType;
|
||||
return shm()->detType;
|
||||
}
|
||||
|
||||
void Module::updateNumberOfChannels() {
|
||||
if (shm()->myDetectorType == CHIPTESTBOARD ||
|
||||
shm()->myDetectorType == MOENCH) {
|
||||
if (shm()->detType == CHIPTESTBOARD || shm()->detType == MOENCH) {
|
||||
std::array<int, 2> retvals{};
|
||||
sendToDetector(F_GET_NUM_CHANNELS, nullptr, retvals);
|
||||
shm()->nChan.x = retvals[0];
|
||||
@ -137,9 +138,9 @@ slsDetectorDefs::xy Module::getNumberOfChannels() const {
|
||||
return coord;
|
||||
}
|
||||
|
||||
void Module::updateNumberOfDetector(slsDetectorDefs::xy det) {
|
||||
shm()->numberOfDetector = det;
|
||||
int args[2] = {shm()->numberOfDetector.y, moduleIndex};
|
||||
void Module::updateNumberOfModule(slsDetectorDefs::xy det) {
|
||||
shm()->numberOfModule = det;
|
||||
int args[2] = {shm()->numberOfModule.y, moduleIndex};
|
||||
sendToDetector(F_SET_POSITION, args, nullptr);
|
||||
}
|
||||
|
||||
@ -148,7 +149,7 @@ slsDetectorDefs::detectorSettings Module::getSettings() const {
|
||||
}
|
||||
|
||||
void Module::setSettings(detectorSettings isettings) {
|
||||
if (shm()->myDetectorType == EIGER) {
|
||||
if (shm()->detType == EIGER) {
|
||||
throw RuntimeError(
|
||||
"Cannot set settings for Eiger. Use threshold energy.");
|
||||
}
|
||||
@ -176,7 +177,7 @@ void Module::setThresholdEnergy(int e_eV, detectorSettings isettings,
|
||||
std::all_of(shm()->trimEnergies.begin(), shm()->trimEnergies.end(),
|
||||
[e_eV](const int &e) { return e != e_eV; });
|
||||
|
||||
sls_detector_module myMod{shm()->myDetectorType};
|
||||
sls_detector_module myMod{shm()->detType};
|
||||
|
||||
if (!interpolate) {
|
||||
std::string settingsfname = getTrimbitFilename(isettings, e_eV);
|
||||
@ -213,7 +214,7 @@ void Module::setThresholdEnergy(int e_eV, detectorSettings isettings,
|
||||
setModule(myMod, trimbits);
|
||||
if (getSettings() != isettings) {
|
||||
throw RuntimeError("setThresholdEnergyAndSettings: Could not set "
|
||||
"settings in detector");
|
||||
"settings in Module");
|
||||
}
|
||||
|
||||
if (shm()->useReceiverFlag) {
|
||||
@ -249,7 +250,7 @@ void Module::setAllThresholdEnergy(std::array<int, 3> e_eV,
|
||||
M_VDCSH
|
||||
};
|
||||
|
||||
std::vector<sls_detector_module> myMods{shm()->myDetectorType};
|
||||
std::vector<sls_detector_module> myMods{shm()->detType};
|
||||
std::vector<int> energy(e_eV.begin(), e_eV.end());
|
||||
// if all energies are same
|
||||
if (allEqualTo(energy, energy[0])) {
|
||||
@ -307,7 +308,7 @@ void Module::setAllThresholdEnergy(std::array<int, 3> e_eV,
|
||||
}
|
||||
}
|
||||
|
||||
sls_detector_module myMod{shm()->myDetectorType};
|
||||
sls_detector_module myMod{shm()->detType};
|
||||
myMod = myMods[0];
|
||||
|
||||
// if multiple thresholds, combine
|
||||
@ -392,7 +393,7 @@ void Module::setAllThresholdEnergy(std::array<int, 3> e_eV,
|
||||
setModule(myMod, trimbits);
|
||||
if (getSettings() != isettings) {
|
||||
throw RuntimeError("setThresholdEnergyAndSettings: Could not set "
|
||||
"settings in detector");
|
||||
"settings in Module");
|
||||
}
|
||||
|
||||
if (shm()->useReceiverFlag) {
|
||||
@ -410,13 +411,13 @@ std::string Module::setSettingsDir(const std::string &dir) {
|
||||
return shm()->settingsDir;
|
||||
}
|
||||
|
||||
void Module::loadSettingsFile(const std::string &fname) {
|
||||
void Module::loadTrimbits(const std::string &fname) {
|
||||
// find specific file if it has detid in file name (.snxxx)
|
||||
if (shm()->myDetectorType == EIGER || shm()->myDetectorType == MYTHEN3) {
|
||||
if (shm()->detType == EIGER || shm()->detType == MYTHEN3) {
|
||||
std::ostringstream ostfn;
|
||||
ostfn << fname;
|
||||
int moduleIdWidth = 3;
|
||||
if (shm()->myDetectorType == MYTHEN3) {
|
||||
if (shm()->detType == MYTHEN3) {
|
||||
moduleIdWidth = 4;
|
||||
}
|
||||
if ((fname.find(".sn") == std::string::npos) &&
|
||||
@ -440,7 +441,7 @@ void Module::setAllTrimbits(int val) {
|
||||
}
|
||||
|
||||
std::vector<int> Module::getTrimEn() const {
|
||||
if (shm()->myDetectorType != EIGER && shm()->myDetectorType != MYTHEN3) {
|
||||
if (shm()->detType != EIGER && shm()->detType != MYTHEN3) {
|
||||
throw RuntimeError("getTrimEn not implemented for this detector.");
|
||||
}
|
||||
return std::vector<int>(shm()->trimEnergies.begin(),
|
||||
@ -448,7 +449,7 @@ std::vector<int> Module::getTrimEn() const {
|
||||
}
|
||||
|
||||
int Module::setTrimEn(const std::vector<int> &energies) {
|
||||
if (shm()->myDetectorType != EIGER && shm()->myDetectorType != MYTHEN3) {
|
||||
if (shm()->detType != EIGER && shm()->detType != MYTHEN3) {
|
||||
throw RuntimeError("setTrimEn not implemented for this detector.");
|
||||
}
|
||||
if (energies.size() > MAX_TRIMEN) {
|
||||
@ -464,7 +465,7 @@ int Module::setTrimEn(const std::vector<int> &energies) {
|
||||
}
|
||||
|
||||
bool Module::getFlipRows() const {
|
||||
if (shm()->myDetectorType == EIGER) {
|
||||
if (shm()->detType == EIGER) {
|
||||
const int rxIndex = 0;
|
||||
return sendToReceiver<int>(rxIndex, F_GET_FLIP_ROWS_RECEIVER);
|
||||
}
|
||||
@ -472,7 +473,7 @@ bool Module::getFlipRows() const {
|
||||
}
|
||||
|
||||
void Module::setFlipRows(bool value) {
|
||||
if (shm()->myDetectorType == EIGER) {
|
||||
if (shm()->detType == EIGER) {
|
||||
const int rxIndex = -1;
|
||||
sendToReceiver<int>(rxIndex, F_SET_FLIP_ROWS_RECEIVER, static_cast<int>(value));
|
||||
} else {
|
||||
@ -514,7 +515,7 @@ int64_t Module::getExptime(int gateIndex) const {
|
||||
|
||||
void Module::setExptime(int gateIndex, int64_t value) {
|
||||
int64_t prevVal = value;
|
||||
if (shm()->myDetectorType == EIGER) {
|
||||
if (shm()->detType == EIGER) {
|
||||
prevVal = getExptime(-1);
|
||||
}
|
||||
int64_t args[]{static_cast<int64_t>(gateIndex), value};
|
||||
@ -570,7 +571,7 @@ int Module::getDynamicRange() const {
|
||||
|
||||
void Module::setDynamicRange(int dr) {
|
||||
int prev_val = dr;
|
||||
if (shm()->myDetectorType == EIGER) {
|
||||
if (shm()->detType == EIGER) {
|
||||
prev_val = getDynamicRange();
|
||||
}
|
||||
|
||||
@ -581,7 +582,7 @@ void Module::setDynamicRange(int dr) {
|
||||
}
|
||||
|
||||
// update speed
|
||||
if (shm()->myDetectorType == EIGER) {
|
||||
if (shm()->detType == EIGER) {
|
||||
if (dr == 32) {
|
||||
LOG(logINFO) << "Setting Clock to Quarter Speed to cope with "
|
||||
"Dynamic Range of 32";
|
||||
@ -991,9 +992,7 @@ int Module::getNumberofUDPDestinations() const {
|
||||
return sendToDetector<int>(F_GET_NUM_DEST_UDP);
|
||||
}
|
||||
|
||||
void Module::setNumberofUDPDestinations(const int value) {
|
||||
sendToDetector(F_SET_NUM_DEST_UDP, value, nullptr);
|
||||
}
|
||||
void Module::clearUDPDestinations() { sendToDetector(F_CLEAR_ALL_UDP_DEST); }
|
||||
|
||||
int Module::getFirstUDPDestination() const {
|
||||
return sendToDetector<int>(F_GET_UDP_FIRST_DEST);
|
||||
@ -1026,7 +1025,7 @@ void Module::setDestinationUDPIP(const IpAddr ip, const int rxIndex) {
|
||||
if (shm()->useReceiverFlag) {
|
||||
sls::MacAddr retval(0LU);
|
||||
sendToReceiver(rxIndex, F_SET_RECEIVER_UDP_IP, ip, retval);
|
||||
LOG(logINFO) << "Setting destination udp mac of detector [" << moduleIndex
|
||||
LOG(logINFO) << "Setting destination udp mac of Module [" << moduleIndex
|
||||
<< ", " << rxIndex << "] to " << retval;
|
||||
if (rxIndex == 0) {
|
||||
sendToDetector(F_SET_DEST_UDP_MAC, retval, nullptr);
|
||||
@ -1063,7 +1062,7 @@ void Module::setDestinationUDPIP2(const IpAddr ip, const int rxIndex) {
|
||||
if (shm()->useReceiverFlag) {
|
||||
sls::MacAddr retval(0LU);
|
||||
sendToReceiver(rxIndex, F_SET_RECEIVER_UDP_IP2, ip, retval);
|
||||
LOG(logINFO) << "Setting destination udp mac2 of detector " << moduleIndex
|
||||
LOG(logINFO) << "Setting destination udp mac2 of Module " << moduleIndex
|
||||
<< " to " << retval;
|
||||
if (rxIndex == 0) {
|
||||
sendToDetector(F_SET_DEST_UDP_MAC2, retval, nullptr);
|
||||
@ -1167,28 +1166,28 @@ void Module::validateUDPConfiguration() {
|
||||
|
||||
std::string Module::printReceiverConfiguration(const int rxIndex) {
|
||||
std::ostringstream os;
|
||||
os << "\n\nDetector " << moduleIndex << "\nReceiver [" << rxIndex << "] Hostname:\t"
|
||||
os << "\n\nModule " << moduleIndex << "\nReceiver [" << rxIndex << "] Hostname:\t"
|
||||
<< getReceiverHostname(rxIndex);
|
||||
|
||||
if (shm()->myDetectorType == JUNGFRAU) {
|
||||
if (shm()->detType == JUNGFRAU) {
|
||||
os << "\nNumber of Interfaces:\t" << getNumberofUDPInterfaces()
|
||||
<< "\nSelected Interface:\t" << getSelectedUDPInterface();
|
||||
}
|
||||
auto t = getDestinationUDPList(rxIndex);
|
||||
|
||||
os << "\nDetector UDP IP:\t" << getSourceUDPIP() << "\nDetector UDP MAC:\t"
|
||||
<< getSourceUDPMAC() << "\nReceiver UDP IP:\t" << t.ip
|
||||
<< "\nReceiver UDP MAC:\t" << t.mac;
|
||||
os << "\nSource UDP IP:\t" << getSourceUDPIP() << "\nSource UDP MAC:\t"
|
||||
<< getSourceUDPMAC() << "\nDestination UDP IP:\t" << t.ip
|
||||
<< "\nDestination UDP MAC:\t" << t.mac;
|
||||
|
||||
if (shm()->myDetectorType == JUNGFRAU) {
|
||||
os << "\nDetector UDP IP2:\t" << getSourceUDPIP2()
|
||||
<< "\nDetector UDP MAC2:\t" << getSourceUDPMAC2()
|
||||
<< "\nReceiver UDP IP2:\t" << t.ip2
|
||||
<< "\nReceiver UDP MAC2:\t" << t.mac2;
|
||||
if (shm()->detType == JUNGFRAU) {
|
||||
os << "\nSource UDP IP2:\t" << getSourceUDPIP2()
|
||||
<< "\nSource UDP MAC2:\t" << getSourceUDPMAC2()
|
||||
<< "\nDestination UDP IP2:\t" << t.ip2
|
||||
<< "\nDestination UDP MAC2:\t" << t.mac2;
|
||||
}
|
||||
os << "\nReceiver UDP Port:\t" << t.port;
|
||||
if (shm()->myDetectorType == JUNGFRAU || shm()->myDetectorType == EIGER) {
|
||||
os << "\nReceiver UDP Port2:\t" << t.port2;
|
||||
os << "\nDestination UDP Port:\t" << t.port;
|
||||
if (shm()->detType == JUNGFRAU || shm()->detType == EIGER) {
|
||||
os << "\nDestination UDP Port2:\t" << t.port2;
|
||||
}
|
||||
os << "\n";
|
||||
return os.str();
|
||||
@ -1280,25 +1279,25 @@ void Module::setReceiverHostname(const std::string &receiverIP, const int rxInde
|
||||
sendToDetector(F_GET_RECEIVER_PARAMETERS, nullptr, retval);
|
||||
|
||||
// populate from shared memory
|
||||
retval.detType = shm()->myDetectorType;
|
||||
retval.numberOfDetector.x = shm()->numberOfDetector.x;
|
||||
retval.numberOfDetector.y = shm()->numberOfDetector.y;
|
||||
retval.detType = shm()->detType;
|
||||
retval.numberOfModule.x = shm()->numberOfModule.x;
|
||||
retval.numberOfModule.y = shm()->numberOfModule.y;
|
||||
retval.moduleIndex = moduleIndex;
|
||||
memset(retval.hostname, 0, sizeof(retval.hostname));
|
||||
strcpy_safe(retval.hostname, shm()->hostname);
|
||||
|
||||
sls::MacAddr retvals[2];
|
||||
sendToReceiver(rxIndex, F_SETUP_RECEIVER, retval, retvals);
|
||||
// update detectors with dest mac
|
||||
// update Modules with dest mac
|
||||
if (retval.udp_dstmac == 0 && retvals[0] != 0) {
|
||||
LOG(logINFO) << "Setting destination udp mac of "
|
||||
"detector "
|
||||
"Module "
|
||||
<< moduleIndex << " to " << retvals[0];
|
||||
sendToDetector(F_SET_DEST_UDP_MAC, retvals[0], nullptr);
|
||||
}
|
||||
if (retval.udp_dstmac2 == 0 && retvals[1] != 0) {
|
||||
LOG(logINFO) << "Setting destination udp mac2 of "
|
||||
"detector "
|
||||
"Module "
|
||||
<< moduleIndex << " to " << retvals[1];
|
||||
sendToDetector(F_SET_DEST_UDP_MAC2, retvals[1], nullptr);
|
||||
}
|
||||
@ -1610,7 +1609,7 @@ int64_t Module::getSubExptime() const {
|
||||
|
||||
void Module::setSubExptime(int64_t value) {
|
||||
int64_t prevVal = value;
|
||||
if (shm()->myDetectorType == EIGER) {
|
||||
if (shm()->detType == EIGER) {
|
||||
prevVal = getSubExptime();
|
||||
}
|
||||
sendToDetector(F_SET_SUB_EXPTIME, value, nullptr);
|
||||
@ -1977,7 +1976,7 @@ void Module::getVetoPhoton(const int chipIndex,
|
||||
|
||||
void Module::setVetoPhoton(const int chipIndex, const int numPhotons,
|
||||
const int energy, const std::string &fname) {
|
||||
if (shm()->myDetectorType != GOTTHARD2) {
|
||||
if (shm()->detType != GOTTHARD2) {
|
||||
throw RuntimeError(
|
||||
"Set Veto reference is not implemented for this detector");
|
||||
}
|
||||
@ -2058,7 +2057,7 @@ void Module::setVetoReference(const int gainIndex, const int value) {
|
||||
}
|
||||
|
||||
void Module::setVetoFile(const int chipIndex, const std::string &fname) {
|
||||
if (shm()->myDetectorType != GOTTHARD2) {
|
||||
if (shm()->detType != GOTTHARD2) {
|
||||
throw RuntimeError(
|
||||
"Set Veto file is not implemented for this detector");
|
||||
}
|
||||
@ -2386,7 +2385,7 @@ void Module::setReadoutMode(const slsDetectorDefs::readoutMode mode) {
|
||||
auto arg = static_cast<uint32_t>(mode); // TODO! unit?
|
||||
sendToDetector(F_SET_READOUT_MODE, arg, nullptr);
|
||||
// update #nchan, as it depends on #samples, adcmask,
|
||||
if (shm()->myDetectorType == CHIPTESTBOARD) {
|
||||
if (shm()->detType == CHIPTESTBOARD) {
|
||||
updateNumberOfChannels();
|
||||
}
|
||||
if (shm()->useReceiverFlag) {
|
||||
@ -2651,7 +2650,7 @@ void Module::setAdditionalJsonParameter(const std::string &key,
|
||||
|
||||
// Advanced
|
||||
void Module::programFPGA(std::vector<char> buffer) {
|
||||
switch (shm()->myDetectorType) {
|
||||
switch (shm()->detType) {
|
||||
case JUNGFRAU:
|
||||
case CHIPTESTBOARD:
|
||||
case MOENCH:
|
||||
@ -3197,42 +3196,42 @@ slsDetectorDefs::detectorType Module::getDetectorTypeFromShm(int det_id,
|
||||
}
|
||||
|
||||
shm.OpenSharedMemory();
|
||||
if (verify && shm()->shmversion != SLS_SHMVERSION) {
|
||||
if (verify && shm()->shmversion != MODULE_SHMVERSION) {
|
||||
std::ostringstream ss;
|
||||
ss << "Single shared memory (" << det_id << "-" << moduleIndex
|
||||
<< ":)version mismatch (expected 0x" << std::hex << SLS_SHMVERSION
|
||||
<< ":)version mismatch (expected 0x" << std::hex << MODULE_SHMVERSION
|
||||
<< " but got 0x" << shm()->shmversion << ")" << std::dec
|
||||
<< ". Clear Shared memory to continue.";
|
||||
shm.UnmapSharedMemory();
|
||||
throw SharedMemoryError(ss.str());
|
||||
}
|
||||
return shm()->myDetectorType;
|
||||
return shm()->detType;
|
||||
}
|
||||
|
||||
void Module::initSharedMemory(detectorType type, int det_id, bool verify) {
|
||||
shm = SharedMemory<sharedSlsDetector>(det_id, moduleIndex);
|
||||
shm = SharedMemory<sharedModule>(det_id, moduleIndex);
|
||||
if (!shm.IsExisting()) {
|
||||
shm.CreateSharedMemory();
|
||||
initializeDetectorStructure(type);
|
||||
initializeModuleStructure(type);
|
||||
} else {
|
||||
shm.OpenSharedMemory();
|
||||
if (verify && shm()->shmversion != SLS_SHMVERSION) {
|
||||
if (verify && shm()->shmversion != MODULE_SHMVERSION) {
|
||||
std::ostringstream ss;
|
||||
ss << "Single shared memory (" << det_id << "-" << moduleIndex
|
||||
<< ":) version mismatch (expected 0x" << std::hex
|
||||
<< SLS_SHMVERSION << " but got 0x" << shm()->shmversion << ")"
|
||||
<< MODULE_SHMVERSION << " but got 0x" << shm()->shmversion << ")"
|
||||
<< std::dec << ". Clear Shared memory to continue.";
|
||||
throw SharedMemoryError(ss.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Module::initializeDetectorStructure(detectorType type) {
|
||||
shm()->shmversion = SLS_SHMVERSION;
|
||||
void Module::initializeModuleStructure(detectorType type) {
|
||||
shm()->shmversion = MODULE_SHMVERSION;
|
||||
memset(shm()->hostname, 0, MAX_STR_LENGTH);
|
||||
shm()->myDetectorType = type;
|
||||
shm()->numberOfDetector.x = 0;
|
||||
shm()->numberOfDetector.y = 0;
|
||||
shm()->detType = type;
|
||||
shm()->numberOfModule.x = 0;
|
||||
shm()->numberOfModule.y = 0;
|
||||
shm()->controlPort = DEFAULT_PORTNO;
|
||||
shm()->stopPort = DEFAULT_PORTNO + 1;
|
||||
sls::strcpy_safe(shm()->settingsDir, getenv("HOME"));
|
||||
@ -3243,12 +3242,12 @@ void Module::initializeDetectorStructure(detectorType type) {
|
||||
}
|
||||
shm()->useReceiverFlag = false;
|
||||
shm()->zmqport = DEFAULT_ZMQ_CL_PORTNO +
|
||||
(moduleIndex * ((shm()->myDetectorType == EIGER) ? 2 : 1));
|
||||
(moduleIndex * ((shm()->detType == EIGER) ? 2 : 1));
|
||||
shm()->zmqip = IpAddr{};
|
||||
shm()->numUDPInterfaces = 1;
|
||||
shm()->stoppedFlag = false;
|
||||
|
||||
// get the detector parameters based on type
|
||||
// get the Module parameters based on type
|
||||
detParameters parameters{type};
|
||||
shm()->nChan.x = parameters.nChanX;
|
||||
shm()->nChan.y = parameters.nChanY;
|
||||
@ -3259,7 +3258,7 @@ void Module::initializeDetectorStructure(detectorType type) {
|
||||
|
||||
void Module::checkDetectorVersionCompatibility() {
|
||||
int64_t arg = 0;
|
||||
switch (shm()->myDetectorType) {
|
||||
switch (shm()->detType) {
|
||||
case EIGER:
|
||||
arg = APIEIGER;
|
||||
break;
|
||||
@ -3338,7 +3337,7 @@ int Module::sendModule(sls_detector_module *myMod, sls::ClientSocket &client) {
|
||||
ts += n;
|
||||
LOG(level) << "dacs sent. " << n << " bytes";
|
||||
|
||||
if (shm()->myDetectorType == EIGER || shm()->myDetectorType == MYTHEN3) {
|
||||
if (shm()->detType == EIGER || shm()->detType == MYTHEN3) {
|
||||
n = client.Send(myMod->chanregs, sizeof(int) * (myMod->nchan));
|
||||
ts += n;
|
||||
LOG(level) << "channels sent. " << n << " bytes";
|
||||
@ -3386,12 +3385,12 @@ sls_detector_module Module::interpolateTrim(sls_detector_module *a,
|
||||
const int energy, const int e1,
|
||||
const int e2, bool trimbits) {
|
||||
// dacs specified only for eiger and mythen3
|
||||
if (shm()->myDetectorType != EIGER && shm()->myDetectorType != MYTHEN3) {
|
||||
if (shm()->detType != EIGER && shm()->detType != MYTHEN3) {
|
||||
throw NotImplementedError(
|
||||
"Interpolation of Trim values not implemented for this detector!");
|
||||
}
|
||||
|
||||
sls_detector_module myMod{shm()->myDetectorType};
|
||||
sls_detector_module myMod{shm()->detType};
|
||||
enum eiger_DacIndex {
|
||||
E_SVP,
|
||||
E_VTR,
|
||||
@ -3431,7 +3430,7 @@ sls_detector_module Module::interpolateTrim(sls_detector_module *a,
|
||||
|
||||
// create copy and interpolate dac lists
|
||||
std::vector<int> dacs_to_copy, dacs_to_interpolate;
|
||||
if (shm()->myDetectorType == EIGER) {
|
||||
if (shm()->detType == EIGER) {
|
||||
dacs_to_copy.insert(
|
||||
dacs_to_copy.end(),
|
||||
{E_SVP, E_VTR, E_SVN, E_VTGSTV, E_RXB_RB, E_RXB_LB, E_VCN, E_VIS});
|
||||
@ -3466,7 +3465,7 @@ sls_detector_module Module::interpolateTrim(sls_detector_module *a,
|
||||
}
|
||||
|
||||
// Copy irrelevant dacs (without failing)
|
||||
if (shm()->myDetectorType == EIGER) {
|
||||
if (shm()->detType == EIGER) {
|
||||
// CAL
|
||||
if (a->dacs[E_CAL] != b->dacs[E_CAL]) {
|
||||
LOG(logWARNING)
|
||||
@ -3514,16 +3513,16 @@ std::string Module::getTrimbitFilename(detectorSettings s, int e_eV) {
|
||||
}
|
||||
std::ostringstream ostfn;
|
||||
ostfn << shm()->settingsDir << ssettings << "/" << e_eV << "eV";
|
||||
if (shm()->myDetectorType == EIGER) {
|
||||
if (shm()->detType == EIGER) {
|
||||
ostfn << "/noise.sn";
|
||||
} else if (shm()->myDetectorType == MYTHEN3) {
|
||||
} else if (shm()->detType == MYTHEN3) {
|
||||
ostfn << "/trim.sn";
|
||||
} else {
|
||||
throw RuntimeError(
|
||||
"Settings or trimbit files not defined for this detector.");
|
||||
}
|
||||
int moduleIdWidth = 3;
|
||||
if (shm()->myDetectorType == MYTHEN3) {
|
||||
if (shm()->detType == MYTHEN3) {
|
||||
moduleIdWidth = 4;
|
||||
}
|
||||
ostfn << std::setfill('0') << std::setw(moduleIdWidth) << std::dec
|
||||
@ -3534,10 +3533,10 @@ std::string Module::getTrimbitFilename(detectorSettings s, int e_eV) {
|
||||
sls_detector_module Module::readSettingsFile(const std::string &fname,
|
||||
bool trimbits) {
|
||||
LOG(logDEBUG1) << "Read settings file " << fname;
|
||||
sls_detector_module myMod(shm()->myDetectorType);
|
||||
sls_detector_module myMod(shm()->detType);
|
||||
// open file
|
||||
std::ifstream infile;
|
||||
if (shm()->myDetectorType == EIGER || shm()->myDetectorType == MYTHEN3) {
|
||||
if (shm()->detType == EIGER || shm()->detType == MYTHEN3) {
|
||||
infile.open(fname.c_str(), std::ifstream::binary);
|
||||
} else {
|
||||
infile.open(fname.c_str(), std::ios_base::in);
|
||||
@ -3549,7 +3548,7 @@ sls_detector_module Module::readSettingsFile(const std::string &fname,
|
||||
auto file_size = getFileSize(infile);
|
||||
|
||||
// eiger
|
||||
if (shm()->myDetectorType == EIGER) {
|
||||
if (shm()->detType == EIGER) {
|
||||
infile.read(reinterpret_cast<char *>(myMod.dacs),
|
||||
sizeof(int) * (myMod.ndac));
|
||||
infile.read(reinterpret_cast<char *>(&myMod.iodelay),
|
||||
@ -3572,7 +3571,7 @@ sls_detector_module Module::readSettingsFile(const std::string &fname,
|
||||
}
|
||||
|
||||
// mythen3 (dacs, trimbits)
|
||||
else if (shm()->myDetectorType == MYTHEN3) {
|
||||
else if (shm()->detType == MYTHEN3) {
|
||||
int expected_size = sizeof(int) * myMod.ndac +
|
||||
sizeof(int) * myMod.nchan + sizeof(myMod.reg);
|
||||
if (file_size != expected_size) {
|
||||
@ -3606,23 +3605,67 @@ sls_detector_module Module::readSettingsFile(const std::string &fname,
|
||||
}
|
||||
|
||||
void Module::programFPGAviaBlackfin(std::vector<char> buffer) {
|
||||
uint64_t filesize = buffer.size();
|
||||
// send program from memory to detector
|
||||
LOG(logINFO) << "Sending programming binary (from pof) to detector "
|
||||
LOG(logINFO) << "Sending programming binary (from pof) to module "
|
||||
<< moduleIndex << " (" << shm()->hostname << ")";
|
||||
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
|
||||
client.Send(F_PROGRAM_FPGA);
|
||||
uint64_t filesize = buffer.size();
|
||||
client.Send(filesize);
|
||||
// error in detector at opening file pointer to flash
|
||||
|
||||
// checksum
|
||||
std::string checksum = sls::md5_calculate_checksum(buffer.data(), filesize);
|
||||
LOG(logDEBUG1) << "Checksum:" << checksum;
|
||||
char cChecksum[MAX_STR_LENGTH];
|
||||
memset(cChecksum, 0, MAX_STR_LENGTH);
|
||||
strcpy(cChecksum, checksum.c_str());
|
||||
client.Send(cChecksum);
|
||||
|
||||
// opening file fail
|
||||
if (client.Receive<int>() == FAIL) {
|
||||
std::cout << '\n';
|
||||
std::ostringstream os;
|
||||
os << "Detector " << moduleIndex << " (" << shm()->hostname << ")"
|
||||
os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
|
||||
<< " returned error: " << client.readErrorMessage();
|
||||
throw RuntimeError(os.str());
|
||||
}
|
||||
|
||||
// erasing flash
|
||||
LOG(logINFO) << "Erasing Flash for detector " << moduleIndex << " ("
|
||||
// sending program in parts of 2mb each
|
||||
uint64_t unitprogramsize = 0;
|
||||
int currentPointer = 0;
|
||||
while (filesize > 0) {
|
||||
unitprogramsize = MAX_FPGAPROGRAMSIZE; // 2mb
|
||||
if (unitprogramsize > filesize) { // less than 2mb
|
||||
unitprogramsize = filesize;
|
||||
}
|
||||
LOG(logDEBUG) << "unitprogramsize:" << unitprogramsize
|
||||
<< "\t filesize:" << filesize;
|
||||
|
||||
client.Send(&buffer[currentPointer], unitprogramsize);
|
||||
if (client.Receive<int>() == FAIL) {
|
||||
std::cout << '\n';
|
||||
std::ostringstream os;
|
||||
os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
|
||||
<< " returned error: " << client.readErrorMessage();
|
||||
throw RuntimeError(os.str());
|
||||
}
|
||||
filesize -= unitprogramsize;
|
||||
currentPointer += unitprogramsize;
|
||||
}
|
||||
|
||||
// checksum
|
||||
if (client.Receive<int>() == FAIL) {
|
||||
std::ostringstream os;
|
||||
os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
|
||||
<< " returned error: " << client.readErrorMessage();
|
||||
throw RuntimeError(os.str());
|
||||
}
|
||||
LOG(logINFO) << "Checksum verified for module " << moduleIndex << " ("
|
||||
<< shm()->hostname << ")";
|
||||
|
||||
// simulating erasing flash
|
||||
{
|
||||
LOG(logINFO) << "(Simulating) Erasing Flash for module " << moduleIndex << " ("
|
||||
<< shm()->hostname << ")";
|
||||
printf("%d%%\r", 0);
|
||||
std::cout << std::flush;
|
||||
@ -3640,73 +3683,114 @@ void Module::programFPGAviaBlackfin(std::vector<char> buffer) {
|
||||
std::cout << std::flush;
|
||||
}
|
||||
printf("\n");
|
||||
LOG(logINFO) << "Writing to Flash to detector " << moduleIndex << " ("
|
||||
<< shm()->hostname << ")";
|
||||
}
|
||||
|
||||
// simulating writing to flash
|
||||
{
|
||||
LOG(logINFO) << "(Simulating) Writing to Flash for module " << moduleIndex << " (" << shm()->hostname << ")";
|
||||
printf("%d%%\r", 0);
|
||||
std::cout << std::flush;
|
||||
|
||||
// sending program in parts of 2mb each
|
||||
uint64_t unitprogramsize = 0;
|
||||
int currentPointer = 0;
|
||||
uint64_t totalsize = filesize;
|
||||
while (filesize > 0) {
|
||||
unitprogramsize = MAX_FPGAPROGRAMSIZE; // 2mb
|
||||
if (unitprogramsize > filesize) { // less than 2mb
|
||||
unitprogramsize = filesize;
|
||||
}
|
||||
LOG(logDEBUG1) << "unitprogramsize:" << unitprogramsize
|
||||
<< "\t filesize:" << filesize;
|
||||
|
||||
client.Send(&buffer[currentPointer], unitprogramsize);
|
||||
if (client.Receive<int>() == FAIL) {
|
||||
std::cout << '\n';
|
||||
std::ostringstream os;
|
||||
os << "Detector " << moduleIndex << " (" << shm()->hostname << ")"
|
||||
<< " returned error: " << client.readErrorMessage();
|
||||
throw RuntimeError(os.str());
|
||||
}
|
||||
filesize -= unitprogramsize;
|
||||
currentPointer += unitprogramsize;
|
||||
|
||||
// print progress
|
||||
// writing takes 30 seconds, printing here (otherwise need threads
|
||||
// in server-unnecessary)
|
||||
const int ERASE_TIME = 30;
|
||||
int count = ERASE_TIME + 1;
|
||||
while (count > 0) {
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
--count;
|
||||
printf(
|
||||
"%d%%\r",
|
||||
static_cast<int>(
|
||||
(static_cast<double>(totalsize - filesize) / totalsize) * 100));
|
||||
(static_cast<double>(ERASE_TIME - count) / ERASE_TIME) * 100));
|
||||
std::cout << std::flush;
|
||||
}
|
||||
std::cout << '\n';
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// fpga has picked up from flash successfully
|
||||
if (client.Receive<int>() == FAIL) {
|
||||
std::ostringstream os;
|
||||
os << "Detector " << moduleIndex << " (" << shm()->hostname << ")"
|
||||
os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
|
||||
<< " returned error: " << client.readErrorMessage();
|
||||
throw RuntimeError(os.str());
|
||||
}
|
||||
if (moduleIndex == 0) {
|
||||
LOG(logINFO) << "Copied to flash and checksum verified";
|
||||
}
|
||||
|
||||
LOG(logINFO) << "FPGA programmed successfully";
|
||||
rebootController();
|
||||
}
|
||||
|
||||
void Module::programFPGAviaNios(std::vector<char> buffer) {
|
||||
LOG(logINFO) << "Sending programming binary (from rbf) to detector "
|
||||
LOG(logINFO) << "Sending programming binary (from rbf) to Module "
|
||||
<< moduleIndex << " (" << shm()->hostname << ")";
|
||||
|
||||
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
|
||||
client.Send(F_PROGRAM_FPGA);
|
||||
uint64_t filesize = buffer.size();
|
||||
client.Send(filesize);
|
||||
|
||||
// checksum
|
||||
std::string checksum = sls::md5_calculate_checksum(buffer.data(), filesize);
|
||||
LOG(logDEBUG1) << "Checksum:" << checksum;
|
||||
char cChecksum[MAX_STR_LENGTH];
|
||||
memset(cChecksum, 0, MAX_STR_LENGTH);
|
||||
strcpy(cChecksum, checksum.c_str());
|
||||
client.Send(cChecksum);
|
||||
|
||||
// validate file size before sending program
|
||||
if (client.Receive<int>() == FAIL) {
|
||||
std::ostringstream os;
|
||||
os << "Detector " << moduleIndex << " (" << shm()->hostname << ")"
|
||||
os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
|
||||
<< " returned error: " << client.readErrorMessage();
|
||||
throw RuntimeError(os.str());
|
||||
}
|
||||
client.Send(buffer);
|
||||
|
||||
// simulating erasing flash
|
||||
{
|
||||
LOG(logINFO) << "(Simulating) Erasing Flash for module " << moduleIndex << " ("
|
||||
<< shm()->hostname << ")";
|
||||
printf("%d%%\r", 0);
|
||||
std::cout << std::flush;
|
||||
// erasing takes 10 seconds, printing here (otherwise need threads
|
||||
// in server-unnecessary)
|
||||
const int ERASE_TIME = 10;
|
||||
int count = ERASE_TIME + 1;
|
||||
while (count > 0) {
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
--count;
|
||||
printf(
|
||||
"%d%%\r",
|
||||
static_cast<int>(
|
||||
(static_cast<double>(ERASE_TIME - count) / ERASE_TIME) * 100));
|
||||
std::cout << std::flush;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// simulating writing to flash
|
||||
{
|
||||
LOG(logINFO) << "(Simulating) Writing to Flash for module " << moduleIndex << " (" << shm()->hostname << ")";
|
||||
printf("%d%%\r", 0);
|
||||
std::cout << std::flush;
|
||||
// writing takes 45 seconds, printing here (otherwise need threads
|
||||
// in server-unnecessary)
|
||||
const int ERASE_TIME = 45;
|
||||
int count = ERASE_TIME + 1;
|
||||
while (count > 0) {
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
--count;
|
||||
printf(
|
||||
"%d%%\r",
|
||||
static_cast<int>(
|
||||
(static_cast<double>(ERASE_TIME - count) / ERASE_TIME) * 100));
|
||||
std::cout << std::flush;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
if (client.Receive<int>() == FAIL) {
|
||||
std::ostringstream os;
|
||||
os << "Detector " << moduleIndex << " (" << shm()->hostname << ")"
|
||||
os << "Module " << moduleIndex << " (" << shm()->hostname << ")"
|
||||
<< " returned error: " << client.readErrorMessage();
|
||||
throw RuntimeError(os.str());
|
||||
}
|
||||
|
@ -14,8 +14,8 @@
|
||||
|
||||
class ServerInterface;
|
||||
|
||||
#define SLS_SHMAPIVERSION 0x190726
|
||||
#define SLS_SHMVERSION 0x210913
|
||||
#define MODULE_SHMAPIVERSION 0x190726
|
||||
#define MODULE_SHMVERSION 0x210913
|
||||
|
||||
namespace sls {
|
||||
|
||||
@ -25,24 +25,24 @@ struct sharedReceiver {
|
||||
};
|
||||
|
||||
/**
|
||||
* @short structure allocated in shared memory to store detector settings for
|
||||
* @short structure allocated in shared memory to store Module settings for
|
||||
* IPC and cache
|
||||
*/
|
||||
struct sharedSlsDetector {
|
||||
struct sharedModule {
|
||||
|
||||
/* FIXED PATTERN FOR STATIC FUNCTIONS. DO NOT CHANGE, ONLY APPEND ------*/
|
||||
|
||||
int shmversion;
|
||||
char hostname[MAX_STR_LENGTH];
|
||||
slsDetectorDefs::detectorType myDetectorType;
|
||||
slsDetectorDefs::detectorType detType;
|
||||
|
||||
/** END OF FIXED PATTERN -----------------------------------------------*/
|
||||
|
||||
slsDetectorDefs::xy numberOfDetector;
|
||||
slsDetectorDefs::xy numberOfModule;
|
||||
int controlPort;
|
||||
int stopPort;
|
||||
char settingsDir[MAX_STR_LENGTH];
|
||||
/** list of the energies at which the detector has been trimmed */
|
||||
/** list of the energies at which the Module has been trimmed */
|
||||
sls::StaticVector<int, MAX_TRIMEN> trimEnergies;
|
||||
/** number of channels per chip */
|
||||
slsDetectorDefs::xy nChan;
|
||||
@ -84,7 +84,7 @@ class Module : public virtual slsDetectorDefs {
|
||||
virtual ~Module();
|
||||
|
||||
/** Frees shared memory and deletes shared memory structure
|
||||
Safe to call only if detector shm also deleted or its numberOfDetectors is
|
||||
Safe to call only if detector shm also deleted or its numberOfModules is
|
||||
updated */
|
||||
void freeSharedMemory();
|
||||
bool isFixedPatternSharedMemoryCompatible() const;
|
||||
@ -107,7 +107,7 @@ class Module : public virtual slsDetectorDefs {
|
||||
detectorType getDetectorType() const;
|
||||
void updateNumberOfChannels();
|
||||
slsDetectorDefs::xy getNumberOfChannels() const;
|
||||
void updateNumberOfDetector(slsDetectorDefs::xy det);
|
||||
void updateNumberOfModule(slsDetectorDefs::xy det);
|
||||
detectorSettings getSettings() const;
|
||||
void setSettings(detectorSettings isettings);
|
||||
int getThresholdEnergy() const;
|
||||
@ -118,7 +118,7 @@ class Module : public virtual slsDetectorDefs {
|
||||
detectorSettings isettings, bool trimbits);
|
||||
std::string getSettingsDir() const;
|
||||
std::string setSettingsDir(const std::string &dir);
|
||||
void loadSettingsFile(const std::string &fname);
|
||||
void loadTrimbits(const std::string &fname);
|
||||
int getAllTrimbits() const;
|
||||
void setAllTrimbits(int val);
|
||||
std::vector<int> getTrimEn() const;
|
||||
@ -232,7 +232,7 @@ class Module : public virtual slsDetectorDefs {
|
||||
sls::UdpDestination getDestinationUDPList(const uint32_t entry) const;
|
||||
void setDestinationUDPList(const sls::UdpDestination dest);
|
||||
int getNumberofUDPDestinations() const;
|
||||
void setNumberofUDPDestinations(const int value);
|
||||
void clearUDPDestinations();
|
||||
int getFirstUDPDestination() const;
|
||||
void setFirstUDPDestination(const int value);
|
||||
sls::IpAddr getDestinationUDPIP(const int rxIndex) const;
|
||||
@ -718,9 +718,9 @@ class Module : public virtual slsDetectorDefs {
|
||||
verify is if shm size matches existing one */
|
||||
void initSharedMemory(detectorType type, int det_id, bool verify = true);
|
||||
|
||||
/** Initialize detector structure to defaults,
|
||||
/** Initialize module structure to defaults,
|
||||
Called when new shared memory is created */
|
||||
void initializeDetectorStructure(detectorType type);
|
||||
void initializeModuleStructure(detectorType type);
|
||||
|
||||
void checkDetectorVersionCompatibility();
|
||||
void checkReceiverVersionCompatibility();
|
||||
@ -763,7 +763,7 @@ class Module : public virtual slsDetectorDefs {
|
||||
void programFPGAviaNios(std::vector<char> buffer);
|
||||
|
||||
const int moduleIndex;
|
||||
mutable sls::SharedMemory<sharedSlsDetector> shm{0, 0};
|
||||
mutable sls::SharedMemory<sharedModule> shm{0, 0};
|
||||
};
|
||||
|
||||
} // namespace sls
|
@ -22,8 +22,8 @@
|
||||
#include <sys/stat.h> // fstat
|
||||
#include <unistd.h>
|
||||
|
||||
#define SHM_MULTI_PREFIX "/slsDetectorPackage_multi_"
|
||||
#define SHM_SLS_PREFIX "_sls_"
|
||||
#define SHM_DETECTOR_PREFIX "/slsDetectorPackage_detector_"
|
||||
#define SHM_MODULE_PREFIX "_module_"
|
||||
#define SHM_ENV_NAME "SLSDETNAME"
|
||||
|
||||
#include <iostream>
|
||||
@ -35,13 +35,10 @@ template <typename T> class SharedMemory {
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
* creates the single/multi detector shared memory name
|
||||
* @param multiId multi detector id
|
||||
* @param slsId sls detector id, -1 if a multi detector shared memory
|
||||
* moduleid of -1 creates a detector only shared memory
|
||||
*/
|
||||
SharedMemory(int multiId, int slsId) {
|
||||
name = ConstructSharedMemoryName(multiId, slsId);
|
||||
SharedMemory(int detectorId, int moduleIndex) {
|
||||
name = ConstructSharedMemoryName(detectorId, moduleIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -208,11 +205,11 @@ template <typename T> class SharedMemory {
|
||||
/**
|
||||
* Create Shared memory name
|
||||
* throws exception if name created is longer than required 255(manpages)
|
||||
* @param multiId multi detector id
|
||||
* @param slsId sls detector id, -1 if a multi detector shared memory
|
||||
* @param detectorId detector id
|
||||
* @param moduleIndex module id, -1 if a detector shared memory
|
||||
* @returns shared memory name
|
||||
*/
|
||||
std::string ConstructSharedMemoryName(int multiId, int slsId) {
|
||||
std::string ConstructSharedMemoryName(int detectorId, int moduleIndex) {
|
||||
|
||||
// using environment path
|
||||
std::string sEnvPath;
|
||||
@ -223,11 +220,11 @@ template <typename T> class SharedMemory {
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
if (slsId < 0)
|
||||
ss << SHM_MULTI_PREFIX << multiId << sEnvPath;
|
||||
if (moduleIndex < 0)
|
||||
ss << SHM_DETECTOR_PREFIX << detectorId << sEnvPath;
|
||||
else
|
||||
ss << SHM_MULTI_PREFIX << multiId << SHM_SLS_PREFIX << slsId
|
||||
<< sEnvPath;
|
||||
ss << SHM_DETECTOR_PREFIX << detectorId << SHM_MODULE_PREFIX
|
||||
<< moduleIndex << sEnvPath;
|
||||
|
||||
std::string temp = ss.str();
|
||||
if (temp.length() > NAME_MAX_LENGTH) {
|
||||
|
@ -2215,13 +2215,12 @@ TEST_CASE("udp_dstlist", "[.cmd]") {
|
||||
CmdProxy proxy(&det);
|
||||
auto det_type = det.getDetectorType().squash();
|
||||
if (det_type == defs::JUNGFRAU || det_type == defs::EIGER) {
|
||||
REQUIRE_NOTHROW(proxy.Call("udp_dstlist", {"0"}, -1, GET));
|
||||
REQUIRE_NOTHROW(proxy.Call("udp_dstlist", {}, 0, GET, std::cout, 0));
|
||||
REQUIRE_THROWS(proxy.Call(
|
||||
"udp_dstlist",
|
||||
{"entry=0", "ip=0.0.0.0", "mac=00:00:00:00:00:00", "port=1233"}, -1,
|
||||
PUT));
|
||||
"udp_dstlist", {"ip=0.0.0.0", "mac=00:00:00:00:00:00", "port=1233"},
|
||||
-1, PUT, std::cout, 0));
|
||||
} else {
|
||||
REQUIRE_THROWS(proxy.Call("udp_dstlist", {"0"}, -1, GET));
|
||||
REQUIRE_THROWS(proxy.Call("udp_dstlist", {}, -1, GET, std::cout, 0));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2230,33 +2229,20 @@ TEST_CASE("udp_numdst", "[.cmd]") {
|
||||
CmdProxy proxy(&det);
|
||||
auto det_type = det.getDetectorType().squash();
|
||||
if (det_type == defs::JUNGFRAU || det_type == defs::EIGER) {
|
||||
auto prev_val = det.getNumberofUDPDestinations();
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("udp_numdst", {"10"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "udp_numdst 10\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("udp_numdst", {}, -1, GET, oss);
|
||||
REQUIRE(oss.str() == "udp_numdst 10\n");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
proxy.Call("udp_numdst", {"32"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "udp_numdst 32\n");
|
||||
}
|
||||
REQUIRE_THROWS(proxy.Call("udp_numdst", {"0"}, -1, PUT));
|
||||
REQUIRE_THROWS(proxy.Call("udp_numdst", {"33"}, -1, PUT));
|
||||
|
||||
for (int i = 0; i != det.size(); ++i) {
|
||||
det.setNumberofUDPDestinations(prev_val[i], {i});
|
||||
}
|
||||
REQUIRE_NOTHROW(proxy.Call("udp_numdst", {}, -1, GET));
|
||||
} else {
|
||||
REQUIRE_THROWS(proxy.Call("udp_numdst", {}, -1, GET));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("udp_cleardst", "[.cmd]") {
|
||||
Detector det;
|
||||
CmdProxy proxy(&det);
|
||||
REQUIRE_THROWS(proxy.Call("udp_cleardst", {}, -1, GET));
|
||||
REQUIRE_NOTHROW(proxy.Call("udp_cleardst", {}, -1, PUT));
|
||||
}
|
||||
|
||||
TEST_CASE("udp_firstdst", "[.cmd]") {
|
||||
Detector det;
|
||||
CmdProxy proxy(&det);
|
||||
|
@ -29,7 +29,7 @@ TEST_CASE("Is shm fixed pattern shm compatible") {
|
||||
REQUIRE(m.isFixedPatternSharedMemoryCompatible() == true);
|
||||
|
||||
// Set shm version to 0
|
||||
sls::SharedMemory<sls::sharedSlsDetector> shm(0, 0);
|
||||
sls::SharedMemory<sls::sharedModule> shm(0, 0);
|
||||
REQUIRE(shm.IsExisting() == true);
|
||||
shm.OpenSharedMemory();
|
||||
shm()->shmversion = 0;
|
||||
|
@ -42,3 +42,17 @@ void BinaryMasterFile::CreateMasterFile(const std::string filePath,
|
||||
attr->WriteMasterBinaryAttributes(fd_);
|
||||
CloseFile();
|
||||
}
|
||||
|
||||
void BinaryMasterFile::UpdateMasterFile(MasterAttributes *attr,
|
||||
bool silentMode) {
|
||||
if (nullptr == (fd_ = fopen((const char *)fileName_.c_str(), "a"))) {
|
||||
fd_ = nullptr;
|
||||
throw sls::RuntimeError("Could not append binary master file " +
|
||||
fileName_);
|
||||
}
|
||||
attr->WriteFinalBinaryAttributes(fd_);
|
||||
CloseFile();
|
||||
if (!silentMode) {
|
||||
LOG(logINFO) << "Updated Master File";
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ class BinaryMasterFile : private virtual slsDetectorDefs, public File {
|
||||
const uint64_t fileIndex, const bool overWriteEnable,
|
||||
const bool silentMode,
|
||||
MasterAttributes *attr) override;
|
||||
void UpdateMasterFile(MasterAttributes *attr, bool silentMode) override;
|
||||
|
||||
private:
|
||||
FILE *fd_{nullptr};
|
||||
|
@ -35,7 +35,7 @@ ClientInterface::~ClientInterface() {
|
||||
}
|
||||
|
||||
ClientInterface::ClientInterface(int portNumber)
|
||||
: myDetectorType(GOTTHARD),
|
||||
: detType(GOTTHARD),
|
||||
portNumber(portNumber > 0 ? portNumber : DEFAULT_PORTNO + 2),
|
||||
server(portNumber) {
|
||||
functionTable();
|
||||
@ -334,7 +334,7 @@ int ClientInterface::setup_receiver(Interface &socket) {
|
||||
// basic setup
|
||||
setDetectorType(arg.detType);
|
||||
{
|
||||
int msize[2] = {arg.numberOfDetector.x, arg.numberOfDetector.y};
|
||||
int msize[2] = {arg.numberOfModule.x, arg.numberOfModule.y};
|
||||
impl()->setDetectorSize(msize);
|
||||
}
|
||||
impl()->setModulePositionId(arg.moduleIndex);
|
||||
@ -359,7 +359,7 @@ int ClientInterface::setup_receiver(Interface &socket) {
|
||||
}
|
||||
impl()->setUDPPortNumber(arg.udp_dstport);
|
||||
impl()->setUDPPortNumber2(arg.udp_dstport2);
|
||||
if (myDetectorType == JUNGFRAU || myDetectorType == GOTTHARD2) {
|
||||
if (detType == JUNGFRAU || detType == GOTTHARD2) {
|
||||
try {
|
||||
impl()->setNumberofUDPInterfaces(arg.udpInterfaces);
|
||||
} catch (const RuntimeError &e) {
|
||||
@ -372,13 +372,13 @@ int ClientInterface::setup_receiver(Interface &socket) {
|
||||
// acquisition parameters
|
||||
impl()->setNumberOfFrames(arg.frames);
|
||||
impl()->setNumberOfTriggers(arg.triggers);
|
||||
if (myDetectorType == GOTTHARD2) {
|
||||
if (detType == GOTTHARD2) {
|
||||
impl()->setNumberOfBursts(arg.bursts);
|
||||
}
|
||||
if (myDetectorType == JUNGFRAU) {
|
||||
if (detType == JUNGFRAU) {
|
||||
impl()->setNumberOfAdditionalStorageCells(arg.additionalStorageCells);
|
||||
}
|
||||
if (myDetectorType == MOENCH || myDetectorType == CHIPTESTBOARD) {
|
||||
if (detType == MOENCH || detType == CHIPTESTBOARD) {
|
||||
try {
|
||||
impl()->setNumberofAnalogSamples(arg.analogSamples);
|
||||
} catch (const RuntimeError &e) {
|
||||
@ -387,7 +387,7 @@ int ClientInterface::setup_receiver(Interface &socket) {
|
||||
" due to fifo structure memory allocation.");
|
||||
}
|
||||
}
|
||||
if (myDetectorType == CHIPTESTBOARD) {
|
||||
if (detType == CHIPTESTBOARD) {
|
||||
try {
|
||||
impl()->setNumberofDigitalSamples(arg.digitalSamples);
|
||||
} catch (const RuntimeError &e) {
|
||||
@ -396,11 +396,11 @@ int ClientInterface::setup_receiver(Interface &socket) {
|
||||
" due to fifo structure memory allocation.");
|
||||
}
|
||||
}
|
||||
if (myDetectorType != MYTHEN3) {
|
||||
if (detType != MYTHEN3) {
|
||||
impl()->setAcquisitionTime(std::chrono::nanoseconds(arg.expTimeNs));
|
||||
}
|
||||
impl()->setAcquisitionPeriod(std::chrono::nanoseconds(arg.periodNs));
|
||||
if (myDetectorType == EIGER) {
|
||||
if (detType == EIGER) {
|
||||
impl()->setSubExpTime(std::chrono::nanoseconds(arg.subExpTimeNs));
|
||||
impl()->setSubPeriod(std::chrono::nanoseconds(arg.subExpTimeNs) +
|
||||
std::chrono::nanoseconds(arg.subDeadTimeNs));
|
||||
@ -416,17 +416,17 @@ int ClientInterface::setup_receiver(Interface &socket) {
|
||||
}
|
||||
impl()->setThresholdEnergy(arg.thresholdEnergyeV[0]);
|
||||
}
|
||||
if (myDetectorType == EIGER || myDetectorType == JUNGFRAU) {
|
||||
if (detType == EIGER || detType == JUNGFRAU) {
|
||||
impl()->setReadNRows(arg.readNRows);
|
||||
}
|
||||
if (myDetectorType == MYTHEN3) {
|
||||
if (detType == MYTHEN3) {
|
||||
std::array<int, 3> val;
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
val[i] = arg.thresholdEnergyeV[i];
|
||||
}
|
||||
impl()->setThresholdEnergy(val);
|
||||
}
|
||||
if (myDetectorType == EIGER || myDetectorType == MYTHEN3) {
|
||||
if (detType == EIGER || detType == MYTHEN3) {
|
||||
try {
|
||||
impl()->setDynamicRange(arg.dynamicRange);
|
||||
} catch (const RuntimeError &e) {
|
||||
@ -436,15 +436,15 @@ int ClientInterface::setup_receiver(Interface &socket) {
|
||||
}
|
||||
}
|
||||
impl()->setTimingMode(arg.timMode);
|
||||
if (myDetectorType == EIGER || myDetectorType == MOENCH ||
|
||||
myDetectorType == CHIPTESTBOARD || myDetectorType == MYTHEN3) {
|
||||
if (detType == EIGER || detType == MOENCH || detType == CHIPTESTBOARD ||
|
||||
detType == MYTHEN3) {
|
||||
try {
|
||||
impl()->setTenGigaEnable(arg.tenGiga);
|
||||
} catch (const RuntimeError &e) {
|
||||
throw RuntimeError("Could not set 10GbE.");
|
||||
}
|
||||
}
|
||||
if (myDetectorType == CHIPTESTBOARD) {
|
||||
if (detType == CHIPTESTBOARD) {
|
||||
try {
|
||||
impl()->setReadoutMode(arg.roMode);
|
||||
} catch (const RuntimeError &e) {
|
||||
@ -452,7 +452,7 @@ int ClientInterface::setup_receiver(Interface &socket) {
|
||||
"due to fifo memory allocation.");
|
||||
}
|
||||
}
|
||||
if (myDetectorType == CHIPTESTBOARD || myDetectorType == MOENCH) {
|
||||
if (detType == CHIPTESTBOARD || detType == MOENCH) {
|
||||
try {
|
||||
impl()->setADCEnableMask(arg.adcMask);
|
||||
} catch (const RuntimeError &e) {
|
||||
@ -466,14 +466,14 @@ int ClientInterface::setup_receiver(Interface &socket) {
|
||||
"due to fifo memory allcoation");
|
||||
}
|
||||
}
|
||||
if (myDetectorType == GOTTHARD) {
|
||||
if (detType == GOTTHARD) {
|
||||
try {
|
||||
impl()->setROI(arg.roi);
|
||||
} catch (const RuntimeError &e) {
|
||||
throw RuntimeError("Could not set ROI");
|
||||
}
|
||||
}
|
||||
if (myDetectorType == MYTHEN3) {
|
||||
if (detType == MYTHEN3) {
|
||||
impl()->setCounterMask(arg.countermask);
|
||||
impl()->setAcquisitionTime1(std::chrono::nanoseconds(arg.expTime1Ns));
|
||||
impl()->setAcquisitionTime2(std::chrono::nanoseconds(arg.expTime2Ns));
|
||||
@ -483,7 +483,7 @@ int ClientInterface::setup_receiver(Interface &socket) {
|
||||
impl()->setGateDelay3(std::chrono::nanoseconds(arg.gateDelay3Ns));
|
||||
impl()->setNumberOfGates(arg.gates);
|
||||
}
|
||||
if (myDetectorType == GOTTHARD2) {
|
||||
if (detType == GOTTHARD2) {
|
||||
impl()->setBurstMode(arg.burstType);
|
||||
}
|
||||
impl()->setScan(arg.scanParams);
|
||||
@ -507,9 +507,9 @@ void ClientInterface::setDetectorType(detectorType arg) {
|
||||
}
|
||||
|
||||
try {
|
||||
myDetectorType = GENERIC;
|
||||
detType = GENERIC;
|
||||
receiver = sls::make_unique<Implementation>(arg);
|
||||
myDetectorType = arg;
|
||||
detType = arg;
|
||||
} catch (...) {
|
||||
throw RuntimeError("Could not set detector type");
|
||||
}
|
||||
@ -535,7 +535,7 @@ int ClientInterface::set_roi(Interface &socket) {
|
||||
auto arg = socket.Receive<ROI>();
|
||||
LOG(logDEBUG1) << "Set ROI: [" << arg.xmin << ", " << arg.xmax << "]";
|
||||
|
||||
if (myDetectorType != GOTTHARD)
|
||||
if (detType != GOTTHARD)
|
||||
functionNotImplemented();
|
||||
|
||||
verifyIdle(socket);
|
||||
@ -616,7 +616,7 @@ int ClientInterface::set_burst_mode(Interface &socket) {
|
||||
int ClientInterface::set_num_analog_samples(Interface &socket) {
|
||||
auto value = socket.Receive<int>();
|
||||
LOG(logDEBUG1) << "Setting num analog samples to " << value;
|
||||
if (myDetectorType != CHIPTESTBOARD && myDetectorType != MOENCH) {
|
||||
if (detType != CHIPTESTBOARD && detType != MOENCH) {
|
||||
functionNotImplemented();
|
||||
}
|
||||
try {
|
||||
@ -632,7 +632,7 @@ int ClientInterface::set_num_analog_samples(Interface &socket) {
|
||||
int ClientInterface::set_num_digital_samples(Interface &socket) {
|
||||
auto value = socket.Receive<int>();
|
||||
LOG(logDEBUG1) << "Setting num digital samples to " << value;
|
||||
if (myDetectorType != CHIPTESTBOARD) {
|
||||
if (detType != CHIPTESTBOARD) {
|
||||
functionNotImplemented();
|
||||
}
|
||||
try {
|
||||
@ -654,7 +654,7 @@ int ClientInterface::set_exptime(Interface &socket) {
|
||||
<< " (gateIndex: " << gateIndex << ")";
|
||||
switch (gateIndex) {
|
||||
case -1:
|
||||
if (myDetectorType == MYTHEN3) {
|
||||
if (detType == MYTHEN3) {
|
||||
impl()->setAcquisitionTime1(value);
|
||||
impl()->setAcquisitionTime2(value);
|
||||
impl()->setAcquisitionTime3(value);
|
||||
@ -663,19 +663,19 @@ int ClientInterface::set_exptime(Interface &socket) {
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
if (myDetectorType != MYTHEN3) {
|
||||
if (detType != MYTHEN3) {
|
||||
functionNotImplemented();
|
||||
}
|
||||
impl()->setAcquisitionTime1(value);
|
||||
break;
|
||||
case 1:
|
||||
if (myDetectorType != MYTHEN3) {
|
||||
if (detType != MYTHEN3) {
|
||||
functionNotImplemented();
|
||||
}
|
||||
impl()->setAcquisitionTime2(value);
|
||||
break;
|
||||
case 2:
|
||||
if (myDetectorType != MYTHEN3) {
|
||||
if (detType != MYTHEN3) {
|
||||
functionNotImplemented();
|
||||
}
|
||||
impl()->setAcquisitionTime3(value);
|
||||
@ -723,19 +723,19 @@ int ClientInterface::set_dynamic_range(Interface &socket) {
|
||||
exists = true;
|
||||
break;
|
||||
/*case 1: //TODO: Not yet implemented in firmware
|
||||
if (myDetectorType == MYTHEN3) {
|
||||
if (detType == MYTHEN3) {
|
||||
exists = true;
|
||||
}
|
||||
break;
|
||||
*/
|
||||
case 4:
|
||||
if (myDetectorType == EIGER) {
|
||||
if (detType == EIGER) {
|
||||
exists = true;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
case 32:
|
||||
if (myDetectorType == EIGER || myDetectorType == MYTHEN3) {
|
||||
if (detType == EIGER || detType == MYTHEN3) {
|
||||
exists = true;
|
||||
}
|
||||
break;
|
||||
@ -935,8 +935,8 @@ int ClientInterface::get_overwrite(Interface &socket) {
|
||||
|
||||
int ClientInterface::enable_tengiga(Interface &socket) {
|
||||
auto val = socket.Receive<int>();
|
||||
if (myDetectorType != EIGER && myDetectorType != CHIPTESTBOARD &&
|
||||
myDetectorType != MOENCH && myDetectorType != MYTHEN3)
|
||||
if (detType != EIGER && detType != CHIPTESTBOARD && detType != MOENCH &&
|
||||
detType != MYTHEN3)
|
||||
functionNotImplemented();
|
||||
|
||||
if (val >= 0) {
|
||||
@ -974,7 +974,7 @@ int ClientInterface::set_fifo_depth(Interface &socket) {
|
||||
|
||||
int ClientInterface::set_activate(Interface &socket) {
|
||||
auto enable = socket.Receive<int>();
|
||||
if (myDetectorType != EIGER)
|
||||
if (detType != EIGER)
|
||||
functionNotImplemented();
|
||||
|
||||
if (enable >= 0) {
|
||||
@ -1025,7 +1025,7 @@ int ClientInterface::set_streaming_timer(Interface &socket) {
|
||||
}
|
||||
|
||||
int ClientInterface::get_flip_rows(Interface &socket) {
|
||||
if (myDetectorType != EIGER)
|
||||
if (detType != EIGER)
|
||||
functionNotImplemented();
|
||||
|
||||
int retval = impl()->getFlipRows();
|
||||
@ -1036,7 +1036,7 @@ int ClientInterface::get_flip_rows(Interface &socket) {
|
||||
int ClientInterface::set_flip_rows(Interface &socket) {
|
||||
auto arg = socket.Receive<int>();
|
||||
|
||||
if (myDetectorType != EIGER)
|
||||
if (detType != EIGER)
|
||||
functionNotImplemented();
|
||||
|
||||
if (arg != 0 && arg != 1) {
|
||||
@ -1277,7 +1277,7 @@ int ClientInterface::get_padding_enable(Interface &socket) {
|
||||
|
||||
int ClientInterface::set_deactivated_padding_enable(Interface &socket) {
|
||||
auto enable = socket.Receive<int>();
|
||||
if (myDetectorType != EIGER) {
|
||||
if (detType != EIGER) {
|
||||
functionNotImplemented();
|
||||
}
|
||||
if (enable < 0) {
|
||||
@ -1291,7 +1291,7 @@ int ClientInterface::set_deactivated_padding_enable(Interface &socket) {
|
||||
}
|
||||
|
||||
int ClientInterface::get_deactivated_padding_enable(Interface &socket) {
|
||||
if (myDetectorType != EIGER)
|
||||
if (detType != EIGER)
|
||||
functionNotImplemented();
|
||||
auto retval = static_cast<int>(impl()->getDeactivatedPadding());
|
||||
LOG(logDEBUG1) << "Deactivated Padding Enable: " << retval;
|
||||
@ -1301,7 +1301,7 @@ int ClientInterface::get_deactivated_padding_enable(Interface &socket) {
|
||||
int ClientInterface::set_readout_mode(Interface &socket) {
|
||||
auto arg = socket.Receive<readoutMode>();
|
||||
|
||||
if (myDetectorType != CHIPTESTBOARD)
|
||||
if (detType != CHIPTESTBOARD)
|
||||
functionNotImplemented();
|
||||
|
||||
if (arg >= 0) {
|
||||
@ -1345,7 +1345,7 @@ int ClientInterface::set_adc_mask(Interface &socket) {
|
||||
int ClientInterface::set_dbit_list(Interface &socket) {
|
||||
sls::StaticVector<int, MAX_RX_DBIT> args;
|
||||
socket.Receive(args);
|
||||
if (myDetectorType != CHIPTESTBOARD)
|
||||
if (detType != CHIPTESTBOARD)
|
||||
functionNotImplemented();
|
||||
LOG(logDEBUG1) << "Setting DBIT list";
|
||||
for (auto &it : args) {
|
||||
@ -1358,7 +1358,7 @@ int ClientInterface::set_dbit_list(Interface &socket) {
|
||||
}
|
||||
|
||||
int ClientInterface::get_dbit_list(Interface &socket) {
|
||||
if (myDetectorType != CHIPTESTBOARD)
|
||||
if (detType != CHIPTESTBOARD)
|
||||
functionNotImplemented();
|
||||
sls::StaticVector<int, MAX_RX_DBIT> retval;
|
||||
retval = impl()->getDbitList();
|
||||
@ -1368,7 +1368,7 @@ int ClientInterface::get_dbit_list(Interface &socket) {
|
||||
|
||||
int ClientInterface::set_dbit_offset(Interface &socket) {
|
||||
auto arg = socket.Receive<int>();
|
||||
if (myDetectorType != CHIPTESTBOARD)
|
||||
if (detType != CHIPTESTBOARD)
|
||||
functionNotImplemented();
|
||||
if (arg < 0) {
|
||||
throw RuntimeError("Invalid dbit offset: " + std::to_string(arg));
|
||||
@ -1380,7 +1380,7 @@ int ClientInterface::set_dbit_offset(Interface &socket) {
|
||||
}
|
||||
|
||||
int ClientInterface::get_dbit_offset(Interface &socket) {
|
||||
if (myDetectorType != CHIPTESTBOARD)
|
||||
if (detType != CHIPTESTBOARD)
|
||||
functionNotImplemented();
|
||||
int retval = impl()->getDbitOffset();
|
||||
LOG(logDEBUG1) << "Dbit offset retval: " << retval;
|
||||
@ -1410,7 +1410,7 @@ int ClientInterface::set_read_n_rows(Interface &socket) {
|
||||
auto arg = socket.Receive<int>();
|
||||
if (arg >= 0) {
|
||||
verifyIdle(socket);
|
||||
if (myDetectorType != EIGER && myDetectorType != JUNGFRAU) {
|
||||
if (detType != EIGER && detType != JUNGFRAU) {
|
||||
throw RuntimeError("Could not set number of rows. Not implemented for this detector");
|
||||
}
|
||||
LOG(logDEBUG1) << "Setting number of rows:" << arg;
|
||||
@ -1436,7 +1436,7 @@ sls::MacAddr ClientInterface::setUdpIp(sls::IpAddr arg) {
|
||||
<< ". Got " << eth;
|
||||
}
|
||||
impl()->setEthernetInterface(eth);
|
||||
if (myDetectorType == EIGER) {
|
||||
if (detType == EIGER) {
|
||||
impl()->setEthernetInterface2(eth);
|
||||
}
|
||||
// get mac address
|
||||
@ -1485,7 +1485,7 @@ sls::MacAddr ClientInterface::setUdpIp2(sls::IpAddr arg) {
|
||||
int ClientInterface::set_udp_ip2(Interface &socket) {
|
||||
auto arg = socket.Receive<sls::IpAddr>();
|
||||
verifyIdle(socket);
|
||||
if (myDetectorType != JUNGFRAU && myDetectorType != GOTTHARD2) {
|
||||
if (detType != JUNGFRAU && detType != GOTTHARD2) {
|
||||
throw RuntimeError(
|
||||
"UDP Destination IP2 not implemented for this detector");
|
||||
}
|
||||
@ -1504,8 +1504,7 @@ int ClientInterface::set_udp_port(Interface &socket) {
|
||||
int ClientInterface::set_udp_port2(Interface &socket) {
|
||||
auto arg = socket.Receive<int>();
|
||||
verifyIdle(socket);
|
||||
if (myDetectorType != JUNGFRAU && myDetectorType != EIGER &&
|
||||
myDetectorType != GOTTHARD2) {
|
||||
if (detType != JUNGFRAU && detType != EIGER && detType != GOTTHARD2) {
|
||||
throw RuntimeError(
|
||||
"UDP Destination Port2 not implemented for this detector");
|
||||
}
|
||||
@ -1518,7 +1517,7 @@ int ClientInterface::set_num_interfaces(Interface &socket) {
|
||||
auto arg = socket.Receive<int>();
|
||||
arg = (arg > 1 ? 2 : 1);
|
||||
verifyIdle(socket);
|
||||
if (myDetectorType != JUNGFRAU && myDetectorType != GOTTHARD2) {
|
||||
if (detType != JUNGFRAU && detType != GOTTHARD2) {
|
||||
throw RuntimeError(
|
||||
"Number of interfaces not implemented for this detector");
|
||||
}
|
||||
@ -1596,7 +1595,7 @@ int ClientInterface::get_progress(Interface &socket) {
|
||||
int ClientInterface::set_num_gates(Interface &socket) {
|
||||
auto value = socket.Receive<int>();
|
||||
LOG(logDEBUG1) << "Setting num gates to " << value;
|
||||
if (myDetectorType != MYTHEN3) {
|
||||
if (detType != MYTHEN3) {
|
||||
functionNotImplemented();
|
||||
}
|
||||
impl()->setNumberOfGates(value);
|
||||
@ -1610,7 +1609,7 @@ int ClientInterface::set_gate_delay(Interface &socket) {
|
||||
auto value = std::chrono::nanoseconds(args[1]);
|
||||
LOG(logDEBUG1) << "Setting gate delay to " << sls::ToString(value)
|
||||
<< " (gateIndex: " << gateIndex << ")";
|
||||
if (myDetectorType != MYTHEN3) {
|
||||
if (detType != MYTHEN3) {
|
||||
functionNotImplemented();
|
||||
}
|
||||
switch (gateIndex) {
|
||||
@ -1685,7 +1684,7 @@ int ClientInterface::set_scan(Interface &socket) {
|
||||
int ClientInterface::set_threshold(Interface &socket) {
|
||||
auto arg = socket.Receive<int>();
|
||||
LOG(logDEBUG) << "Threshold: " << arg << " eV";
|
||||
if (myDetectorType != EIGER)
|
||||
if (detType != EIGER)
|
||||
functionNotImplemented();
|
||||
verifyIdle(socket);
|
||||
impl()->setThresholdEnergy(arg);
|
||||
@ -1712,7 +1711,7 @@ int ClientInterface::set_streaming_hwm(Interface &socket) {
|
||||
int ClientInterface::set_all_threshold(Interface &socket) {
|
||||
auto eVs = socket.Receive<std::array<int, 3>>();
|
||||
LOG(logDEBUG) << "Threshold:" << sls::ToString(eVs);
|
||||
if (myDetectorType != MYTHEN3)
|
||||
if (detType != MYTHEN3)
|
||||
functionNotImplemented();
|
||||
verifyIdle(socket);
|
||||
impl()->setThresholdEnergy(eVs);
|
||||
@ -1733,7 +1732,7 @@ int ClientInterface::set_detector_datastream(Interface &socket) {
|
||||
bool enable = static_cast<int>(args[1]);
|
||||
LOG(logDEBUG1) << "Setting datastream (" << sls::ToString(port) << ") to "
|
||||
<< sls::ToString(enable);
|
||||
if (myDetectorType != EIGER)
|
||||
if (detType != EIGER)
|
||||
functionNotImplemented();
|
||||
verifyIdle(socket);
|
||||
impl()->setDetectorDataStream(port, enable);
|
||||
|
@ -11,7 +11,7 @@ class ServerInterface;
|
||||
|
||||
class ClientInterface : private virtual slsDetectorDefs {
|
||||
enum numberMode { DEC, HEX };
|
||||
detectorType myDetectorType;
|
||||
detectorType detType;
|
||||
int portNumber{0};
|
||||
sls::ServerSocket server;
|
||||
std::unique_ptr<Implementation> receiver;
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "HDF5VirtualFile.h"
|
||||
#endif
|
||||
#include "DataStreamer.h"
|
||||
#include "sls/container_utils.h"
|
||||
#include "sls/sls_detector_exceptions.h"
|
||||
|
||||
#include <cerrno>
|
||||
@ -56,6 +57,10 @@ bool DataProcessor::GetStartedFlag() { return startedFlag_; }
|
||||
|
||||
uint64_t DataProcessor::GetNumFramesCaught() { return numFramesCaught_; }
|
||||
|
||||
uint64_t DataProcessor::GetNumCompleteFramesCaught() {
|
||||
return numCompleteFramesCaught_;
|
||||
}
|
||||
|
||||
uint64_t DataProcessor::GetCurrentFrameIndex() { return currentFrameIndex_; }
|
||||
|
||||
uint64_t DataProcessor::GetProcessedIndex() {
|
||||
@ -68,6 +73,7 @@ void DataProcessor::ResetParametersforNewAcquisition() {
|
||||
StopRunning();
|
||||
startedFlag_ = false;
|
||||
numFramesCaught_ = 0;
|
||||
numCompleteFramesCaught_ = 0;
|
||||
firstIndex_ = 0;
|
||||
currentFrameIndex_ = 0;
|
||||
firstStreamerFrame_ = true;
|
||||
@ -248,6 +254,41 @@ void DataProcessor::LinkDataInMasterFile(const bool silentMode) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void DataProcessor::UpdateMasterFile(bool silentMode) {
|
||||
if (masterFile_) {
|
||||
// final attributes
|
||||
std::unique_ptr<MasterAttributes> masterAttributes;
|
||||
switch (detectorType_) {
|
||||
case GOTTHARD:
|
||||
masterAttributes = sls::make_unique<GotthardMasterAttributes>();
|
||||
break;
|
||||
case JUNGFRAU:
|
||||
masterAttributes = sls::make_unique<JungfrauMasterAttributes>();
|
||||
break;
|
||||
case EIGER:
|
||||
masterAttributes = sls::make_unique<EigerMasterAttributes>();
|
||||
break;
|
||||
case MYTHEN3:
|
||||
masterAttributes = sls::make_unique<Mythen3MasterAttributes>();
|
||||
break;
|
||||
case GOTTHARD2:
|
||||
masterAttributes = sls::make_unique<Gotthard2MasterAttributes>();
|
||||
break;
|
||||
case MOENCH:
|
||||
masterAttributes = sls::make_unique<MoenchMasterAttributes>();
|
||||
break;
|
||||
case CHIPTESTBOARD:
|
||||
masterAttributes = sls::make_unique<CtbMasterAttributes>();
|
||||
break;
|
||||
default:
|
||||
throw sls::RuntimeError(
|
||||
"Unknown detector type to set up master file attributes");
|
||||
}
|
||||
masterAttributes->framesInFile = numFramesCaught_;
|
||||
masterFile_->UpdateMasterFile(masterAttributes.get(), silentMode);
|
||||
}
|
||||
}
|
||||
|
||||
void DataProcessor::ThreadExecution() {
|
||||
char *buffer = nullptr;
|
||||
fifo_->PopAddress(buffer);
|
||||
@ -306,9 +347,10 @@ uint64_t DataProcessor::ProcessAnImage(char *buf) {
|
||||
sls_detector_header header = rheader->detHeader;
|
||||
uint64_t fnum = header.frameNumber;
|
||||
currentFrameIndex_ = fnum;
|
||||
numFramesCaught_++;
|
||||
uint32_t nump = header.packetNumber;
|
||||
if (nump == generalData_->packetsPerFrame) {
|
||||
numFramesCaught_++;
|
||||
numCompleteFramesCaught_++;
|
||||
}
|
||||
|
||||
LOG(logDEBUG1) << "DataProcessing " << index << ": fnum:" << fnum;
|
||||
|
@ -37,6 +37,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
|
||||
|
||||
bool GetStartedFlag();
|
||||
uint64_t GetNumFramesCaught();
|
||||
uint64_t GetNumCompleteFramesCaught();
|
||||
/** (-1 if no frames have been caught */
|
||||
uint64_t GetCurrentFrameIndex();
|
||||
/** (-1 if no frames have been caught) */
|
||||
@ -76,6 +77,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
|
||||
const int numModY);
|
||||
void LinkDataInMasterFile(const bool silentMode);
|
||||
#endif
|
||||
void UpdateMasterFile(bool silentMode);
|
||||
/**
|
||||
* Call back for raw data
|
||||
* args to raw data ready callback are
|
||||
@ -174,9 +176,12 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
|
||||
std::atomic<uint64_t> firstIndex_{0};
|
||||
|
||||
// for statistics
|
||||
/** Number of complete frames caught */
|
||||
/** Number of frames caught */
|
||||
uint64_t numFramesCaught_{0};
|
||||
|
||||
/** Number of complete frames caught */
|
||||
uint64_t numCompleteFramesCaught_{0};
|
||||
|
||||
/** Frame Number of latest processed frame number */
|
||||
std::atomic<uint64_t> currentFrameIndex_{0};
|
||||
|
||||
|
@ -118,6 +118,11 @@ class File : private virtual slsDetectorDefs {
|
||||
"should be overloaded by a derived class";
|
||||
};
|
||||
|
||||
virtual void UpdateMasterFile(MasterAttributes *attr, bool silentMode) {
|
||||
LOG(logERROR) << "This is a generic function UpdateMasterFile that "
|
||||
"should be overloaded by a derived class";
|
||||
};
|
||||
|
||||
protected:
|
||||
slsDetectorDefs::fileFormat format_;
|
||||
};
|
||||
|
@ -117,6 +117,9 @@ void HDF5MasterFile::CreateMasterFile(const std::string filePath,
|
||||
Group group5(group3.createGroup("detector"));
|
||||
Group group6(group1.createGroup("sample"));
|
||||
|
||||
// TODO find a way to get complete group link
|
||||
attrGroupName_ = "/entry/instrument/detector";
|
||||
|
||||
attr->WriteMasterHDF5Attributes(fd_, &group5);
|
||||
fd_->close();
|
||||
|
||||
@ -130,3 +133,28 @@ void HDF5MasterFile::CreateMasterFile(const std::string filePath,
|
||||
LOG(logINFO) << "Master File: " << fileName_;
|
||||
}
|
||||
}
|
||||
|
||||
void HDF5MasterFile::UpdateMasterFile(MasterAttributes *attr, bool silentMode) {
|
||||
std::lock_guard<std::mutex> lock(*hdf5Lib_);
|
||||
|
||||
try {
|
||||
Exception::dontPrint(); // to handle errors
|
||||
FileAccPropList flist;
|
||||
flist.setFcloseDegree(H5F_CLOSE_STRONG);
|
||||
fd_ = new H5File(fileName_.c_str(), H5F_ACC_RDWR,
|
||||
FileCreatPropList::DEFAULT, flist);
|
||||
|
||||
Group group = fd_->openGroup(attrGroupName_.c_str());
|
||||
attr->WriteFinalHDF5Attributes(fd_, &group);
|
||||
fd_->close();
|
||||
|
||||
} catch (const Exception &error) {
|
||||
error.printErrorStack();
|
||||
CloseFile();
|
||||
throw sls::RuntimeError(
|
||||
"Could not create/overwrite master HDF5 handles");
|
||||
}
|
||||
if (!silentMode) {
|
||||
LOG(logINFO) << "Updated Master File";
|
||||
}
|
||||
}
|
@ -19,9 +19,11 @@ class HDF5MasterFile : private virtual slsDetectorDefs, public File {
|
||||
const uint64_t fileIndex, const bool overWriteEnable,
|
||||
const bool silentMode,
|
||||
MasterAttributes *attr) override;
|
||||
void UpdateMasterFile(MasterAttributes *attr, bool silentMode) override;
|
||||
|
||||
private:
|
||||
std::mutex *hdf5Lib_;
|
||||
H5File *fd_{nullptr};
|
||||
std::string fileName_;
|
||||
std::string attrGroupName_;
|
||||
};
|
@ -429,7 +429,7 @@ uint64_t Implementation::getFramesCaught() const {
|
||||
|
||||
for (const auto &it : dataProcessor) {
|
||||
flagsum += it->GetStartedFlag();
|
||||
min = std::min(min, it->GetNumFramesCaught());
|
||||
min = std::min(min, it->GetNumCompleteFramesCaught());
|
||||
}
|
||||
// no data processed
|
||||
if (flagsum != dataProcessor.size())
|
||||
@ -571,6 +571,13 @@ void Implementation::stopReceiver() {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (fileWriteEnable && masterFileWriteEnable && modulePos == 0) {
|
||||
try {
|
||||
dataProcessor[0]->UpdateMasterFile(silentMode);
|
||||
} catch (...) {
|
||||
; // ignore it and just print it
|
||||
}
|
||||
}
|
||||
|
||||
// wait for the processes (dataStreamer) to be done
|
||||
running = true;
|
||||
@ -589,7 +596,7 @@ void Implementation::stopReceiver() {
|
||||
std::vector<uint64_t> mp = getNumMissingPackets();
|
||||
uint64_t tot = 0;
|
||||
for (int i = 0; i < numThreads; i++) {
|
||||
int nf = dataProcessor[i]->GetNumFramesCaught();
|
||||
int nf = dataProcessor[i]->GetNumCompleteFramesCaught();
|
||||
tot += nf;
|
||||
std::string mpMessage = std::to_string((int64_t)mp[i]);
|
||||
if ((int64_t)mp[i] < 0) {
|
||||
|
@ -16,6 +16,7 @@ using namespace H5;
|
||||
using ns = std::chrono::nanoseconds;
|
||||
|
||||
struct MasterAttributes {
|
||||
// (before acquisition)
|
||||
slsDetectorDefs::detectorType detType{slsDetectorDefs::GENERIC};
|
||||
slsDetectorDefs::timingMode timingMode{slsDetectorDefs::AUTO_TIMING};
|
||||
uint32_t imageSize{0};
|
||||
@ -57,6 +58,9 @@ struct MasterAttributes {
|
||||
uint32_t gates;
|
||||
std::map<std::string, std::string> additionalJsonHeader;
|
||||
|
||||
// Final Attributes (after acquisition)
|
||||
uint64_t framesInFile{0};
|
||||
|
||||
MasterAttributes(){};
|
||||
virtual ~MasterAttributes(){};
|
||||
|
||||
@ -87,30 +91,42 @@ struct MasterAttributes {
|
||||
};
|
||||
|
||||
void WriteBinaryAttributes(FILE *fd, std::string message) {
|
||||
if (fwrite((void *)message.c_str(), 1, message.length(), fd) !=
|
||||
message.length()) {
|
||||
throw sls::RuntimeError(
|
||||
"Master binary file incorrect number of bytes written to file");
|
||||
}
|
||||
};
|
||||
|
||||
void WriteFinalBinaryAttributes(FILE *fd) {
|
||||
// adding few common parameters to the end
|
||||
if (!additionalJsonHeader.empty()) {
|
||||
std::ostringstream oss;
|
||||
|
||||
if (!additionalJsonHeader.empty()) {
|
||||
oss << "Additional Json Header : "
|
||||
<< sls::ToString(additionalJsonHeader) << '\n';
|
||||
message += oss.str();
|
||||
}
|
||||
oss << "Frames in File : " << framesInFile << '\n';
|
||||
|
||||
// adding sls_receiver header format
|
||||
message += std::string("\n#Frame Header\n"
|
||||
"Frame Number : 8 bytes\n"
|
||||
"SubFrame Number/ExpLength : 4 bytes\n"
|
||||
"Packet Number : 4 bytes\n"
|
||||
"Bunch ID : 8 bytes\n"
|
||||
"Timestamp : 8 bytes\n"
|
||||
"Module Id : 2 bytes\n"
|
||||
"Row : 2 bytes\n"
|
||||
"Column : 2 bytes\n"
|
||||
"Reserved : 2 bytes\n"
|
||||
"Debug : 4 bytes\n"
|
||||
"Round Robin Number : 2 bytes\n"
|
||||
"Detector Type : 1 byte\n"
|
||||
"Header Version : 1 byte\n"
|
||||
"Packets Caught Mask : 64 bytes\n");
|
||||
oss << '\n'
|
||||
<< "#Frame Header" << '\n'
|
||||
<< "Frame Number : 8 bytes" << '\n'
|
||||
<< "SubFrame Number/ExpLength : 4 bytes" << '\n'
|
||||
<< "Packet Number : 4 bytes" << '\n'
|
||||
<< "Bunch ID : 8 bytes" << '\n'
|
||||
<< "Timestamp : 8 bytes" << '\n'
|
||||
<< "Module Id : 2 bytes" << '\n'
|
||||
<< "Row : 2 bytes" << '\n'
|
||||
<< "Column : 2 bytes" << '\n'
|
||||
<< "Reserved : 2 bytes" << '\n'
|
||||
<< "Debug : 4 bytes" << '\n'
|
||||
<< "Round Robin Number : 2 bytes" << '\n'
|
||||
<< "Detector Type : 1 byte" << '\n'
|
||||
<< "Header Version : 1 byte" << '\n'
|
||||
<< "Packets Caught Mask : 64 bytes" << '\n';
|
||||
|
||||
std::string message = oss.str();
|
||||
|
||||
// writing to file
|
||||
if (fwrite((void *)message.c_str(), 1, message.length(), fd) !=
|
||||
@ -233,6 +249,18 @@ struct MasterAttributes {
|
||||
"Total Frames", PredType::STD_U64LE, dataspace);
|
||||
dataset.write(&totalFrames, PredType::STD_U64LE);
|
||||
}
|
||||
};
|
||||
|
||||
void WriteFinalHDF5Attributes(H5File *fd, Group *group) {
|
||||
char c[1024];
|
||||
memset(c, 0, sizeof(c));
|
||||
// Total Frames in file
|
||||
{
|
||||
DataSpace dataspace = DataSpace(H5S_SCALAR);
|
||||
DataSet dataset = group->createDataSet(
|
||||
"Frames in File", PredType::STD_U64LE, dataspace);
|
||||
dataset.write(&framesInFile, PredType::STD_U64LE);
|
||||
}
|
||||
// additional json header
|
||||
if (!additionalJsonHeader.empty()) {
|
||||
std::string json = sls::ToString(additionalJsonHeader);
|
||||
|
@ -10,7 +10,7 @@ set(SOURCES
|
||||
src/ZmqSocket.cpp
|
||||
src/UdpRxSocket.cpp
|
||||
src/sls_detector_exceptions.cpp
|
||||
# src/sls_detector_defs.cpp
|
||||
src/md5_helper.cpp
|
||||
)
|
||||
|
||||
# Header files to install as a part of the library
|
||||
@ -44,9 +44,25 @@ if(SLS_DEVEL_HEADERS)
|
||||
include/sls/versionAPI.h
|
||||
include/sls/ZmqSocket.h
|
||||
include/sls/bit_utils.h
|
||||
include/sls/mdf5.h
|
||||
include/sls/md5_helper.h
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
# Library for md5 c code that we are using (and potentially other c code)
|
||||
# Maybe this should be broken out into it's own folder etc.
|
||||
add_library(md5sls STATIC
|
||||
src/md5.c
|
||||
)
|
||||
|
||||
target_include_directories(md5sls
|
||||
PUBLIC
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
|
||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
|
||||
)
|
||||
|
||||
|
||||
# Create an object library to avoid building the library twice
|
||||
add_library(slsSupportObject OBJECT
|
||||
${SOURCES}
|
||||
@ -66,6 +82,7 @@ target_link_libraries(slsSupportObject
|
||||
rapidjson
|
||||
PRIVATE
|
||||
slsProjectWarnings
|
||||
md5sls
|
||||
)
|
||||
|
||||
if (SLS_USE_TESTS)
|
||||
@ -103,6 +120,9 @@ if((CMAKE_BUILD_TYPE STREQUAL "Release") AND SLS_LTO_AVAILABLE)
|
||||
set_property(TARGET ${SUPPORT_LIBRARY_TARGETS} PROPERTY INTERPROCEDURAL_OPTIMIZATION True)
|
||||
endif()
|
||||
|
||||
|
||||
list(APPEND SUPPORT_LIBRARY_TARGETS md5sls)
|
||||
|
||||
install(TARGETS ${SUPPORT_LIBRARY_TARGETS}
|
||||
EXPORT "${TARGETS_EXPORT_NAME}"
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
|
385
slsSupportLib/include/sls/md5.h
Normal file
385
slsSupportLib/include/sls/md5.h
Normal file
@ -0,0 +1,385 @@
|
||||
/*
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
/*
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modifications 2021 Paul Scherrer Institut
|
||||
* Removed most of the code that is not relevant for our scope.
|
||||
* Snippets copied from md5_local.h or md32_common.h has been marked
|
||||
*/
|
||||
|
||||
|
||||
#ifndef HEADER_MD5_H
|
||||
# define HEADER_MD5_H
|
||||
|
||||
# include <stddef.h>
|
||||
|
||||
|
||||
# ifdef __cplusplus
|
||||
/*
|
||||
* Modifications 2021 Paul Scherrer Institut
|
||||
* namespace sls added
|
||||
*/
|
||||
namespace sls {
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
/*
|
||||
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
* ! MD5_LONG has to be at least 32 bits wide. !
|
||||
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
*/
|
||||
# define MD5_LONG unsigned int
|
||||
# define MD5_CBLOCK 64
|
||||
# define MD5_LBLOCK (MD5_CBLOCK/4)
|
||||
# define MD5_DIGEST_LENGTH 16
|
||||
|
||||
/**
|
||||
* Modification 2021 Paul Scherrer Institut
|
||||
* Comment from md32_common.h
|
||||
*/
|
||||
/*-
|
||||
* This is a generic 32 bit "collector" for message digest algorithms.
|
||||
* Whenever needed it collects input character stream into chunks of
|
||||
* 32 bit values and invokes a block function that performs actual hash
|
||||
* calculations.
|
||||
*
|
||||
* Porting guide.
|
||||
*
|
||||
* Obligatory macros:
|
||||
*
|
||||
* DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN
|
||||
* this macro defines byte order of input stream.
|
||||
* HASH_CBLOCK
|
||||
* size of a unit chunk HASH_BLOCK operates on.
|
||||
* HASH_LONG
|
||||
* has to be at least 32 bit wide.
|
||||
* HASH_CTX
|
||||
* context structure that at least contains following
|
||||
* members:
|
||||
* typedef struct {
|
||||
* ...
|
||||
* HASH_LONG Nl,Nh;
|
||||
* either {
|
||||
* HASH_LONG data[HASH_LBLOCK];
|
||||
* unsigned char data[HASH_CBLOCK];
|
||||
* };
|
||||
* unsigned int num;
|
||||
* ...
|
||||
* } HASH_CTX;
|
||||
* data[] vector is expected to be zeroed upon first call to
|
||||
* HASH_UPDATE.
|
||||
* HASH_UPDATE
|
||||
* name of "Update" function, implemented here.
|
||||
* HASH_TRANSFORM
|
||||
* name of "Transform" function, implemented here.
|
||||
* HASH_FINAL
|
||||
* name of "Final" function, implemented here.
|
||||
* HASH_BLOCK_DATA_ORDER
|
||||
* name of "block" function capable of treating *unaligned* input
|
||||
* message in original (data) byte order, implemented externally.
|
||||
* HASH_MAKE_STRING
|
||||
* macro converting context variables to an ASCII hash string.
|
||||
*
|
||||
* MD5 example:
|
||||
*
|
||||
* #define DATA_ORDER_IS_LITTLE_ENDIAN
|
||||
*
|
||||
* #define HASH_LONG MD5_LONG
|
||||
* #define HASH_CTX MD5_CTX
|
||||
* #define HASH_CBLOCK MD5_CBLOCK
|
||||
* #define HASH_UPDATE MD5_Update_SLS
|
||||
* #define HASH_TRANSFORM MD5_Transform
|
||||
* #define HASH_FINAL MD5_Final_SLS
|
||||
* #define HASH_BLOCK_DATA_ORDER md5_block_data_order
|
||||
*/
|
||||
# define MD32_REG_T int
|
||||
|
||||
/**
|
||||
* Modification 2021 Paul Scherrer Institut
|
||||
* Made default little endian if big endian not defined
|
||||
*/
|
||||
#ifndef DATA_ORDER_IS_BIG_ENDIAN
|
||||
#define DATA_ORDER_IS_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Modification 2021 Paul Scherrer Institut
|
||||
* Macros exported from md32_common.h
|
||||
*/
|
||||
#define HASH_LONG MD5_LONG
|
||||
#define HASH_CTX MD5_CTX
|
||||
#define HASH_CBLOCK MD5_CBLOCK
|
||||
#define HASH_UPDATE MD5_Update_SLS
|
||||
#define HASH_TRANSFORM MD5_Transform
|
||||
#define HASH_FINAL MD5_Final_SLS
|
||||
#define HASH_BLOCK_DATA_ORDER md5_block_data_order
|
||||
#define HASH_MAKE_STRING(c,s) do { \
|
||||
unsigned long ll; \
|
||||
ll=(c)->A; (void)HOST_l2c(ll,(s)); \
|
||||
ll=(c)->B; (void)HOST_l2c(ll,(s)); \
|
||||
ll=(c)->C; (void)HOST_l2c(ll,(s)); \
|
||||
ll=(c)->D; (void)HOST_l2c(ll,(s)); \
|
||||
} while (0)
|
||||
#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
|
||||
#if defined(DATA_ORDER_IS_BIG_ENDIAN)
|
||||
|
||||
# define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \
|
||||
l|=(((unsigned long)(*((c)++)))<<16), \
|
||||
l|=(((unsigned long)(*((c)++)))<< 8), \
|
||||
l|=(((unsigned long)(*((c)++))) ) )
|
||||
# define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>>16)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>> 8)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l) )&0xff), \
|
||||
l)
|
||||
|
||||
#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
|
||||
|
||||
# define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \
|
||||
l|=(((unsigned long)(*((c)++)))<< 8), \
|
||||
l|=(((unsigned long)(*((c)++)))<<16), \
|
||||
l|=(((unsigned long)(*((c)++)))<<24) )
|
||||
# define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>> 8)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>>16)&0xff), \
|
||||
*((c)++)=(unsigned char)(((l)>>24)&0xff), \
|
||||
l)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct MD5state_st {
|
||||
MD5_LONG A, B, C, D;
|
||||
MD5_LONG Nl, Nh;
|
||||
MD5_LONG data[MD5_LBLOCK];
|
||||
unsigned int num;
|
||||
} MD5_CTX;
|
||||
|
||||
int MD5_Init_SLS(MD5_CTX *c);
|
||||
int MD5_Update_SLS(MD5_CTX *c, const void *data, size_t len);
|
||||
int MD5_Final_SLS(unsigned char *md, MD5_CTX *c);
|
||||
|
||||
/**
|
||||
* Modification 2021 Paul Scherrer Institut
|
||||
* from md32_common.h
|
||||
*/
|
||||
void md5_block_data_order(MD5_CTX *c, const void *p, size_t num);
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
|
||||
} // namespace sls
|
||||
# endif
|
||||
# endif
|
||||
|
7
slsSupportLib/include/sls/md5_helper.h
Normal file
7
slsSupportLib/include/sls/md5_helper.h
Normal file
@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace sls {
|
||||
std::string md5_calculate_checksum(char *buffer, ssize_t bytes);
|
||||
} // namespace sls
|
@ -54,7 +54,8 @@
|
||||
#define MAX_TRIMEN 100
|
||||
|
||||
/** maximum unit size of program sent to detector */
|
||||
#define MAX_FPGAPROGRAMSIZE (2 * 1024 * 1024)
|
||||
//#define MAX_FPGAPROGRAMSIZE (2 * 1024 * 1024)
|
||||
#define MAX_FPGAPROGRAMSIZE (128 * 1024)
|
||||
|
||||
#define GET_FLAG -1
|
||||
|
||||
@ -499,7 +500,7 @@ typedef struct {
|
||||
*/
|
||||
struct rxParameters {
|
||||
detectorType detType{GENERIC};
|
||||
xy numberOfDetector;
|
||||
xy numberOfModule;
|
||||
int moduleIndex{0};
|
||||
char hostname[MAX_STR_LENGTH];
|
||||
int udpInterfaces{1};
|
||||
|
@ -247,7 +247,7 @@ enum detFuncs {
|
||||
F_GET_DEST_UDP_LIST,
|
||||
F_SET_DEST_UDP_LIST,
|
||||
F_GET_NUM_DEST_UDP,
|
||||
F_SET_NUM_DEST_UDP,
|
||||
F_CLEAR_ALL_UDP_DEST,
|
||||
F_GET_UDP_FIRST_DEST,
|
||||
F_SET_UDP_FIRST_DEST,
|
||||
|
||||
@ -604,7 +604,7 @@ const char* getFunctionNameFromEnum(enum detFuncs func) {
|
||||
case F_GET_DEST_UDP_LIST: return "F_GET_DEST_UDP_LIST";
|
||||
case F_SET_DEST_UDP_LIST: return "F_SET_DEST_UDP_LIST";
|
||||
case F_GET_NUM_DEST_UDP: return "F_GET_NUM_DEST_UDP";
|
||||
case F_SET_NUM_DEST_UDP: return "F_SET_NUM_DEST_UDP";
|
||||
case F_CLEAR_ALL_UDP_DEST: return "F_CLEAR_ALL_UDP_DEST";
|
||||
case F_GET_UDP_FIRST_DEST: return "F_GET_UDP_FIRST_DEST";
|
||||
case F_SET_UDP_FIRST_DEST: return "F_SET_UDP_FIRST_DEST";
|
||||
|
||||
|
@ -1,14 +1,13 @@
|
||||
/** API versions */
|
||||
#define GITBRANCH "roundrobin"
|
||||
#define APILIB 0x210831
|
||||
#define APIRECEIVER 0x210831
|
||||
#define GITBRANCH "udp_numdst"
|
||||
|
||||
#define APICTB 0x210917
|
||||
#define APIGOTTHARD 0x210917
|
||||
#define APIMYTHEN3 0x210917
|
||||
#define APIMOENCH 0x210917
|
||||
#define APIEIGER 0x210917
|
||||
#define APILIB 0x210917
|
||||
#define APIRECEIVER 0x210917
|
||||
#define APIGUI 0x210819
|
||||
|
||||
|
||||
#define APICTB 0x210909
|
||||
#define APIGOTTHARD 0x210909
|
||||
#define APIGOTTHARD2 0x210909
|
||||
#define APIJUNGFRAU 0x210909
|
||||
#define APIMYTHEN3 0x210909
|
||||
#define APIMOENCH 0x210909
|
||||
#define APIEIGER 0x210909
|
||||
#define APIJUNGFRAU 0x210927
|
||||
#define APIGOTTHARD2 0x210927
|
||||
|
@ -26,8 +26,8 @@ std::ostream &operator<<(std::ostream &os, const slsDetectorDefs::ROI &roi) {
|
||||
std::string ToString(const slsDetectorDefs::rxParameters &r) {
|
||||
std::ostringstream oss;
|
||||
oss << '[' << "detType:" << r.detType << std::endl
|
||||
<< "numberOfDetector.x:" << r.numberOfDetector.x << std::endl
|
||||
<< "numberOfDetector.y:" << r.numberOfDetector.y << std::endl
|
||||
<< "numberOfModule.x:" << r.numberOfModule.x << std::endl
|
||||
<< "numberOfModule.y:" << r.numberOfModule.y << std::endl
|
||||
<< "moduleIndex:" << r.moduleIndex << std::endl
|
||||
<< "hostname:" << r.hostname << std::endl
|
||||
<< "udpInterfaces:" << r.udpInterfaces << std::endl
|
||||
|
515
slsSupportLib/src/md5.c
Normal file
515
slsSupportLib/src/md5.c
Normal file
@ -0,0 +1,515 @@
|
||||
/*
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
/*
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
/*
|
||||
* MD5 low level APIs are deprecated for public use, but still ok for
|
||||
* internal use.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modifications 2021 Paul Scherrer Institut
|
||||
* Removed most of the code that is not relevant for our scope
|
||||
* from md5_dgst.c and renamed to md5.c
|
||||
* from md32_common.h and replaced their macros with their defines
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/**
|
||||
* Modification 2021 Paul Scherrer Institut
|
||||
* Header included was md5_local.h
|
||||
* and string.h header was included
|
||||
* sls namespace added
|
||||
*/
|
||||
#include "sls/md5.h"
|
||||
#include <string.h>
|
||||
#ifdef __cplusplus
|
||||
namespace sls {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Modification 2021 Paul Scherrer Institut
|
||||
* Macros exported from md5_local.h
|
||||
*/
|
||||
#define F(b,c,d) ((((c) ^ (d)) & (b)) ^ (d))
|
||||
#define G(b,c,d) ((((b) ^ (c)) & (d)) ^ (c))
|
||||
#define H(b,c,d) ((b) ^ (c) ^ (d))
|
||||
#define I(b,c,d) (((~(d)) | (b)) ^ (c))
|
||||
|
||||
#define R0(a,b,c,d,k,s,t) { \
|
||||
a+=((k)+(t)+F((b),(c),(d))); \
|
||||
a=ROTATE(a,s); \
|
||||
a+=b; };
|
||||
|
||||
#define R1(a,b,c,d,k,s,t) { \
|
||||
a+=((k)+(t)+G((b),(c),(d))); \
|
||||
a=ROTATE(a,s); \
|
||||
a+=b; };
|
||||
|
||||
#define R2(a,b,c,d,k,s,t) { \
|
||||
a+=((k)+(t)+H((b),(c),(d))); \
|
||||
a=ROTATE(a,s); \
|
||||
a+=b; };
|
||||
|
||||
#define R3(a,b,c,d,k,s,t) { \
|
||||
a+=((k)+(t)+I((b),(c),(d))); \
|
||||
a=ROTATE(a,s); \
|
||||
a+=b; };
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Implemented from RFC1321 The MD5 Message-Digest Algorithm
|
||||
*/
|
||||
|
||||
#define INIT_DATA_A (unsigned long)0x67452301L
|
||||
#define INIT_DATA_B (unsigned long)0xefcdab89L
|
||||
#define INIT_DATA_C (unsigned long)0x98badcfeL
|
||||
#define INIT_DATA_D (unsigned long)0x10325476L
|
||||
|
||||
int MD5_Init_SLS(MD5_CTX *c)
|
||||
{
|
||||
memset(c, 0, sizeof(*c));
|
||||
c->A = INIT_DATA_A;
|
||||
c->B = INIT_DATA_B;
|
||||
c->C = INIT_DATA_C;
|
||||
c->D = INIT_DATA_D;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void md5_block_data_order(MD5_CTX *c, const void *data_, size_t num)
|
||||
{
|
||||
const unsigned char *data = data_;
|
||||
register unsigned MD32_REG_T A, B, C, D, l;
|
||||
/* See comment in crypto/sha/sha_local.h for details. */
|
||||
unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
|
||||
XX8, XX9, XX10, XX11, XX12, XX13, XX14, XX15;
|
||||
# define X(i) XX##i
|
||||
|
||||
A = c->A;
|
||||
B = c->B;
|
||||
C = c->C;
|
||||
D = c->D;
|
||||
|
||||
for (; num--;) {
|
||||
(void)HOST_c2l(data, l);
|
||||
X(0) = l;
|
||||
(void)HOST_c2l(data, l);
|
||||
X(1) = l;
|
||||
/* Round 0 */
|
||||
R0(A, B, C, D, X(0), 7, 0xd76aa478L);
|
||||
(void)HOST_c2l(data, l);
|
||||
X(2) = l;
|
||||
R0(D, A, B, C, X(1), 12, 0xe8c7b756L);
|
||||
(void)HOST_c2l(data, l);
|
||||
X(3) = l;
|
||||
R0(C, D, A, B, X(2), 17, 0x242070dbL);
|
||||
(void)HOST_c2l(data, l);
|
||||
X(4) = l;
|
||||
R0(B, C, D, A, X(3), 22, 0xc1bdceeeL);
|
||||
(void)HOST_c2l(data, l);
|
||||
X(5) = l;
|
||||
R0(A, B, C, D, X(4), 7, 0xf57c0fafL);
|
||||
(void)HOST_c2l(data, l);
|
||||
X(6) = l;
|
||||
R0(D, A, B, C, X(5), 12, 0x4787c62aL);
|
||||
(void)HOST_c2l(data, l);
|
||||
X(7) = l;
|
||||
R0(C, D, A, B, X(6), 17, 0xa8304613L);
|
||||
(void)HOST_c2l(data, l);
|
||||
X(8) = l;
|
||||
R0(B, C, D, A, X(7), 22, 0xfd469501L);
|
||||
(void)HOST_c2l(data, l);
|
||||
X(9) = l;
|
||||
R0(A, B, C, D, X(8), 7, 0x698098d8L);
|
||||
(void)HOST_c2l(data, l);
|
||||
X(10) = l;
|
||||
R0(D, A, B, C, X(9), 12, 0x8b44f7afL);
|
||||
(void)HOST_c2l(data, l);
|
||||
X(11) = l;
|
||||
R0(C, D, A, B, X(10), 17, 0xffff5bb1L);
|
||||
(void)HOST_c2l(data, l);
|
||||
X(12) = l;
|
||||
R0(B, C, D, A, X(11), 22, 0x895cd7beL);
|
||||
(void)HOST_c2l(data, l);
|
||||
X(13) = l;
|
||||
R0(A, B, C, D, X(12), 7, 0x6b901122L);
|
||||
(void)HOST_c2l(data, l);
|
||||
X(14) = l;
|
||||
R0(D, A, B, C, X(13), 12, 0xfd987193L);
|
||||
(void)HOST_c2l(data, l);
|
||||
X(15) = l;
|
||||
R0(C, D, A, B, X(14), 17, 0xa679438eL);
|
||||
R0(B, C, D, A, X(15), 22, 0x49b40821L);
|
||||
/* Round 1 */
|
||||
R1(A, B, C, D, X(1), 5, 0xf61e2562L);
|
||||
R1(D, A, B, C, X(6), 9, 0xc040b340L);
|
||||
R1(C, D, A, B, X(11), 14, 0x265e5a51L);
|
||||
R1(B, C, D, A, X(0), 20, 0xe9b6c7aaL);
|
||||
R1(A, B, C, D, X(5), 5, 0xd62f105dL);
|
||||
R1(D, A, B, C, X(10), 9, 0x02441453L);
|
||||
R1(C, D, A, B, X(15), 14, 0xd8a1e681L);
|
||||
R1(B, C, D, A, X(4), 20, 0xe7d3fbc8L);
|
||||
R1(A, B, C, D, X(9), 5, 0x21e1cde6L);
|
||||
R1(D, A, B, C, X(14), 9, 0xc33707d6L);
|
||||
R1(C, D, A, B, X(3), 14, 0xf4d50d87L);
|
||||
R1(B, C, D, A, X(8), 20, 0x455a14edL);
|
||||
R1(A, B, C, D, X(13), 5, 0xa9e3e905L);
|
||||
R1(D, A, B, C, X(2), 9, 0xfcefa3f8L);
|
||||
R1(C, D, A, B, X(7), 14, 0x676f02d9L);
|
||||
R1(B, C, D, A, X(12), 20, 0x8d2a4c8aL);
|
||||
/* Round 2 */
|
||||
R2(A, B, C, D, X(5), 4, 0xfffa3942L);
|
||||
R2(D, A, B, C, X(8), 11, 0x8771f681L);
|
||||
R2(C, D, A, B, X(11), 16, 0x6d9d6122L);
|
||||
R2(B, C, D, A, X(14), 23, 0xfde5380cL);
|
||||
R2(A, B, C, D, X(1), 4, 0xa4beea44L);
|
||||
R2(D, A, B, C, X(4), 11, 0x4bdecfa9L);
|
||||
R2(C, D, A, B, X(7), 16, 0xf6bb4b60L);
|
||||
R2(B, C, D, A, X(10), 23, 0xbebfbc70L);
|
||||
R2(A, B, C, D, X(13), 4, 0x289b7ec6L);
|
||||
R2(D, A, B, C, X(0), 11, 0xeaa127faL);
|
||||
R2(C, D, A, B, X(3), 16, 0xd4ef3085L);
|
||||
R2(B, C, D, A, X(6), 23, 0x04881d05L);
|
||||
R2(A, B, C, D, X(9), 4, 0xd9d4d039L);
|
||||
R2(D, A, B, C, X(12), 11, 0xe6db99e5L);
|
||||
R2(C, D, A, B, X(15), 16, 0x1fa27cf8L);
|
||||
R2(B, C, D, A, X(2), 23, 0xc4ac5665L);
|
||||
/* Round 3 */
|
||||
R3(A, B, C, D, X(0), 6, 0xf4292244L);
|
||||
R3(D, A, B, C, X(7), 10, 0x432aff97L);
|
||||
R3(C, D, A, B, X(14), 15, 0xab9423a7L);
|
||||
R3(B, C, D, A, X(5), 21, 0xfc93a039L);
|
||||
R3(A, B, C, D, X(12), 6, 0x655b59c3L);
|
||||
R3(D, A, B, C, X(3), 10, 0x8f0ccc92L);
|
||||
R3(C, D, A, B, X(10), 15, 0xffeff47dL);
|
||||
R3(B, C, D, A, X(1), 21, 0x85845dd1L);
|
||||
R3(A, B, C, D, X(8), 6, 0x6fa87e4fL);
|
||||
R3(D, A, B, C, X(15), 10, 0xfe2ce6e0L);
|
||||
R3(C, D, A, B, X(6), 15, 0xa3014314L);
|
||||
R3(B, C, D, A, X(13), 21, 0x4e0811a1L);
|
||||
R3(A, B, C, D, X(4), 6, 0xf7537e82L);
|
||||
R3(D, A, B, C, X(11), 10, 0xbd3af235L);
|
||||
R3(C, D, A, B, X(2), 15, 0x2ad7d2bbL);
|
||||
R3(B, C, D, A, X(9), 21, 0xeb86d391L);
|
||||
|
||||
A = c->A += A;
|
||||
B = c->B += B;
|
||||
C = c->C += C;
|
||||
D = c->D += D;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Modification 2021 Paul Scherrer Institut
|
||||
* from md32_common.h
|
||||
*/
|
||||
int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len)
|
||||
{
|
||||
const unsigned char *data = data_;
|
||||
unsigned char *p;
|
||||
HASH_LONG l;
|
||||
size_t n;
|
||||
|
||||
if (len == 0)
|
||||
return 1;
|
||||
|
||||
l = (c->Nl + (((HASH_LONG) len) << 3)) & 0xffffffffUL;
|
||||
if (l < c->Nl) /* overflow */
|
||||
c->Nh++;
|
||||
c->Nh += (HASH_LONG) (len >> 29); /* might cause compiler warning on
|
||||
* 16-bit */
|
||||
c->Nl = l;
|
||||
|
||||
n = c->num;
|
||||
if (n != 0) {
|
||||
p = (unsigned char *)c->data;
|
||||
|
||||
if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) {
|
||||
memcpy(p + n, data, HASH_CBLOCK - n);
|
||||
HASH_BLOCK_DATA_ORDER(c, p, 1);
|
||||
n = HASH_CBLOCK - n;
|
||||
data += n;
|
||||
len -= n;
|
||||
c->num = 0;
|
||||
/*
|
||||
* We use memset rather than OPENSSL_cleanse() here deliberately.
|
||||
* Using OPENSSL_cleanse() here could be a performance issue. It
|
||||
* will get properly cleansed on finalisation so this isn't a
|
||||
* security problem.
|
||||
*/
|
||||
memset(p, 0, HASH_CBLOCK); /* keep it zeroed */
|
||||
} else {
|
||||
memcpy(p + n, data, len);
|
||||
c->num += (unsigned int)len;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
n = len / HASH_CBLOCK;
|
||||
if (n > 0) {
|
||||
HASH_BLOCK_DATA_ORDER(c, data, n);
|
||||
n *= HASH_CBLOCK;
|
||||
data += n;
|
||||
len -= n;
|
||||
}
|
||||
|
||||
if (len != 0) {
|
||||
p = (unsigned char *)c->data;
|
||||
c->num = (unsigned int)len;
|
||||
memcpy(p, data, len);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modification 2021 Paul Scherrer Institut
|
||||
* from md32_common.h
|
||||
*/
|
||||
int HASH_FINAL(unsigned char *md, HASH_CTX *c)
|
||||
{
|
||||
unsigned char *p = (unsigned char *)c->data;
|
||||
size_t n = c->num;
|
||||
|
||||
p[n] = 0x80; /* there is always room for one */
|
||||
n++;
|
||||
|
||||
if (n > (HASH_CBLOCK - 8)) {
|
||||
memset(p + n, 0, HASH_CBLOCK - n);
|
||||
n = 0;
|
||||
HASH_BLOCK_DATA_ORDER(c, p, 1);
|
||||
}
|
||||
memset(p + n, 0, HASH_CBLOCK - 8 - n);
|
||||
|
||||
p += HASH_CBLOCK - 8;
|
||||
#if defined(DATA_ORDER_IS_BIG_ENDIAN)
|
||||
(void)HOST_l2c(c->Nh, p);
|
||||
(void)HOST_l2c(c->Nl, p);
|
||||
#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
|
||||
(void)HOST_l2c(c->Nl, p);
|
||||
(void)HOST_l2c(c->Nh, p);
|
||||
#endif
|
||||
p -= HASH_CBLOCK;
|
||||
HASH_BLOCK_DATA_ORDER(c, p, 1);
|
||||
c->num = 0;
|
||||
// OPENSSL_cleanse(p, HASH_CBLOCK);
|
||||
//Erik: Since we don't do encryption secure cleaning is not needed
|
||||
memset(p, 0, HASH_CBLOCK);
|
||||
|
||||
HASH_MAKE_STRING(c, md);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // namespace sls
|
||||
#endif
|
30
slsSupportLib/src/md5_helper.cpp
Normal file
30
slsSupportLib/src/md5_helper.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
#include "sls/md5_helper.h"
|
||||
|
||||
#include "sls/md5.h"
|
||||
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace sls {
|
||||
|
||||
std::string md5_calculate_checksum(char *buffer, ssize_t bytes) {
|
||||
MD5_CTX c;
|
||||
if (!MD5_Init_SLS(&c)) {
|
||||
throw std::runtime_error(
|
||||
"Could not calculate md5 checksum.[initializing]");
|
||||
}
|
||||
if (!MD5_Update_SLS(&c, buffer, bytes)) {
|
||||
throw std::runtime_error("Could not calculate md5 checksum.[Updating]");
|
||||
}
|
||||
unsigned char out[MD5_DIGEST_LENGTH];
|
||||
if (!MD5_Final_SLS(out, &c)) {
|
||||
throw std::runtime_error("Could not calculate md5 checksum.[Final]");
|
||||
}
|
||||
std::ostringstream oss;
|
||||
for (int i = 0; i != MD5_DIGEST_LENGTH; ++i)
|
||||
oss << std::hex << std::setw(2) << std::setfill('0') << +out[i];
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
} // namespace sls
|
Loading…
x
Reference in New Issue
Block a user