mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-17 07:17:13 +02:00
Compare commits
40 Commits
5.0.0-rc2
...
2020.10.28
Author | SHA1 | Date | |
---|---|---|---|
c1d841abbc | |||
e57f49086d | |||
07cc28f91b | |||
f6189072bc | |||
453908c7cb | |||
23d9d5fa81 | |||
671ee3179e | |||
de4c834b44 | |||
9c19ce602d | |||
47018b61cd | |||
91ad7b0594 | |||
e3ffc9a57b | |||
b9234ee7f2 | |||
559b02e167 | |||
a5d70c1214 | |||
cefddff848 | |||
0460d7e531 | |||
b31f8a5ca6 | |||
f4a2702996 | |||
476afed516 | |||
3d414e6438 | |||
df376c47d4 | |||
a86d70235c | |||
5cd89487b6 | |||
acf29b6db8 | |||
fddc93ba8d | |||
ae960fcb57 | |||
9f2bc85a18 | |||
3021594e20 | |||
9e8208dc0a | |||
21ad6b3a8a | |||
12abf3e58b | |||
6ddde13b87 | |||
e4226d34dc | |||
c1c885edd2 | |||
a310ab9bfa | |||
904d10eb43 | |||
e364fbcf32 | |||
95f816ad64 | |||
2bd796cfff |
@ -51,7 +51,8 @@ set(SPHINX_SOURCE_FILES
|
|||||||
src/serverdefaults.rst
|
src/serverdefaults.rst
|
||||||
src/quick_start_guide.rst
|
src/quick_start_guide.rst
|
||||||
src/troubleshooting.rst
|
src/troubleshooting.rst
|
||||||
|
src/receivers.rst
|
||||||
|
src/slsreceiver.rst
|
||||||
)
|
)
|
||||||
|
|
||||||
foreach(filename ${SPHINX_SOURCE_FILES})
|
foreach(filename ${SPHINX_SOURCE_FILES})
|
||||||
|
@ -151,6 +151,9 @@ Download
|
|||||||
|
|
||||||
Upgrade (from v4.x.x)
|
Upgrade (from v4.x.x)
|
||||||
^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Check :ref:`firmware troubleshooting <blackfin firmware troubleshooting>` if you run into issues while programming firmware.
|
||||||
|
|
||||||
#. Tftp must be installed on pc.
|
#. Tftp must be installed on pc.
|
||||||
|
|
||||||
#. Update client package to the latest (5.0.0-rc1).
|
#. Update client package to the latest (5.0.0-rc1).
|
||||||
@ -204,6 +207,9 @@ Upgrade (from v4.x.x)
|
|||||||
Upgrade (from v5.0.0-rcx)
|
Upgrade (from v5.0.0-rcx)
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Check :ref:`firmware troubleshooting <blackfin firmware troubleshooting>` if you run into issues while programming firmware.
|
||||||
|
|
||||||
|
|
||||||
#. Program from console
|
#. Program from console
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
@ -216,6 +222,7 @@ Upgrade (from v5.0.0-rcx)
|
|||||||
sls_detector_put programfpga xxx.pof
|
sls_detector_put programfpga xxx.pof
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Gotthard
|
Gotthard
|
||||||
---------
|
---------
|
||||||
|
|
||||||
@ -249,7 +256,7 @@ Download
|
|||||||
- `25um (slave) <https://github.com/slsdetectorgroup/slsDetectorFirmware/blob/master/binaries/gotthard_I/25um/slave/gotthard_I_25um_slave.pof>`__
|
- `25um (slave) <https://github.com/slsdetectorgroup/slsDetectorFirmware/blob/master/binaries/gotthard_I/25um/slave/gotthard_I_25um_slave.pof>`__
|
||||||
-
|
-
|
||||||
|
|
||||||
|
.. _firmware upgrade using blaster for blackfin:
|
||||||
|
|
||||||
Upgrade
|
Upgrade
|
||||||
^^^^^^^^
|
^^^^^^^^
|
||||||
@ -392,6 +399,8 @@ Download
|
|||||||
Upgrade (from v5.0.0-rcx)
|
Upgrade (from v5.0.0-rcx)
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Check :ref:`firmware troubleshooting <blackfin firmware troubleshooting>` if you run into issues while programming firmware.
|
||||||
|
|
||||||
#. Program from console
|
#. Program from console
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
@ -434,6 +443,8 @@ Download
|
|||||||
Upgrade (from v5.0.0-rcx)
|
Upgrade (from v5.0.0-rcx)
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Check :ref:`firmware troubleshooting <blackfin firmware troubleshooting>` if you run into issues while programming firmware.
|
||||||
|
|
||||||
#. Program from console
|
#. Program from console
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
@ -444,3 +455,57 @@ Upgrade (from v5.0.0-rcx)
|
|||||||
|
|
||||||
# Or only program firmware
|
# Or only program firmware
|
||||||
sls_detector_put programfpga xxx.pof
|
sls_detector_put programfpga xxx.pof
|
||||||
|
|
||||||
|
|
||||||
|
.. _blackfin firmware troubleshooting:
|
||||||
|
|
||||||
|
Firmware Troubleshooting with blackfin
|
||||||
|
----------------------------------------
|
||||||
|
|
||||||
|
#. v4.x.x client after programming will most likely reboot the blackfin processor, regardless of error.
|
||||||
|
|
||||||
|
#. v5.x.x-rcx client after programming will not reboot the blackfin processor, if error occurred.
|
||||||
|
|
||||||
|
#. If a reboot occured with an incomplete firmware in flash, the blackfin will most likely not find the mtd3 drive. To see if this drive exists:
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# connect to the board
|
||||||
|
telnet bchipxxx
|
||||||
|
|
||||||
|
# view of mtd3 existing
|
||||||
|
root:/> more /proc/mtd
|
||||||
|
dev: size erasesize name
|
||||||
|
mtd0: 00040000 00020000 "bootloader(nor)"
|
||||||
|
mtd1: 00100000 00020000 "linux kernel(nor)"
|
||||||
|
mtd2: 002c0000 00020000 "file system(nor)"
|
||||||
|
mtd3: 01000000 00010000 "bitfile(spi)"
|
||||||
|
|
||||||
|
4. If one can see the mtd3 drive, one can already try to flash again using the **programfpga** command (without rebooting blackfin or detector).
|
||||||
|
|
||||||
|
#. 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.
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# step 1: connect to the board
|
||||||
|
telnet bchipxxx
|
||||||
|
|
||||||
|
# step 2: check if mtd3 drive listed
|
||||||
|
more /proc/mtd
|
||||||
|
|
||||||
|
# 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;
|
||||||
|
reboot
|
||||||
|
|
||||||
|
# step 4: repeat steps 1 - 3 until you see the mtd3 drive
|
||||||
|
|
||||||
|
|
||||||
|
Last Resort using USB Blaster
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
If none of these steps work, the last resort might be physically upgrading the firmware using a USB blaster, which also requires opening up the detector. Instructions for all the blackfin detectors are the same as the one for :ref:`gotthard firmware upgrade <firmware upgrade using blaster for blackfin>`.
|
@ -66,6 +66,13 @@ Welcome to slsDetectorPackage's documentation!
|
|||||||
virtualserver
|
virtualserver
|
||||||
serverdefaults
|
serverdefaults
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:caption: Receiver
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
receivers
|
||||||
|
slsreceiver
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:caption: Troubleshooting
|
:caption: Troubleshooting
|
||||||
|
|
||||||
|
50
docs/src/receivers.rst
Normal file
50
docs/src/receivers.rst
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
Receivers
|
||||||
|
=================
|
||||||
|
|
||||||
|
Receiver processes can be run on same or different machines as the client, receives the data from the detector (via UDP packets).
|
||||||
|
When using the slsReceiver/ slsMultiReceiver, they can be further configured by the client control software (via TCP/IP) to set file name, file path, progress of acquisition etc.
|
||||||
|
|
||||||
|
Detector UDP Header
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
| The UDP data format for the packets consist of a common header for all detectors, followed by the data for that one packet.
|
||||||
|
|
||||||
|
**The SLS Detector Header**
|
||||||
|
|
||||||
|
.. table:: <-------------------------------- 8 bytes -------------------------------->
|
||||||
|
:align: center
|
||||||
|
:widths: 30,30,30,30
|
||||||
|
|
||||||
|
+--------------------------------------------------------------------+
|
||||||
|
|frameNumber |
|
||||||
|
+---------------------------------+----------------------------------+
|
||||||
|
|expLength |packetNumber |
|
||||||
|
+---------------------------------+----------------------------------+
|
||||||
|
|bunchId |
|
||||||
|
+--------------------------------------------------------------------+
|
||||||
|
|timestamp |
|
||||||
|
+----------------+----------------+----------------+-----------------+
|
||||||
|
|modId |row |column |reserved |
|
||||||
|
+----------------+----------------+----------------+--------+--------+
|
||||||
|
|debug |roundRNumber |detType |version |
|
||||||
|
+---------------------------------+----------------+--------+--------+
|
||||||
|
|
||||||
|
UDP configuration in Config file
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
#. UDP source port is hardcoded in detector server, starting at 32410.
|
||||||
|
#. **udp_dstport** : UDP destination port number. Port in receiver pc to listen to packets from the detector.
|
||||||
|
#. **udp_dstip** : IP address of UDP destination interface. IP address of interface in receiver pc to listen to packets from detector. If **auto** is used (only when using slsReceiver/ slsMultiReceiver), the IP of **rx_hostname** is picked up.
|
||||||
|
#. **udp_dstmac** : Mac address of UDP destination interface. MAC address of interface in receiver pc to list to packets from detector. Only required when using custom receiver, else slsReceiver/slsMultiReceiver picks it up from **udp_dstip**.
|
||||||
|
#. **udp_srcip** : IP address of UDP source interface. IP address of detector UDP interface to send packets from. Do not use for Eiger 1Gb interface (uses its hardware IP). For others, must be in the same subnet as **udp_dstip**.
|
||||||
|
#. **udp_srcmac** : MAC address of UDP source interface. MAC address of detector UDP interface to send packets from. Do not use for Eiger (uses hardware mac). For others, it is not necessary, but can help for switch and debugging to put unique values for each module.
|
||||||
|
|
||||||
|
|
||||||
|
Custom Receiver
|
||||||
|
----------------
|
||||||
|
|
||||||
|
| When using custom receiver with our package, ensure that **udp_dstmac** is also configured in the config file. This parameter is not required when using slsReceiver.
|
||||||
|
|
||||||
|
| Cannot use "auto" for **udp_dstip**.
|
||||||
|
|
||||||
|
| Also ensure that there are no **rx_** commands in the config file. These commands are for configuring the slsReceiver.
|
159
docs/src/slsreceiver.rst
Normal file
159
docs/src/slsreceiver.rst
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
slsReceiver/ slsMultiReceiver
|
||||||
|
================================
|
||||||
|
|
||||||
|
| One has to start the slsReceiver before loading config file or using any receiver commands (prefix: **rx_** )
|
||||||
|
|
||||||
|
For a Single Module
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# default port 1954
|
||||||
|
slsReceiver
|
||||||
|
|
||||||
|
# custom port 2012
|
||||||
|
slsReceiver -t2012
|
||||||
|
|
||||||
|
|
||||||
|
For Multiple Modules
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# each receiver (for each module) requires a unique tcp port (if all on same machine)
|
||||||
|
|
||||||
|
# using slsReceiver in multiple consoles
|
||||||
|
slsReceiver
|
||||||
|
slsReceiver -t1955
|
||||||
|
|
||||||
|
# slsMultiReceiver [starting port] [number of receivers]
|
||||||
|
slsMultiReceiver 2012 2
|
||||||
|
|
||||||
|
# slsMultiReceiver [starting port] [number of receivers] [print each frame header for debugging]
|
||||||
|
slsMultiReceiver 2012 2 1
|
||||||
|
|
||||||
|
|
||||||
|
Client Commands
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
| One can remove **udp_dstmac** from the config file, as the slsReceiver fetches this from the **udp_ip**.
|
||||||
|
|
||||||
|
| One can use "auto" for **udp_dstip** if one wants to use default ip of **rx_hostname**.
|
||||||
|
|
||||||
|
| The first command to the receiver (**rx_** commands) should be **rx_hostname**. The following are the different ways to establish contact.
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# default receiver tcp port (1954)
|
||||||
|
rx_hostname xxx
|
||||||
|
|
||||||
|
# custom receiver port
|
||||||
|
rx_hostname xxx:1957
|
||||||
|
|
||||||
|
# custom receiver port
|
||||||
|
rx_tcpport 1954
|
||||||
|
rx_hostname xxx
|
||||||
|
|
||||||
|
# multi modules with custom ports
|
||||||
|
rx_hostname xxx:1955+xxx:1956+
|
||||||
|
|
||||||
|
# multi modules with custom ports on same rxr pc
|
||||||
|
0:rx_tcpport 1954
|
||||||
|
1:rx_tcpport 1955
|
||||||
|
2:rx_tcpport 1956
|
||||||
|
rx_hostname xxx
|
||||||
|
|
||||||
|
# multi modules with custom ports on different rxr pc
|
||||||
|
0:rx_tcpport 1954
|
||||||
|
0:rx_hostname xxx
|
||||||
|
1:rx_tcpport 1955
|
||||||
|
1:rx_hostname yyy
|
||||||
|
|
||||||
|
|
||||||
|
| Example commands:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# to get a list of receiver commands (these dont include file commands)
|
||||||
|
sls_detector_get list | grep rx_
|
||||||
|
|
||||||
|
# some file commands are:
|
||||||
|
fwrite
|
||||||
|
foverwrite
|
||||||
|
findex
|
||||||
|
fpath
|
||||||
|
fname
|
||||||
|
fmaster
|
||||||
|
fformat
|
||||||
|
|
||||||
|
# to get help on a single commands
|
||||||
|
sls_detector_get -h rx_framescaught
|
||||||
|
|
||||||
|
|
||||||
|
File format
|
||||||
|
--------------
|
||||||
|
|
||||||
|
* The file name format is [fpath]/[fname]_dx_fy_[findex].raw, where x is module index and y is file index. **fname** is file name prefix and by default "run". **fpath** is '/' by default.
|
||||||
|
|
||||||
|
* Each acquisition will have an increasing acquisition index or findex (if file write enabled). This can be retrieved by using **findex** command.
|
||||||
|
|
||||||
|
* Each acquisition can have multiple files (the file index number **y**), with **rx_framesperfile** being the maximum number of frames per file. The default varies for each detector type.
|
||||||
|
|
||||||
|
* Some file name examples:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
# first file
|
||||||
|
path-to-file/run_d0_f0_0.raw
|
||||||
|
|
||||||
|
# second file after reaching max frames in first file
|
||||||
|
path-to-file/run_d0_f1_0.raw
|
||||||
|
|
||||||
|
# second acquisition, first file
|
||||||
|
path-to-file/run_d0_f0_1.raw
|
||||||
|
|
||||||
|
* Each acquisition will create a master file that can be enabled/disabled using **fmaster**. This should have parameters relevant to the acquisition.
|
||||||
|
|
||||||
|
* SLS Receiver Header consist of SLS Detector Header + 64 bytes of bitmask, altogether 112 bytes. The packetNumber in the sls detector header part, will be updated to number of packets caught by receiver for that frame. Furthermore, the bit mask will specify which packets have been received.
|
||||||
|
|
||||||
|
**Binary file format**
|
||||||
|
|
||||||
|
* This is the default file format.
|
||||||
|
|
||||||
|
* Each data file will consist of frames, each consisting of slsReceiver Header followed by data for 1 frame.
|
||||||
|
|
||||||
|
* Master file is of ASCII format and will also include the format of the slsReceiver Header.
|
||||||
|
|
||||||
|
|
||||||
|
**HDF5 file formats**
|
||||||
|
|
||||||
|
#. Compile the package with HDF5 option enabled
|
||||||
|
|
||||||
|
#. Using cmk script: ./cmk.sh -hj9 -d [path of hdf5 dir]
|
||||||
|
|
||||||
|
#. Enable using cmake **-DCMAKE_INSTALL_PREFIX=/path/to/hdf/installation** and **-DSLS_USE_HDF5=ON**
|
||||||
|
|
||||||
|
#. Start Receiver process
|
||||||
|
|
||||||
|
#. Load config file
|
||||||
|
|
||||||
|
#. Set file format from client or in config file
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
sls_detector_put fformat hdf5
|
||||||
|
|
||||||
|
|
||||||
|
| For multiple, modules, a virtual file linking all the modules is created. Both the data files and virtual files are linked in the master file.
|
||||||
|
|
||||||
|
|
||||||
|
Performance
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Please refer to Receiver PC Tuning options and slsReceiver Tuning under `Troubleshooting <https://slsdetectorgroup.github.io/devdoc/troubleshooting.html>`_.
|
||||||
|
|
||||||
|
|
||||||
|
Using Callbacks
|
||||||
|
----------------
|
||||||
|
|
||||||
|
| One can get a callback in the receiver for each frame to:
|
||||||
|
* manipulate the data that will be written to file, or
|
||||||
|
* disable file writing in slsReceiver and take care of the data for each call back
|
||||||
|
|
||||||
|
| When handling callbacks, the control should be returned as soon as possible, to prevent packet loss from fifo being full.
|
||||||
|
|
@ -13,7 +13,7 @@ Compilation
|
|||||||
* Using cmk.sh script,
|
* Using cmk.sh script,
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
./cmk.sh -b**s**j9 #option s is for simulator
|
./cmk.sh -bsj9 #option s is for simulator
|
||||||
|
|
||||||
|
|
||||||
Binaries
|
Binaries
|
||||||
|
@ -8,18 +8,15 @@ rx_hostname pcmoench01
|
|||||||
udp_dstport 50004
|
udp_dstport 50004
|
||||||
|
|
||||||
# udp destination ip (receiver)
|
# udp destination ip (receiver)
|
||||||
#udp_dstip 172.24.8.84
|
udp_dstip 10.0.1.100
|
||||||
# or to get ip from rx_hostname
|
|
||||||
udp_dstip auto
|
|
||||||
|
|
||||||
# udp source ip (same subnet as udp_dstip)
|
# udp source ip (same subnet as udp_dstip)
|
||||||
udp_srcip 172.24.8.254
|
udp_srcip 10.0.1.184
|
||||||
|
|
||||||
|
# PCBv2.0 (using 2 interfaces, top)
|
||||||
# PCBv2.0 (using 2 interfaces)
|
|
||||||
udp_dstport2 50005
|
udp_dstport2 50005
|
||||||
udp_dstip2 auto
|
udp_dstip2 10.0.2.100
|
||||||
udp_srcip2 172.24.8.111
|
udp_srcip2 10.0.2.184
|
||||||
# enable two interfaces
|
# enable two interfaces
|
||||||
numinterfaces 2
|
numinterfaces 2
|
||||||
# select inner interface(effective only when numinterfaces is 1)
|
# select inner interface(effective only when numinterfaces is 1)
|
||||||
|
@ -983,6 +983,7 @@ mount -t tmpfs none /mnt/ramdisk -o size=10G
|
|||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
check how many GB memory you can allocate, to avoid swapping otherwise
|
check how many GB memory you can allocate, to avoid swapping otherwise
|
||||||
|
|
||||||
|
|
||||||
\section{Offline processing and monitoring}
|
\section{Offline processing and monitoring}
|
||||||
|
|
||||||
\subsection{Data out of the detector: UDP packets}\label{UDP}
|
\subsection{Data out of the detector: UDP packets}\label{UDP}
|
||||||
@ -1017,28 +1018,31 @@ white the option {\tt{n:flippeddatax 1}}, which flips in vertical the content of
|
|||||||
\subsection{``raw'' files}
|
\subsection{``raw'' files}
|
||||||
If you use the option of writing raw files, you will have a raw file for each UDP port (meaning most likely 2 chips), 4 files per module. In addition to the raw files, you will get also a ``master'' file, containing in ascii some detector general parameters and the explanation of how to interpret the data from the raw files.
|
If you use the option of writing raw files, you will have a raw file for each UDP port (meaning most likely 2 chips), 4 files per module. In addition to the raw files, you will get also a ``master'' file, containing in ascii some detector general parameters and the explanation of how to interpret the data from the raw files.
|
||||||
|
|
||||||
The master file is named: {\tt{filename\_master\_0.raw}} and for version ``4.0.0'' of the slsDetectorSoftware looks like:
|
The master file is named: {\tt{filename\_master\_0.raw}} and for version ``5.0'' of the slsDetectorSoftware looks like:
|
||||||
|
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
Version : 4.0
|
Version : 6.2
|
||||||
Detector Type : 3
|
TimeStamp : Thu Oct 8 11:10:07 2020
|
||||||
|
|
||||||
|
Detector Type : Eiger
|
||||||
|
Timing Mode : auto
|
||||||
|
Image Size : 524288 bytes
|
||||||
|
Pixels : [512, 256]
|
||||||
|
Max Frames Per File : 10000
|
||||||
|
Frame Discard Policy : nodiscard
|
||||||
|
Frame Padding : 1
|
||||||
|
Scan Parameters : [disabled]
|
||||||
|
Total Frames : 10
|
||||||
Dynamic Range : 32
|
Dynamic Range : 32
|
||||||
Ten Giga : 1
|
Ten Giga : 1
|
||||||
Image Size : 524288 bytes
|
Exptime : 1s
|
||||||
nPixelsX : 512 pixels
|
Period : 50us
|
||||||
nPixelsY : 256 pixels
|
SubExptime : 2.62144ms
|
||||||
Max Frames Per File : 10000
|
SubPeriod : 2.62144ms
|
||||||
Total Frames : 3
|
Quad : 0
|
||||||
Exptime (ns) : 10000000
|
Number of Lines read out : 256
|
||||||
SubExptime (ns) : 2621440
|
Rate Corrections : [0, 0]
|
||||||
SubPeriod(ns) : 2621440
|
|
||||||
Period (ns) : 0
|
|
||||||
Gap Pixels Enable : 0
|
|
||||||
Quad Enable : 0
|
|
||||||
Timestamp : Wed Aug 21 16:30:20 2019
|
|
||||||
|
|
||||||
|
\#Frame Header
|
||||||
#Frame Header
|
|
||||||
Frame Number : 8 bytes
|
Frame Number : 8 bytes
|
||||||
SubFrame Number/ExpLength : 4 bytes
|
SubFrame Number/ExpLength : 4 bytes
|
||||||
Packet Number : 4 bytes
|
Packet Number : 4 bytes
|
||||||
@ -1060,20 +1064,35 @@ Note that if one wants to reconstruct the real time the detector was acquiring
|
|||||||
\subsection{Offline image reconstruction}
|
\subsection{Offline image reconstruction}
|
||||||
The offline image reconstruction{\tt{slsImageReconstruction}} is not part of the package anymore. However, it can be retrieved from \\
|
The offline image reconstruction{\tt{slsImageReconstruction}} is not part of the package anymore. However, it can be retrieved from \\
|
||||||
{\tt{git clone https://github.com/slsdetectorgroup/slsImageReconstruction.git slsImageReconstruction}}.\\
|
{\tt{git clone https://github.com/slsdetectorgroup/slsImageReconstruction.git slsImageReconstruction}}.\\
|
||||||
Checkout the {\tt{v3.1}} branch if in a 3.1.X release, the {\tt{v4.0.0}} branch if in 4.0.X release, or the {\tt{v4.1}} branch if in 4.1.X release of the {\tt{slsDetector}} code. There is a {\tt{developer}} branch that is following the 5.X chnages but it is not officila yet.
|
Checkout the {\tt{v3.1}} branch if in a 3.1.X release, the {\tt{v4.0.0}} branch if in 4.0.X release, or the {\tt{v4.1}} branch if in 4.1.X release of the {\tt{slsDetector}} code. There is a {\tt{developer}} branch that is following the 5.X chnages but it is not official yet.
|
||||||
|
|
||||||
Four possible conversions are possible: into \textbf{cbf}, \textbf{hdf5}. \textbf{tiff} and \textbf{root} format. The detector writes 2 raw files per receiver. An offline image reconstruction executable has been written to collate the possible files together and produce output files. By default an interpolation between the values of the large pixels is performed. Gap pixels between modules are also inserted.
|
Four possible conversions are possible: into \textbf{cbf}, \textbf{hdf5}. \textbf{tiff} and \textbf{root} format. The detector writes 2 raw files per receiver. An offline image reconstruction executable has been written to collate the possible files together and produce output files. By default an interpolation between the values of the large pixels is performed. Gap pixels between modules are also inserted.
|
||||||
|
|
||||||
Note that the number of images per file in the 3.1.X release is hardcoded and needs to match whatever you are using in \\
|
\subsection{Releases}
|
||||||
|
Note for different releases:
|
||||||
|
\begin{itemize}
|
||||||
|
\item Note that the number of images per file in the 3.1.X release is hardcoded and needs to match whatever you are using in \\
|
||||||
{\tt{slsDetectorsPackage/slsReceiverSoftware/include/sls\_receiver\_defs.h}}:
|
{\tt{slsDetectorsPackage/slsReceiverSoftware/include/sls\_receiver\_defs.h}}:
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
#define EIGER_MAX_FRAMES_PER_FILE 2000
|
#define EIGER_MAX_FRAMES_PER_FILE 2000
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
The default is 2000 in the 3.1.X release. The default has been changed to 10000 frm realease 4.0.X and now this is picked up automatically without doing anything.
|
The default is 2000 in the 3.1.X release. The default has been changed to 10000 frm realease 4.0.X and now this is picked up automatically without doing anything.
|
||||||
|
|
||||||
|
\item From release 4.1.x, it is not needed to change the options in the \tt{slsImageReconstruction/src/main\_csaxs.cpp} file, but it is enough to change the options in the compiler. Options are:
|
||||||
|
\begin{enumerate}
|
||||||
|
\item [cbf] if you want header style supperted at MS beamline (in reality the lines are just hardcoded with no real information in them, just to have all required filesds) analyser (Krysalis?) choose -DMSHeader
|
||||||
|
\item [hdf5] If you want a master file, which contains a virtual dataset pointing at dataset written in subfiles, use the option -DMASTERVIRTUAL . This option however is not supported neither by Matlab2018, nor by Albula and Nedved installed at the MS beamlines.
|
||||||
|
\item [hdf5] The master file contains links to the datasets of other files, use -DMASTERLINK option. Although this version is very unconfortable if you need to open writing your code different events, but it is what Albula, Nedved and so on uses (it is compatible to Dectris). So it has more portability.
|
||||||
|
\item [hdf5]to compress using zlib, use the -DZLIB. Very slow compression, not used
|
||||||
|
\item [hdf5] -DBITSHUFFLE should have lz4 and bitshuffle implemented. I am not sure it works. NEEDS to be tested. Not to be used if not for debugging.
|
||||||
|
\end{enumerate}
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
\subsubsection{cbf}
|
\subsubsection{cbf}
|
||||||
The cbf executable executable uses the CBFlib-0.9.5 library (downloaded from the web as it downloads architecture dependent packages at installation).Edit the Makefile to correclty point at it.\\
|
The cbf executable executable uses the CBFlib-0.9.5 library (downloaded from the web as it downloads architecture dependent packages at installation).Edit the Makefile to correclty point at it.\\
|
||||||
\underline{At cSAXS, the CBFlib-0.9.5 has been compiled -such that the required packages are}\\\underline{ downloaded in /sls/X12SA/data/x12saop/EigerPackage/CBFlib-0.9.5.}\\
|
|
||||||
|
|
||||||
To use it for a single module:
|
To use it for a single module:
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
@ -1128,7 +1147,7 @@ make cbfMaker; make cbfMakerOMNY;
|
|||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
|
|
||||||
\subsubsection{hdf5}
|
\subsubsection{hdf5}
|
||||||
In case of HDF5 output file, we rely on having the HDF5 1.10.1 library installed and {\tt{HDF5-External-Filter-Plugins}} installed. With HDF5 1.10.3, no need of the external plugings package is needed, but a small modification to the file is needed. Edit the Makefile to correclty point at it. Different compression methods are being tried so different external filters might be to be installed. This work is not finished yet.
|
In case of HDF5 output file, we rely on having the hdf5/1.10.3 (previously was 1.10.1 library installed and {\tt{HDF5-External-Filter-Plugins}} installed). Edit the Makefile to correclty point at Different compression methods (so far only the not efficien gzip is implemented) are being tried so different external filters might be to be installed. This work is not finished yet.
|
||||||
|
|
||||||
To choose HDF5, with ZLIB implementation, open {\tt{slsImageReconstruction/src/main\_csaxs.cpp}} and make sure that
|
To choose HDF5, with ZLIB implementation, open {\tt{slsImageReconstruction/src/main\_csaxs.cpp}} and make sure that
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
@ -1201,6 +1220,28 @@ The HV can also be set and read through the software:
|
|||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
Note that the get {\tt{vhighvoltage}}(\tt{\textcolor{red}{highvoltage}}) would return the measured HV from the master module only. If getting the highvoltage for individual halfmodules, only the master will have a value different from -999.
|
Note that the get {\tt{vhighvoltage}}(\tt{\textcolor{red}{highvoltage}}) would return the measured HV from the master module only. If getting the highvoltage for individual halfmodules, only the master will have a value different from -999.
|
||||||
|
|
||||||
|
\section{Run the sum of counts in the receiver}
|
||||||
|
In the package {\tt{slsImageReconstruction}} there is also a very basic executable that allows to run receivers that sum all the counts in the UDP port and writes them as a text files in the {\tt{outdir}} directory in the same directory as the data files, with the same {\tt{fname}}. This is to use EIGER as a simple normalization detector.
|
||||||
|
The code is in {\tt{slsImageReconstruction/src/ReceiverSum.cpp}}.
|
||||||
|
For the compilation you need to be in {\tt{slsImageReconstruction}}
|
||||||
|
\begin{verbatim}
|
||||||
|
make -f Makefile.zmq receiverSum
|
||||||
|
\end{verbatim}
|
||||||
|
you might need to edit the path to the {\tt{slsDetectorPackage}} that you are using in the {\tt{Makefile.zmq}}.
|
||||||
|
Usage is:
|
||||||
|
\begin{verbatim}
|
||||||
|
export LD_LIBRARY_PATH=pathtoslsDetectorPackage/build/bin
|
||||||
|
./bin/receiverSum
|
||||||
|
./bin/receiverSum rx_tcppport 1955
|
||||||
|
\end{verbatim}
|
||||||
|
For now, to work peoperly there are some requirements that need to make more general if the code wants to be used more:
|
||||||
|
\begin{enumerate}
|
||||||
|
\item You can use the code only for a module (2 Receivers)
|
||||||
|
\item The first receiver has to run using tcp\_port 1954 (the second port is not fixed but we use 1955 normally)
|
||||||
|
\item Set the option {\tt{enablefwrite 0}} (\textcolor{red}{\tt{fwrite 0}}) as we do not write raw data but only the text files.
|
||||||
|
\item As a bit of time is required to make the sum compared to a normal receiver, use the option {\tt sls\_detector\_put rx\_fifodepth 50000}.
|
||||||
|
\end{enumerate}
|
||||||
|
File like fnamed0\_findex.txt, fnamed1\_findex.txt, fnamed2\_findex.txt and fnamed3\_findex.txt will be written, containing 2 columns: the frame number and the sum of counts for the port.
|
||||||
\appendix
|
\appendix
|
||||||
|
|
||||||
\section{Kill the server, copy a new server, start the server}\label{server}
|
\section{Kill the server, copy a new server, start the server}\label{server}
|
||||||
|
@ -1 +0,0 @@
|
|||||||
../../slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp
|
|
1
serverBin/ctbDetectorServer_developer
Symbolic link
1
serverBin/ctbDetectorServer_developer
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer
|
@ -1 +0,0 @@
|
|||||||
../slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServerv5.0.0-rc2
|
|
1
serverBin/eigerDetectorServer_developer
Symbolic link
1
serverBin/eigerDetectorServer_developer
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer
|
@ -1 +0,0 @@
|
|||||||
../slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServerv5.0.0-rc2
|
|
1
serverBin/gotthard2DetectorServer_developer
Symbolic link
1
serverBin/gotthard2DetectorServer_developer
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer
|
@ -1 +0,0 @@
|
|||||||
../slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServerv5.0.0-rc2
|
|
1
serverBin/gotthardDetectorServer_developer
Symbolic link
1
serverBin/gotthardDetectorServer_developer
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer
|
@ -1 +0,0 @@
|
|||||||
../slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServerv5.0.0-rc2
|
|
1
serverBin/jungfrauDetectorServer_developer
Symbolic link
1
serverBin/jungfrauDetectorServer_developer
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer
|
@ -1 +0,0 @@
|
|||||||
../slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServerv5.0.0-rc2
|
|
1
serverBin/moenchDetectorServer_developer
Symbolic link
1
serverBin/moenchDetectorServer_developer
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer
|
@ -1 +0,0 @@
|
|||||||
../slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServerv5.0.0-rc2
|
|
1
serverBin/mythen3DetectorServer_developer
Symbolic link
1
serverBin/mythen3DetectorServer_developer
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer
|
@ -1 +0,0 @@
|
|||||||
../slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServerv5.0.0-rc2
|
|
BIN
slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer
Executable file
BIN
slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer
Executable file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer
Executable file
BIN
slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer
Executable file
Binary file not shown.
Binary file not shown.
@ -1766,6 +1766,7 @@ int checkDetectorType() {
|
|||||||
char buffer[MAX_STR_LENGTH];
|
char buffer[MAX_STR_LENGTH];
|
||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
fread(buffer, MAX_STR_LENGTH, sizeof(char), fd);
|
fread(buffer, MAX_STR_LENGTH, sizeof(char), fd);
|
||||||
|
fclose(fd);
|
||||||
if (strlen(buffer) == 0) {
|
if (strlen(buffer) == 0) {
|
||||||
LOG(logERROR,
|
LOG(logERROR,
|
||||||
("Could not read file %s to get type of the module attached\n",
|
("Could not read file %s to get type of the module attached\n",
|
||||||
|
Binary file not shown.
BIN
slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer
Executable file
BIN
slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer
Executable file
Binary file not shown.
Binary file not shown.
BIN
slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer
Executable file
BIN
slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer
Executable file
Binary file not shown.
Binary file not shown.
@ -119,6 +119,9 @@
|
|||||||
#define CONFIG_DYNAMIC_RANGE_8_VAL ((0x1 << CONFIG_DYNAMIC_RANGE_OFST) & CONFIG_DYNAMIC_RANGE_MSK)
|
#define CONFIG_DYNAMIC_RANGE_8_VAL ((0x1 << CONFIG_DYNAMIC_RANGE_OFST) & CONFIG_DYNAMIC_RANGE_MSK)
|
||||||
#define CONFIG_DYNAMIC_RANGE_16_VAL ((0x2 << CONFIG_DYNAMIC_RANGE_OFST) & CONFIG_DYNAMIC_RANGE_MSK)
|
#define CONFIG_DYNAMIC_RANGE_16_VAL ((0x2 << CONFIG_DYNAMIC_RANGE_OFST) & CONFIG_DYNAMIC_RANGE_MSK)
|
||||||
#define CONFIG_DYNAMIC_RANGE_24_VAL ((0x3 << CONFIG_DYNAMIC_RANGE_OFST) & CONFIG_DYNAMIC_RANGE_MSK)
|
#define CONFIG_DYNAMIC_RANGE_24_VAL ((0x3 << CONFIG_DYNAMIC_RANGE_OFST) & CONFIG_DYNAMIC_RANGE_MSK)
|
||||||
|
#define CONFIG_TRIGGER_ENA_OFST (8)
|
||||||
|
#define CONFIG_TRIGGER_ENA_MSK (0x00000001 << CONFIG_TRIGGER_ENA_OFST)
|
||||||
|
|
||||||
|
|
||||||
/* Control RW register */
|
/* Control RW register */
|
||||||
#define CONTROL_REG (0x21 * REG_OFFSET + BASE_CONTROL)
|
#define CONTROL_REG (0x21 * REG_OFFSET + BASE_CONTROL)
|
||||||
@ -129,7 +132,7 @@
|
|||||||
#define CONTROL_STP_ACQSTN_MSK (0x00000001 << CONTROL_STP_ACQSTN_OFST)
|
#define CONTROL_STP_ACQSTN_MSK (0x00000001 << CONTROL_STP_ACQSTN_OFST)
|
||||||
#define CONTROL_STRT_PATTERN_OFST (2)
|
#define CONTROL_STRT_PATTERN_OFST (2)
|
||||||
#define CONTROL_STRT_PATTERN_MSK (0x00000001 << CONTROL_STRT_PATTERN_OFST)
|
#define CONTROL_STRT_PATTERN_MSK (0x00000001 << CONTROL_STRT_PATTERN_OFST)
|
||||||
#define CONTROL_STRT_READOUT_OFST (3) // not connected in software yet
|
#define CONTROL_STRT_READOUT_OFST (3)
|
||||||
#define CONTROL_STRT_READOUT_MSK (0x00000001 << CONTROL_STRT_READOUT_OFST)
|
#define CONTROL_STRT_READOUT_MSK (0x00000001 << CONTROL_STRT_READOUT_OFST)
|
||||||
#define CONTROL_STRT_SW_TRIGGER_OFST (4)
|
#define CONTROL_STRT_SW_TRIGGER_OFST (4)
|
||||||
#define CONTROL_STRT_SW_TRIGGER_MSK (0x00000001 << CONTROL_STRT_SW_TRIGGER_OFST)
|
#define CONTROL_STRT_SW_TRIGGER_MSK (0x00000001 << CONTROL_STRT_SW_TRIGGER_OFST)
|
||||||
@ -148,6 +151,16 @@
|
|||||||
|
|
||||||
#define DTA_OFFSET_REG (0x24 * REG_OFFSET + BASE_CONTROL)
|
#define DTA_OFFSET_REG (0x24 * REG_OFFSET + BASE_CONTROL)
|
||||||
|
|
||||||
|
|
||||||
|
/* Formatting for adif core -----------------------------------------------*/
|
||||||
|
#define ADIF_CONFIG_REG (0x00 * REG_OFFSET + BASE_ADIF)
|
||||||
|
|
||||||
|
#define ADIF_ADDTNL_OFST_OFST (0)
|
||||||
|
#define ADIF_ADDTNL_OFST_MSK (0x00000003 << ADIF_ADDTNL_OFST_OFST)
|
||||||
|
#define ADIF_PIPELINE_OFST (4)
|
||||||
|
#define ADIF_PIPELINE_MSK (0x0000000F << ADIF_PIPELINE_OFST)
|
||||||
|
|
||||||
|
|
||||||
/* Formatting for data core -----------------------------------------------*/
|
/* Formatting for data core -----------------------------------------------*/
|
||||||
#define FMT_CONFIG_REG (0x00 * REG_OFFSET + BASE_FMT)
|
#define FMT_CONFIG_REG (0x00 * REG_OFFSET + BASE_FMT)
|
||||||
|
|
||||||
@ -456,11 +469,11 @@
|
|||||||
#define SET_PERIOD_LSB_REG (0x28 * REG_OFFSET + BASE_FLOW_CONTROL)
|
#define SET_PERIOD_LSB_REG (0x28 * REG_OFFSET + BASE_FLOW_CONTROL)
|
||||||
#define SET_PERIOD_MSB_REG (0x29 * REG_OFFSET + BASE_FLOW_CONTROL)
|
#define SET_PERIOD_MSB_REG (0x29 * REG_OFFSET + BASE_FLOW_CONTROL)
|
||||||
|
|
||||||
/* External Signal register */
|
/* Flow Trigger register (for all timing modes) */
|
||||||
#define EXT_SIGNAL_REG (0x30 * REG_OFFSET + BASE_FLOW_CONTROL)
|
#define FLOW_TRIGGER_REG (0x30 * REG_OFFSET + BASE_FLOW_CONTROL)
|
||||||
|
|
||||||
#define EXT_SIGNAL_OFST (0)
|
#define FLOW_TRIGGER_OFST (0)
|
||||||
#define EXT_SIGNAL_MSK (0x00000001 << EXT_SIGNAL_OFST)
|
#define FLOW_TRIGGER_MSK (0x00000001 << FLOW_TRIGGER_OFST)
|
||||||
|
|
||||||
/* Trigger Delay 64 bit register */
|
/* Trigger Delay 64 bit register */
|
||||||
#define SET_TRIGGER_DELAY_LSB_REG (0x32 * REG_OFFSET + BASE_FLOW_CONTROL)
|
#define SET_TRIGGER_DELAY_LSB_REG (0x32 * REG_OFFSET + BASE_FLOW_CONTROL)
|
||||||
|
BIN
slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer
Executable file
BIN
slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer
Executable file
Binary file not shown.
Binary file not shown.
@ -50,6 +50,8 @@ uint32_t clkDivider[NUM_CLOCKS] = {};
|
|||||||
|
|
||||||
int highvoltage = 0;
|
int highvoltage = 0;
|
||||||
int detPos[2] = {};
|
int detPos[2] = {};
|
||||||
|
int64_t exptimeReg[3] = {0, 0, 0};
|
||||||
|
int64_t gateDelayReg[3] = {0, 0, 0};
|
||||||
|
|
||||||
int isInitCheckDone() { return initCheckDone; }
|
int isInitCheckDone() { return initCheckDone; }
|
||||||
|
|
||||||
@ -418,6 +420,10 @@ void setupDetector() {
|
|||||||
setHighVoltage(DEFAULT_HIGH_VOLTAGE);
|
setHighVoltage(DEFAULT_HIGH_VOLTAGE);
|
||||||
setDefaultDacs();
|
setDefaultDacs();
|
||||||
setASICDefaults();
|
setASICDefaults();
|
||||||
|
setADIFDefaults();
|
||||||
|
|
||||||
|
// set trigger flow for m3 (for all timing modes)
|
||||||
|
bus_w(FLOW_TRIGGER_REG, bus_r(FLOW_TRIGGER_REG) | FLOW_TRIGGER_MSK);
|
||||||
|
|
||||||
// dynamic range
|
// dynamic range
|
||||||
setDynamicRange(DEFAULT_DYNAMIC_RANGE);
|
setDynamicRange(DEFAULT_DYNAMIC_RANGE);
|
||||||
@ -514,6 +520,17 @@ void setASICDefaults() {
|
|||||||
bus_w(ASIC_RDO_CONFIG_REG, val);
|
bus_w(ASIC_RDO_CONFIG_REG, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setADIFDefaults() {
|
||||||
|
uint32_t addr = ADIF_CONFIG_REG;
|
||||||
|
bus_w(addr, ((bus_r(addr) & ~ADIF_ADDTNL_OFST_MSK) & ~ADIF_PIPELINE_MSK));
|
||||||
|
bus_w(addr,
|
||||||
|
(bus_r(addr) | ((DEFAULT_ADIF_PIPELINE_VAL << ADIF_PIPELINE_OFST) &
|
||||||
|
ADIF_PIPELINE_MSK)));
|
||||||
|
bus_w(addr,
|
||||||
|
(bus_r(addr) | ((DEFAULT_ADIF_ADD_OFST_VAL << ADIF_ADDTNL_OFST_OFST) &
|
||||||
|
ADIF_ADDTNL_OFST_MSK)));
|
||||||
|
}
|
||||||
|
|
||||||
/* firmware functions (resets) */
|
/* firmware functions (resets) */
|
||||||
|
|
||||||
void cleanFifos() {
|
void cleanFifos() {
|
||||||
@ -681,7 +698,7 @@ void updateGatePeriod() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG(logINFO, ("\tSetting Gate Period to %lld ns\n", (long long int)max));
|
LOG(logINFO, ("\tUpdating Gate Period to %lld ns\n", (long long int)max));
|
||||||
max *= (1E-9 * getFrequency(SYSTEM_C0));
|
max *= (1E-9 * getFrequency(SYSTEM_C0));
|
||||||
set64BitReg(max, ASIC_EXP_GATE_PERIOD_LSB_REG,
|
set64BitReg(max, ASIC_EXP_GATE_PERIOD_LSB_REG,
|
||||||
ASIC_EXP_GATE_PERIOD_MSB_REG);
|
ASIC_EXP_GATE_PERIOD_MSB_REG);
|
||||||
@ -714,14 +731,22 @@ int setExpTime(int gateIndex, int64_t val) {
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
if (val < 0) {
|
if (val < 0) {
|
||||||
LOG(logERROR, ("Invalid exptime (index:%d): %lld ns\n", gateIndex,
|
LOG(logERROR,
|
||||||
(long long int)val));
|
("Invalid exptime%d : %lld ns\n", gateIndex, (long long int)val));
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
LOG(logINFO, ("Setting exptime %lld ns (index:%d)\n", (long long int)val,
|
LOG(logINFO,
|
||||||
gateIndex));
|
("Setting exptime%d to %lld ns\n", gateIndex, (long long int)val));
|
||||||
val *= (1E-9 * getFrequency(SYSTEM_C0));
|
val *= (1E-9 * getFrequency(SYSTEM_C0));
|
||||||
|
|
||||||
|
// set in register only if counter enabled
|
||||||
|
exptimeReg[gateIndex] = val;
|
||||||
|
if (getCounterMask() & (1 << gateIndex)) {
|
||||||
set64BitReg(val, alsb, amsb);
|
set64BitReg(val, alsb, amsb);
|
||||||
|
} else {
|
||||||
|
LOG(logWARNING, ("Writing 0 to reg (counter disabled)\n"));
|
||||||
|
set64BitReg(0, alsb, amsb);
|
||||||
|
}
|
||||||
|
|
||||||
// validate for tolerance
|
// validate for tolerance
|
||||||
int64_t retval = getExpTime(gateIndex);
|
int64_t retval = getExpTime(gateIndex);
|
||||||
@ -755,7 +780,15 @@ int64_t getExpTime(int gateIndex) {
|
|||||||
LOG(logERROR, ("Invalid gate index: %d\n", gateIndex));
|
LOG(logERROR, ("Invalid gate index: %d\n", gateIndex));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return get64BitReg(alsb, amsb) / (1E-9 * getFrequency(SYSTEM_C0));
|
|
||||||
|
uint64_t retval = 0;
|
||||||
|
// read from register if counter enabled
|
||||||
|
if (getCounterMask() & (1 << gateIndex)) {
|
||||||
|
retval = get64BitReg(alsb, amsb);
|
||||||
|
} else {
|
||||||
|
retval = exptimeReg[gateIndex];
|
||||||
|
}
|
||||||
|
return retval / (1E-9 * getFrequency(SYSTEM_C0));
|
||||||
}
|
}
|
||||||
|
|
||||||
int setGateDelay(int gateIndex, int64_t val) {
|
int setGateDelay(int gateIndex, int64_t val) {
|
||||||
@ -779,14 +812,22 @@ int setGateDelay(int gateIndex, int64_t val) {
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
if (val < 0) {
|
if (val < 0) {
|
||||||
LOG(logERROR, ("Invalid gate delay (index:%d): %lld ns\n", gateIndex,
|
LOG(logERROR, ("Invalid gate delay%d : %lld ns\n", gateIndex,
|
||||||
(long long int)val));
|
(long long int)val));
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
LOG(logINFO, ("Setting gate delay %lld ns (index:%d)\n", (long long int)val,
|
LOG(logINFO,
|
||||||
gateIndex));
|
("Setting gate delay%d to %lld ns\n", gateIndex, (long long int)val));
|
||||||
val *= (1E-9 * getFrequency(SYSTEM_C0));
|
val *= (1E-9 * getFrequency(SYSTEM_C0));
|
||||||
|
|
||||||
|
// set in register only if counter enabled
|
||||||
|
gateDelayReg[gateIndex] = val;
|
||||||
|
if (getCounterMask() & (1 << gateIndex)) {
|
||||||
set64BitReg(val, alsb, amsb);
|
set64BitReg(val, alsb, amsb);
|
||||||
|
} else {
|
||||||
|
LOG(logWARNING, ("Writing 0 to reg (counter disabled)\n"));
|
||||||
|
set64BitReg(0, alsb, amsb);
|
||||||
|
}
|
||||||
|
|
||||||
// validate for tolerance
|
// validate for tolerance
|
||||||
int64_t retval = getGateDelay(gateIndex);
|
int64_t retval = getGateDelay(gateIndex);
|
||||||
@ -820,7 +861,15 @@ int64_t getGateDelay(int gateIndex) {
|
|||||||
LOG(logERROR, ("Invalid gate index: %d\n", gateIndex));
|
LOG(logERROR, ("Invalid gate index: %d\n", gateIndex));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return get64BitReg(alsb, amsb) / (1E-9 * getFrequency(SYSTEM_C0));
|
|
||||||
|
uint64_t retval = 0;
|
||||||
|
// read from register if counter enabled
|
||||||
|
if (getCounterMask() & (1 << gateIndex)) {
|
||||||
|
retval = get64BitReg(alsb, amsb);
|
||||||
|
} else {
|
||||||
|
retval = gateDelayReg[gateIndex];
|
||||||
|
}
|
||||||
|
return retval / (1E-9 * getFrequency(SYSTEM_C0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setCounterMask(uint32_t arg) {
|
void setCounterMask(uint32_t arg) {
|
||||||
@ -835,7 +884,13 @@ void setCounterMask(uint32_t arg) {
|
|||||||
LOG(logDEBUG, ("Config Reg: 0x%x\n", bus_r(addr)));
|
LOG(logDEBUG, ("Config Reg: 0x%x\n", bus_r(addr)));
|
||||||
|
|
||||||
updatePacketizing();
|
updatePacketizing();
|
||||||
updateGatePeriod();
|
LOG(logINFO, ("\tUpdating Exptime and Gate Delay\n"));
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
uint64_t ns = exptimeReg[i] / (1E-9 * getFrequency(SYSTEM_C0));
|
||||||
|
setExpTime(i, ns);
|
||||||
|
ns = gateDelayReg[i] / (1E-9 * getFrequency(SYSTEM_C0));
|
||||||
|
setGateDelay(i, ns);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t getCounterMask() {
|
uint32_t getCounterMask() {
|
||||||
@ -844,6 +899,7 @@ uint32_t getCounterMask() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void updatePacketizing() {
|
void updatePacketizing() {
|
||||||
|
LOG(logINFO, ("\tUpdating Packetizing\n"));
|
||||||
const int ncounters = __builtin_popcount(getCounterMask());
|
const int ncounters = __builtin_popcount(getCounterMask());
|
||||||
const int tgEnable = enableTenGigabitEthernet(-1);
|
const int tgEnable = enableTenGigabitEthernet(-1);
|
||||||
int packetsPerFrame = 0;
|
int packetsPerFrame = 0;
|
||||||
@ -1025,9 +1081,24 @@ int setTrimbits(int *trimbits) {
|
|||||||
LOG(logINFO, ("Trimbits validated\n"));
|
LOG(logINFO, ("Trimbits validated\n"));
|
||||||
trimmingPrint = logDEBUG5;
|
trimmingPrint = logDEBUG5;
|
||||||
|
|
||||||
|
// remember previous run clock
|
||||||
|
uint32_t prevRunClk = clkDivider[SYSTEM_C0];
|
||||||
|
|
||||||
|
// set to trimming clock
|
||||||
|
if (setClockDivider(SYSTEM_C0, DEFAULT_TRIMMING_RUN_CLKDIV) == FAIL) {
|
||||||
|
LOG(logERROR,
|
||||||
|
("Could not start trimming. Could not set to trimming clock\n"));
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// trimming
|
||||||
|
int error = 0;
|
||||||
uint64_t patword = 0;
|
uint64_t patword = 0;
|
||||||
int iaddr = 0;
|
int iaddr = 0;
|
||||||
for (int ichip = 0; ichip < NCHIP; ichip++) {
|
for (int ichip = 0; ichip < NCHIP; ichip++) {
|
||||||
|
if (error != 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
LOG(logDEBUG1, (" Chip %d\n", ichip));
|
LOG(logDEBUG1, (" Chip %d\n", ichip));
|
||||||
iaddr = 0;
|
iaddr = 0;
|
||||||
patword = 0;
|
patword = 0;
|
||||||
@ -1118,8 +1189,8 @@ int setTrimbits(int *trimbits) {
|
|||||||
if (iaddr >= MAX_PATTERN_LENGTH) {
|
if (iaddr >= MAX_PATTERN_LENGTH) {
|
||||||
LOG(logERROR, ("Addr 0x%x is past max_address_length 0x%x!\n",
|
LOG(logERROR, ("Addr 0x%x is past max_address_length 0x%x!\n",
|
||||||
iaddr, MAX_PATTERN_LENGTH));
|
iaddr, MAX_PATTERN_LENGTH));
|
||||||
trimmingPrint = logINFO;
|
error = 1;
|
||||||
return FAIL;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set pattern wait address
|
// set pattern wait address
|
||||||
@ -1141,12 +1212,25 @@ int setTrimbits(int *trimbits) {
|
|||||||
startPattern();
|
startPattern();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (error == 0) {
|
||||||
// copy trimbits locally
|
// copy trimbits locally
|
||||||
for (int ichan = 0; ichan < ((detectorModules)->nchan); ++ichan) {
|
for (int ichan = 0; ichan < ((detectorModules)->nchan); ++ichan) {
|
||||||
detectorChans[ichan] = trimbits[ichan];
|
detectorChans[ichan] = trimbits[ichan];
|
||||||
}
|
}
|
||||||
trimmingPrint = logINFO;
|
|
||||||
LOG(logINFO, ("All trimbits have been loaded\n"));
|
LOG(logINFO, ("All trimbits have been loaded\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
trimmingPrint = logINFO;
|
||||||
|
// set back to previous clock
|
||||||
|
if (setClockDivider(SYSTEM_C0, prevRunClk) == FAIL) {
|
||||||
|
LOG(logERROR, ("Could not set to previous run clock after trimming\n"));
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error != 0) {
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1268,29 +1352,30 @@ int setHighVoltage(int val) {
|
|||||||
|
|
||||||
/* parameters - timing */
|
/* parameters - timing */
|
||||||
void setTiming(enum timingMode arg) {
|
void setTiming(enum timingMode arg) {
|
||||||
|
uint32_t addr = CONFIG_REG;
|
||||||
switch (arg) {
|
switch (arg) {
|
||||||
case AUTO_TIMING:
|
case AUTO_TIMING:
|
||||||
LOG(logINFO, ("Set Timing: Auto (Int. Trigger, Int. Gating)\n"));
|
LOG(logINFO, ("Set Timing: Auto (Int. Trigger, Int. Gating)\n"));
|
||||||
bus_w(EXT_SIGNAL_REG, bus_r(EXT_SIGNAL_REG) & ~EXT_SIGNAL_MSK);
|
bus_w(addr, bus_r(addr) & ~CONFIG_TRIGGER_ENA_MSK);
|
||||||
bus_w(ASIC_EXP_STATUS_REG,
|
bus_w(ASIC_EXP_STATUS_REG,
|
||||||
bus_r(ASIC_EXP_STATUS_REG) & ~ASIC_EXP_STAT_GATE_SRC_EXT_MSK);
|
bus_r(ASIC_EXP_STATUS_REG) & ~ASIC_EXP_STAT_GATE_SRC_EXT_MSK);
|
||||||
break;
|
break;
|
||||||
case TRIGGER_EXPOSURE:
|
case TRIGGER_EXPOSURE:
|
||||||
LOG(logINFO, ("Set Timing: Trigger (Ext. Trigger, Int. Gating)\n"));
|
LOG(logINFO, ("Set Timing: Trigger (Ext. Trigger, Int. Gating)\n"));
|
||||||
bus_w(EXT_SIGNAL_REG, bus_r(EXT_SIGNAL_REG) | EXT_SIGNAL_MSK);
|
bus_w(addr, bus_r(addr) | CONFIG_TRIGGER_ENA_MSK);
|
||||||
bus_w(ASIC_EXP_STATUS_REG,
|
bus_w(ASIC_EXP_STATUS_REG,
|
||||||
bus_r(ASIC_EXP_STATUS_REG) & ~ASIC_EXP_STAT_GATE_SRC_EXT_MSK);
|
bus_r(ASIC_EXP_STATUS_REG) & ~ASIC_EXP_STAT_GATE_SRC_EXT_MSK);
|
||||||
break;
|
break;
|
||||||
case GATED:
|
case GATED:
|
||||||
LOG(logINFO, ("Set Timing: Gating (Int. Trigger, Ext. Gating)\n"));
|
LOG(logINFO, ("Set Timing: Gating (Int. Trigger, Ext. Gating)\n"));
|
||||||
bus_w(EXT_SIGNAL_REG, bus_r(EXT_SIGNAL_REG) & ~EXT_SIGNAL_MSK);
|
bus_w(addr, bus_r(addr) & ~CONFIG_TRIGGER_ENA_MSK);
|
||||||
bus_w(ASIC_EXP_STATUS_REG,
|
bus_w(ASIC_EXP_STATUS_REG,
|
||||||
bus_r(ASIC_EXP_STATUS_REG) | ASIC_EXP_STAT_GATE_SRC_EXT_MSK);
|
bus_r(ASIC_EXP_STATUS_REG) | ASIC_EXP_STAT_GATE_SRC_EXT_MSK);
|
||||||
break;
|
break;
|
||||||
case TRIGGER_GATED:
|
case TRIGGER_GATED:
|
||||||
LOG(logINFO,
|
LOG(logINFO,
|
||||||
("Set Timing: Trigger_Gating (Ext. Trigger, Ext. Gating)\n"));
|
("Set Timing: Trigger_Gating (Ext. Trigger, Ext. Gating)\n"));
|
||||||
bus_w(EXT_SIGNAL_REG, bus_r(EXT_SIGNAL_REG) | EXT_SIGNAL_MSK);
|
bus_w(addr, bus_r(addr) | CONFIG_TRIGGER_ENA_MSK);
|
||||||
bus_w(ASIC_EXP_STATUS_REG,
|
bus_w(ASIC_EXP_STATUS_REG,
|
||||||
bus_r(ASIC_EXP_STATUS_REG) | ASIC_EXP_STAT_GATE_SRC_EXT_MSK);
|
bus_r(ASIC_EXP_STATUS_REG) | ASIC_EXP_STAT_GATE_SRC_EXT_MSK);
|
||||||
break;
|
break;
|
||||||
@ -1301,7 +1386,7 @@ void setTiming(enum timingMode arg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum timingMode getTiming() {
|
enum timingMode getTiming() {
|
||||||
uint32_t extTrigger = (bus_r(EXT_SIGNAL_REG) & EXT_SIGNAL_MSK);
|
uint32_t extTrigger = (bus_r(CONFIG_REG) & CONFIG_TRIGGER_ENA_MSK);
|
||||||
uint32_t extGate =
|
uint32_t extGate =
|
||||||
(bus_r(ASIC_EXP_STATUS_REG) & ASIC_EXP_STAT_GATE_SRC_EXT_MSK);
|
(bus_r(ASIC_EXP_STATUS_REG) & ASIC_EXP_STAT_GATE_SRC_EXT_MSK);
|
||||||
if (extTrigger) {
|
if (extTrigger) {
|
||||||
@ -1891,6 +1976,7 @@ int checkDetectorType() {
|
|||||||
char buffer[MAX_STR_LENGTH];
|
char buffer[MAX_STR_LENGTH];
|
||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
fread(buffer, MAX_STR_LENGTH, sizeof(char), fd);
|
fread(buffer, MAX_STR_LENGTH, sizeof(char), fd);
|
||||||
|
fclose(fd);
|
||||||
if (strlen(buffer) == 0) {
|
if (strlen(buffer) == 0) {
|
||||||
LOG(logERROR,
|
LOG(logERROR,
|
||||||
("Could not read file %s to get type of the module attached\n",
|
("Could not read file %s to get type of the module attached\n",
|
||||||
@ -2322,6 +2408,22 @@ int softwareTrigger() {
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int startReadOut() {
|
||||||
|
LOG(logINFOBLUE, ("Starting Readout\n"));
|
||||||
|
#ifdef VIRTUAL
|
||||||
|
// cannot set #frames and exptiem temporarily to 1 and 0,
|
||||||
|
// because have to set it back after readout (but this is non blocking)
|
||||||
|
return startStateMachine();
|
||||||
|
#endif
|
||||||
|
cleanFifos();
|
||||||
|
|
||||||
|
// start readout
|
||||||
|
bus_w(CONTROL_REG, bus_r(CONTROL_REG) | CONTROL_STRT_READOUT_MSK);
|
||||||
|
|
||||||
|
LOG(logINFO, ("Status Register: %08x\n", bus_r(STATUS_REG)));
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
enum runStatus getRunStatus() {
|
enum runStatus getRunStatus() {
|
||||||
LOG(logDEBUG1, ("Getting status\n"));
|
LOG(logDEBUG1, ("Getting status\n"));
|
||||||
// scan error or running
|
// scan error or running
|
||||||
|
@ -39,14 +39,17 @@
|
|||||||
#define DEFAULT_TIMING_MODE (AUTO_TIMING)
|
#define DEFAULT_TIMING_MODE (AUTO_TIMING)
|
||||||
#define DEFAULT_READOUT_C0 (10) //(100000000) // rdo_clk, 100 MHz
|
#define DEFAULT_READOUT_C0 (10) //(100000000) // rdo_clk, 100 MHz
|
||||||
#define DEFAULT_READOUT_C1 (10) //(100000000) // smp sample clk (x2), 100 MHz
|
#define DEFAULT_READOUT_C1 (10) //(100000000) // smp sample clk (x2), 100 MHz
|
||||||
#define DEFAULT_SYSTEM_C0 (20) // (50000000) // run_clk, 50 MHz
|
#define DEFAULT_SYSTEM_C0 (10) //(100000000) // run_clk, 100 MHz
|
||||||
#define DEFAULT_SYSTEM_C1 (10) //(100000000) // sync_clk, 100 MHz
|
#define DEFAULT_SYSTEM_C1 (10) //(100000000) // sync_clk, 100 MHz
|
||||||
#define DEFAULT_SYSTEM_C2 (10) //(100000000) // str_clk, 100 MHz
|
#define DEFAULT_SYSTEM_C2 (10) //(100000000) // str_clk, 100 MHz
|
||||||
#define DEFAULT_SYSTEM_C3 (5) //(200000000) // smp_clk, 200 MHz
|
#define DEFAULT_SYSTEM_C3 (5) //(200000000) // smp_clk, 200 MHz
|
||||||
// (DEFAULT_SYSTEM_C3 only for timing receiver) should not be changed
|
// (DEFAULT_SYSTEM_C3 only for timing receiver) should not be changed
|
||||||
|
#define DEFAULT_TRIMMING_RUN_CLKDIV (40) // (25000000) // 25 MHz
|
||||||
|
|
||||||
#define DEFAULT_ASIC_LATCHING_NUM_PULSES (10)
|
#define DEFAULT_ASIC_LATCHING_NUM_PULSES (10)
|
||||||
#define DEFAULT_MSTR_OTPT_P1_NUM_PULSES (20)
|
#define DEFAULT_MSTR_OTPT_P1_NUM_PULSES (20)
|
||||||
|
#define DEFAULT_ADIF_PIPELINE_VAL (8)
|
||||||
|
#define DEFAULT_ADIF_ADD_OFST_VAL (0)
|
||||||
|
|
||||||
/* Firmware Definitions */
|
/* Firmware Definitions */
|
||||||
#define MAX_TIMESLOT_VAL (0xFFFFFF)
|
#define MAX_TIMESLOT_VAL (0xFFFFFF)
|
||||||
|
@ -40,8 +40,10 @@ int startWritingFPGAprogram(FILE **filefp);
|
|||||||
* When done writing the program, close file pointer and
|
* When done writing the program, close file pointer and
|
||||||
* notify FPGA to pick up the program from flash
|
* notify FPGA to pick up the program from flash
|
||||||
* @param filefp pointer to flash
|
* @param filefp pointer to flash
|
||||||
|
* @return 0 for success, 1 for fail (time taken for fpga to touch flash
|
||||||
|
* exceeded)
|
||||||
*/
|
*/
|
||||||
void stopWritingFPGAprogram(FILE *filefp);
|
int stopWritingFPGAprogram(FILE *filefp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write FPGA Program to flash
|
* Write FPGA Program to flash
|
||||||
|
@ -120,6 +120,7 @@ int setDefaultDacs();
|
|||||||
#endif
|
#endif
|
||||||
#ifdef MYTHEN3D
|
#ifdef MYTHEN3D
|
||||||
void setASICDefaults();
|
void setASICDefaults();
|
||||||
|
void setADIFDefaults();
|
||||||
#endif
|
#endif
|
||||||
#if defined(GOTTHARD2D) || defined(EIGERD)
|
#if defined(GOTTHARD2D) || defined(EIGERD)
|
||||||
int readConfigFile();
|
int readConfigFile();
|
||||||
@ -566,8 +567,7 @@ int stopStateMachine();
|
|||||||
#if defined(EIGERD) || defined(MYTHEN3D)
|
#if defined(EIGERD) || defined(MYTHEN3D)
|
||||||
int softwareTrigger();
|
int softwareTrigger();
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(EIGERD) || defined(MYTHEN3D)
|
||||||
#ifdef EIGERD
|
|
||||||
int startReadOut();
|
int startReadOut();
|
||||||
#endif
|
#endif
|
||||||
enum runStatus getRunStatus();
|
enum runStatus getRunStatus();
|
||||||
|
@ -240,3 +240,4 @@ int set_bad_channels(int);
|
|||||||
int reconfigure_udp(int);
|
int reconfigure_udp(int);
|
||||||
int validate_udp_configuration(int);
|
int validate_udp_configuration(int);
|
||||||
int get_bursts_left(int);
|
int get_bursts_left(int);
|
||||||
|
int start_readout(int);
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
/* global variables */
|
/* global variables */
|
||||||
#define MTDSIZE 10
|
#define MTDSIZE 10
|
||||||
|
#define MAX_TIME_FPGA_TOUCH_FLASH_US (10 * 1000 * 1000) // 10s
|
||||||
|
|
||||||
int gpioDefined = 0;
|
int gpioDefined = 0;
|
||||||
char mtdvalue[MTDSIZE] = {0};
|
char mtdvalue[MTDSIZE] = {0};
|
||||||
@ -99,32 +100,36 @@ int startWritingFPGAprogram(FILE **filefp) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void stopWritingFPGAprogram(FILE *filefp) {
|
int stopWritingFPGAprogram(FILE *filefp) {
|
||||||
LOG(logDEBUG1, ("Stopping of writing FPGA program\n"));
|
LOG(logDEBUG1, ("Stopping of writing FPGA program\n"));
|
||||||
|
|
||||||
int wait = 0;
|
|
||||||
if (filefp != NULL) {
|
if (filefp != NULL) {
|
||||||
fclose(filefp);
|
fclose(filefp);
|
||||||
wait = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// touch and program
|
// touch and program
|
||||||
FPGATouchFlash();
|
FPGATouchFlash();
|
||||||
|
|
||||||
if (wait) {
|
LOG(logINFO, ("Waiting for FPGA to program from flash\n"));
|
||||||
LOG(logDEBUG1, ("Waiting for FPGA to program from flash\n"));
|
|
||||||
// waiting for success or done
|
// waiting for success or done
|
||||||
char output[255];
|
char output[255];
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
int timeSpent = 0;
|
||||||
while (res == 0) {
|
while (res == 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");
|
FILE *sysFile = popen("cat /sys/class/gpio/gpio7/value", "r");
|
||||||
fgets(output, sizeof(output), sysFile);
|
fgets(output, sizeof(output), sysFile);
|
||||||
pclose(sysFile);
|
pclose(sysFile);
|
||||||
sscanf(output, "%d", &res);
|
sscanf(output, "%d", &res);
|
||||||
LOG(logDEBUG1, ("gpi07 returned %d\n", res));
|
LOG(logDEBUG1, ("gpi07 returned %d\n", res));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
LOG(logINFO, ("FPGA has picked up the program from flash\n"));
|
LOG(logINFO, ("FPGA has picked up the program from flash\n"));
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int writeFPGAProgram(char *fpgasrc, uint64_t fsize, FILE *filefp) {
|
int writeFPGAProgram(char *fpgasrc, uint64_t fsize, FILE *filefp) {
|
||||||
|
@ -358,6 +358,7 @@ void function_table() {
|
|||||||
flist[F_RECONFIGURE_UDP] = &reconfigure_udp;
|
flist[F_RECONFIGURE_UDP] = &reconfigure_udp;
|
||||||
flist[F_VALIDATE_UDP_CONFIG] = &validate_udp_configuration;
|
flist[F_VALIDATE_UDP_CONFIG] = &validate_udp_configuration;
|
||||||
flist[F_GET_BURSTS_LEFT] = &get_bursts_left;
|
flist[F_GET_BURSTS_LEFT] = &get_bursts_left;
|
||||||
|
flist[F_START_READOUT] = &start_readout;
|
||||||
|
|
||||||
// check
|
// check
|
||||||
if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) {
|
if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) {
|
||||||
@ -3719,6 +3720,7 @@ int program_fpga(int file_des) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// writing to flash part by part
|
// writing to flash part by part
|
||||||
|
int clientSocketCrash = 0;
|
||||||
while (ret != FAIL && filesize) {
|
while (ret != FAIL && filesize) {
|
||||||
|
|
||||||
unitprogramsize = MAX_FPGAPROGRAMSIZE; // 2mb
|
unitprogramsize = MAX_FPGAPROGRAMSIZE; // 2mb
|
||||||
@ -3729,9 +3731,13 @@ int program_fpga(int file_des) {
|
|||||||
(long long unsigned int)filesize));
|
(long long unsigned int)filesize));
|
||||||
|
|
||||||
// receive part of program
|
// receive part of program
|
||||||
if (receiveData(file_des, fpgasrc, unitprogramsize, OTHER) < 0)
|
if (receiveData(file_des, fpgasrc, unitprogramsize, OTHER) < 0) {
|
||||||
return printSocketReadError();
|
printSocketReadError();
|
||||||
|
clientSocketCrash = 1;
|
||||||
|
ret = FAIL;
|
||||||
|
}
|
||||||
|
// client has not crashed yet, so write to flash and send ret
|
||||||
|
else {
|
||||||
if (!(unitprogramsize - filesize)) {
|
if (!(unitprogramsize - filesize)) {
|
||||||
fpgasrc[unitprogramsize] = '\0';
|
fpgasrc[unitprogramsize] = '\0';
|
||||||
filesize -= unitprogramsize;
|
filesize -= unitprogramsize;
|
||||||
@ -3743,7 +3749,10 @@ int program_fpga(int file_des) {
|
|||||||
ret = writeFPGAProgram(fpgasrc, unitprogramsize, fp);
|
ret = writeFPGAProgram(fpgasrc, unitprogramsize, fp);
|
||||||
Server_SendResult(file_des, INT32, NULL, 0);
|
Server_SendResult(file_des, INT32, NULL, 0);
|
||||||
if (ret == FAIL) {
|
if (ret == FAIL) {
|
||||||
LOG(logERROR, ("Failure: Breaking out of program receiving\n"));
|
strcpy(mess, "Could not write to flash. Breaking out of "
|
||||||
|
"program receiving. Try to flash again "
|
||||||
|
"without rebooting.\n");
|
||||||
|
LOG(logERROR, (mess));
|
||||||
} else {
|
} else {
|
||||||
// print progress
|
// print progress
|
||||||
LOG(logINFO,
|
LOG(logINFO,
|
||||||
@ -3753,18 +3762,30 @@ int program_fpga(int file_des) {
|
|||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ret == OK) {
|
|
||||||
LOG(logINFO, ("Done copying program\n"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ret == OK) {
|
||||||
|
LOG(logINFO, ("Done copying program\n"));
|
||||||
// closing file pointer to flash and informing FPGA
|
// closing file pointer to flash and informing FPGA
|
||||||
stopWritingFPGAprogram(fp);
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// free resources
|
// free resources
|
||||||
free(fpgasrc);
|
free(fpgasrc);
|
||||||
if (fp != NULL)
|
if (fp != NULL)
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
|
// send final ret (if no client crash)
|
||||||
|
if (clientSocketCrash == 0) {
|
||||||
|
Server_SendResult(file_des, INT32, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
#endif // end of Blackfin programming
|
#endif // end of Blackfin programming
|
||||||
if (ret == FAIL) {
|
if (ret == FAIL) {
|
||||||
LOG(logERROR, ("Program FPGA FAIL!\n"));
|
LOG(logERROR, ("Program FPGA FAIL!\n"));
|
||||||
@ -8084,3 +8105,43 @@ int get_bursts_left(int file_des) {
|
|||||||
#endif
|
#endif
|
||||||
return Server_SendResult(file_des, INT64, &retval, sizeof(retval));
|
return Server_SendResult(file_des, INT64, &retval, sizeof(retval));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int start_readout(int file_des) {
|
||||||
|
ret = OK;
|
||||||
|
memset(mess, 0, sizeof(mess));
|
||||||
|
#ifndef MYTHEN3D
|
||||||
|
functionNotImplemented();
|
||||||
|
#else
|
||||||
|
if (Server_VerifyLock() == OK) {
|
||||||
|
enum runStatus s = getRunStatus();
|
||||||
|
if (s == RUNNING || s == WAITING) {
|
||||||
|
ret = FAIL;
|
||||||
|
strcpy(mess, "Could not start readout because the detector is "
|
||||||
|
"already running!\n");
|
||||||
|
LOG(logERROR, (mess));
|
||||||
|
} else if (configured == FAIL) {
|
||||||
|
ret = FAIL;
|
||||||
|
strcpy(mess, "Could not start readout because ");
|
||||||
|
strcat(mess, configureMessage);
|
||||||
|
LOG(logERROR, (mess));
|
||||||
|
} else {
|
||||||
|
memset(scanErrMessage, 0, MAX_STR_LENGTH);
|
||||||
|
sharedMemory_setScanStop(0);
|
||||||
|
sharedMemory_setScanStatus(IDLE); // if it was error
|
||||||
|
// start readout
|
||||||
|
ret = startReadOut();
|
||||||
|
if (ret == FAIL) {
|
||||||
|
#ifdef VIRTUAL
|
||||||
|
sprintf(mess,
|
||||||
|
"Could not start readout. Could not create udp "
|
||||||
|
"socket in server. Check udp_dstip & udp_dstport.\n");
|
||||||
|
#else
|
||||||
|
sprintf(mess, "Could not start readout\n");
|
||||||
|
#endif
|
||||||
|
LOG(logERROR, (mess));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return Server_SendResult(file_des, INT32, NULL, 0);
|
||||||
|
}
|
||||||
|
@ -456,6 +456,11 @@ class Detector {
|
|||||||
* WAITING and automatically returns to idle at the end of acquisition. */
|
* WAITING and automatically returns to idle at the end of acquisition. */
|
||||||
void startDetector();
|
void startDetector();
|
||||||
|
|
||||||
|
/** [Mythen3] Non blocking: start detector readout of counters in chip.
|
||||||
|
* Status changes to TRANSMITTING and automatically returns to idle at the
|
||||||
|
* end of readout. */
|
||||||
|
void startDetectorReadout();
|
||||||
|
|
||||||
/** Non blocking: Abort detector acquisition. Status changes to IDLE or
|
/** Non blocking: Abort detector acquisition. Status changes to IDLE or
|
||||||
* STOPPED. Goes to stop server. */
|
* STOPPED. Goes to stop server. */
|
||||||
void stopDetector();
|
void stopDetector();
|
||||||
|
@ -1027,12 +1027,12 @@ std::string CmdProxy::Scan(int action) {
|
|||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
os << cmd << ' ';
|
os << cmd << ' ';
|
||||||
if (action == defs::HELP_ACTION) {
|
if (action == defs::HELP_ACTION) {
|
||||||
os << "[dac_name|0|trimbit_scan] [start_val] [stop_val] "
|
os << "[dac_name|0|trimbits] [start_val] [stop_val] "
|
||||||
"[step_size] [dac settling time ns|us|ms|s]\n\tEnables/ disables "
|
"[step_size] [dac settling time ns|us|ms|s]\n\tEnables/ disables "
|
||||||
"scans for dac and trimbits \n\tEnabling scan sets number of "
|
"scans for dac and trimbits \n\tEnabling scan sets number of "
|
||||||
"frames to number of steps in receiver. \n\tTo cancel scan "
|
"frames to number of steps in receiver. \n\tTo cancel scan "
|
||||||
"configuration, set dac to '0', which also sets number of frames "
|
"configuration, set dac to '0', which also sets number of frames "
|
||||||
"to 1. \n\t[Eiger][Mythen3] Use trimbit_scan as dac name for a "
|
"to 1. \n\t[Eiger][Mythen3] Use trimbits as dac name for a "
|
||||||
"trimbit scan."
|
"trimbit scan."
|
||||||
<< '\n';
|
<< '\n';
|
||||||
} else if (action == defs::GET_ACTION) {
|
} else if (action == defs::GET_ACTION) {
|
||||||
|
@ -835,6 +835,7 @@ class CmdProxy {
|
|||||||
{"rx_start", &CmdProxy::rx_start},
|
{"rx_start", &CmdProxy::rx_start},
|
||||||
{"rx_stop", &CmdProxy::rx_stop},
|
{"rx_stop", &CmdProxy::rx_stop},
|
||||||
{"start", &CmdProxy::start},
|
{"start", &CmdProxy::start},
|
||||||
|
{"readout", &CmdProxy::readout},
|
||||||
{"stop", &CmdProxy::stop},
|
{"stop", &CmdProxy::stop},
|
||||||
{"rx_status", &CmdProxy::ReceiverStatus},
|
{"rx_status", &CmdProxy::ReceiverStatus},
|
||||||
{"status", &CmdProxy::DetectorStatus},
|
{"status", &CmdProxy::DetectorStatus},
|
||||||
@ -1429,7 +1430,14 @@ class CmdProxy {
|
|||||||
EXECUTE_SET_COMMAND_NOID(
|
EXECUTE_SET_COMMAND_NOID(
|
||||||
start, startDetector,
|
start, startDetector,
|
||||||
"\n\tStarts detector acquisition. Status changes to RUNNING or WAITING "
|
"\n\tStarts detector acquisition. Status changes to RUNNING or WAITING "
|
||||||
"and automatically returns to idle at the end of acquisition.");
|
"and automatically returns to idle at the end of acquisition. If the "
|
||||||
|
"acquisition was abruptly stopped, some detectors come back to "
|
||||||
|
"STOPPED.");
|
||||||
|
|
||||||
|
EXECUTE_SET_COMMAND_NOID(
|
||||||
|
readout, startDetectorReadout,
|
||||||
|
"\n\t[Mythen3] Starts detector readout. Status changes to TRANSMITTING "
|
||||||
|
"and automatically returns to idle at the end of readout.");
|
||||||
|
|
||||||
EXECUTE_SET_COMMAND_NOID(stop, stopDetector,
|
EXECUTE_SET_COMMAND_NOID(stop, stopDetector,
|
||||||
"\n\tAbort detector acquisition. Status changes "
|
"\n\tAbort detector acquisition. Status changes "
|
||||||
@ -1486,7 +1494,8 @@ class CmdProxy {
|
|||||||
udp_srcip2, getSourceUDPIP2, setSourceUDPIP2, IpAddr,
|
udp_srcip2, getSourceUDPIP2, setSourceUDPIP2, IpAddr,
|
||||||
"[x.x.x.x]\n\t[Jungfrau][Gotthard2] Ip address of the detector "
|
"[x.x.x.x]\n\t[Jungfrau][Gotthard2] Ip address of the detector "
|
||||||
"(source) udp interface 2. Must be same subnet as destination udp "
|
"(source) udp interface 2. Must be same subnet as destination udp "
|
||||||
"ip2.\n\t [Jungfrau] bottom half \n\t [Gotthard2] veto debugging.");
|
"ip2.\n\t [Jungfrau] top half or inner interface\n\t [Gotthard2] veto "
|
||||||
|
"debugging.");
|
||||||
|
|
||||||
INTEGER_COMMAND_VEC_ID(
|
INTEGER_COMMAND_VEC_ID(
|
||||||
udp_srcmac, getSourceUDPMAC, setSourceUDPMAC, MacAddr,
|
udp_srcmac, getSourceUDPMAC, setSourceUDPMAC, MacAddr,
|
||||||
@ -1494,10 +1503,10 @@ class CmdProxy {
|
|||||||
"interface. \n\t[Eiger] Do not set as detector will replace with its "
|
"interface. \n\t[Eiger] Do not set as detector will replace with its "
|
||||||
"own DHCP Mac (1G) or DHCP Mac + 1 (10G).");
|
"own DHCP Mac (1G) or DHCP Mac + 1 (10G).");
|
||||||
|
|
||||||
INTEGER_COMMAND_VEC_ID(
|
INTEGER_COMMAND_VEC_ID(udp_srcmac2, getSourceUDPMAC2, setSourceUDPMAC2,
|
||||||
udp_srcmac2, getSourceUDPMAC2, setSourceUDPMAC2, MacAddr,
|
MacAddr,
|
||||||
"[x:x:x:x:x:x]\n\t[Jungfrau] Mac address of the bottom "
|
"[x:x:x:x:x:x]\n\t[Jungfrau] Mac address of the top "
|
||||||
"half of detector (source) udp interface. ");
|
"half or inner (source) udp interface. ");
|
||||||
|
|
||||||
INTEGER_COMMAND_VEC_ID(
|
INTEGER_COMMAND_VEC_ID(
|
||||||
udp_dstmac, getDestinationUDPMAC, setDestinationUDPMAC, MacAddr,
|
udp_dstmac, getDestinationUDPMAC, setDestinationUDPMAC, MacAddr,
|
||||||
@ -1511,7 +1520,8 @@ class CmdProxy {
|
|||||||
"[x:x:x:x:x:x]\n\t[Jungfrau] Mac address of the receiver (destination) "
|
"[x:x:x:x:x:x]\n\t[Jungfrau] Mac address of the receiver (destination) "
|
||||||
"udp interface 2. Not mandatory to set as udp_dstip2 retrieves it from "
|
"udp interface 2. Not mandatory to set as udp_dstip2 retrieves it from "
|
||||||
"slsReceiver process but must be set if you use a custom receiver (not "
|
"slsReceiver process but must be set if you use a custom receiver (not "
|
||||||
"slsReceiver). \n\t [Jungfrau] bottom half \n\t [Gotthard2] veto "
|
"slsReceiver). \n\t [Jungfrau] top half or inner interface \n\t "
|
||||||
|
"[Gotthard2] veto "
|
||||||
"debugging.");
|
"debugging.");
|
||||||
|
|
||||||
INTEGER_COMMAND_VEC_ID_GET(
|
INTEGER_COMMAND_VEC_ID_GET(
|
||||||
@ -1527,7 +1537,8 @@ class CmdProxy {
|
|||||||
"[n]\n\t[Jungfrau][Eiger][Gotthard2] Port number of the "
|
"[n]\n\t[Jungfrau][Eiger][Gotthard2] Port number of the "
|
||||||
"receiver (destination) udp interface 2. Default is 50002. "
|
"receiver (destination) udp interface 2. Default is 50002. "
|
||||||
"\n\tIf multi command, ports for each module is calculated "
|
"\n\tIf multi command, ports for each module is calculated "
|
||||||
"(incremented by 2) \n\t[Jungfrau] bottom half \n\t[Eiger] "
|
"(incremented by 2) \n\t[Jungfrau] top half or inner interface "
|
||||||
|
"\n\t[Eiger] "
|
||||||
"right half \n\t[Gotthard2] veto debugging");
|
"right half \n\t[Gotthard2] veto debugging");
|
||||||
|
|
||||||
EXECUTE_SET_COMMAND(
|
EXECUTE_SET_COMMAND(
|
||||||
|
@ -593,6 +593,10 @@ void Detector::startDetector() {
|
|||||||
pimpl->Parallel(&Module::startAcquisition, {});
|
pimpl->Parallel(&Module::startAcquisition, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Detector::startDetectorReadout() {
|
||||||
|
pimpl->Parallel(&Module::startReadout, {});
|
||||||
|
}
|
||||||
|
|
||||||
void Detector::stopDetector() { pimpl->Parallel(&Module::stopAcquisition, {}); }
|
void Detector::stopDetector() { pimpl->Parallel(&Module::stopAcquisition, {}); }
|
||||||
|
|
||||||
Result<defs::runStatus> Detector::getDetectorStatus(Positions pos) const {
|
Result<defs::runStatus> Detector::getDetectorStatus(Positions pos) const {
|
||||||
|
@ -640,24 +640,26 @@ void DetectorImpl::readFrameFromReceiver() {
|
|||||||
if (data) {
|
if (data) {
|
||||||
char *callbackImage = multiframe.get();
|
char *callbackImage = multiframe.get();
|
||||||
int imagesize = multisize;
|
int imagesize = multisize;
|
||||||
|
int nDetActualPixelsX = nDetPixelsX;
|
||||||
|
int nDetActualPixelsY = nDetPixelsY;
|
||||||
|
|
||||||
if (gapPixels) {
|
if (gapPixels) {
|
||||||
int n = InsertGapPixels(multiframe.get(), multigappixels,
|
int n = InsertGapPixels(multiframe.get(), multigappixels,
|
||||||
quadEnable, dynamicRange, nDetPixelsX,
|
quadEnable, dynamicRange,
|
||||||
nDetPixelsY);
|
nDetActualPixelsX, nDetActualPixelsY);
|
||||||
callbackImage = multigappixels;
|
callbackImage = multigappixels;
|
||||||
imagesize = n;
|
imagesize = n;
|
||||||
}
|
}
|
||||||
LOG(logDEBUG) << "Image Info:"
|
LOG(logDEBUG) << "Image Info:"
|
||||||
<< "\n\tnDetPixelsX: " << nDetPixelsX
|
<< "\n\tnDetActualPixelsX: " << nDetActualPixelsX
|
||||||
<< "\n\tnDetPixelsY: " << nDetPixelsY
|
<< "\n\tnDetActualPixelsY: " << nDetActualPixelsY
|
||||||
<< "\n\timagesize: " << imagesize
|
<< "\n\timagesize: " << imagesize
|
||||||
<< "\n\tdynamicRange: " << dynamicRange;
|
<< "\n\tdynamicRange: " << dynamicRange;
|
||||||
|
|
||||||
thisData =
|
thisData = new detectorData(currentProgress, currentFileName,
|
||||||
new detectorData(currentProgress, currentFileName, nDetPixelsX,
|
nDetActualPixelsX, nDetActualPixelsY,
|
||||||
nDetPixelsY, callbackImage, imagesize,
|
callbackImage, imagesize, dynamicRange,
|
||||||
dynamicRange, currentFileIndex, completeImage);
|
currentFileIndex, completeImage);
|
||||||
|
|
||||||
dataReady(
|
dataReady(
|
||||||
thisData, currentFrameIndex,
|
thisData, currentFrameIndex,
|
||||||
|
@ -407,6 +407,11 @@ void Module::startAcquisition() {
|
|||||||
sendToDetector(F_START_ACQUISITION);
|
sendToDetector(F_START_ACQUISITION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Module::startReadout() {
|
||||||
|
shm()->stoppedFlag = false;
|
||||||
|
sendToDetector(F_START_READOUT);
|
||||||
|
}
|
||||||
|
|
||||||
void Module::stopAcquisition() {
|
void Module::stopAcquisition() {
|
||||||
// get status before stopping acquisition
|
// get status before stopping acquisition
|
||||||
runStatus s = ERROR, r = ERROR;
|
runStatus s = ERROR, r = ERROR;
|
||||||
@ -3166,6 +3171,15 @@ void Module::programFPGAviaBlackfin(std::vector<char> buffer) {
|
|||||||
std::cout << std::flush;
|
std::cout << std::flush;
|
||||||
}
|
}
|
||||||
std::cout << '\n';
|
std::cout << '\n';
|
||||||
|
|
||||||
|
// fpga has picked up from flash successfully
|
||||||
|
if (client.Receive<int>() == FAIL) {
|
||||||
|
std::ostringstream os;
|
||||||
|
os << "Detector " << moduleId << " (" << shm()->hostname << ")"
|
||||||
|
<< " returned error: " << client.readErrorMessage();
|
||||||
|
throw RuntimeError(os.str());
|
||||||
|
}
|
||||||
|
|
||||||
LOG(logINFO) << "FPGA programmed successfully";
|
LOG(logINFO) << "FPGA programmed successfully";
|
||||||
rebootController();
|
rebootController();
|
||||||
}
|
}
|
||||||
|
@ -160,6 +160,7 @@ class Module : public virtual slsDetectorDefs {
|
|||||||
void startReceiver();
|
void startReceiver();
|
||||||
void stopReceiver();
|
void stopReceiver();
|
||||||
void startAcquisition();
|
void startAcquisition();
|
||||||
|
void startReadout();
|
||||||
void stopAcquisition();
|
void stopAcquisition();
|
||||||
void restreamStopFromReceiver();
|
void restreamStopFromReceiver();
|
||||||
void startAndReadAll();
|
void startAndReadAll();
|
||||||
|
@ -115,6 +115,23 @@ TEST_CASE("Setting and reading back MYTHEN3 dacs", "[.cmd][.dacs][.new]") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* acquisition */
|
||||||
|
|
||||||
|
TEST_CASE("readout", "[.cmd][.new]") {
|
||||||
|
Detector det;
|
||||||
|
CmdProxy proxy(&det);
|
||||||
|
// PUT only command
|
||||||
|
REQUIRE_THROWS(proxy.Call("readout", {}, -1, GET));
|
||||||
|
auto det_type = det.getDetectorType().squash();
|
||||||
|
if (det_type != defs::MYTHEN3) {
|
||||||
|
REQUIRE_THROWS(proxy.Call("readout", {}, -1, GET));
|
||||||
|
} else {
|
||||||
|
std::ostringstream oss;
|
||||||
|
proxy.Call("readout", {}, -1, PUT, oss);
|
||||||
|
REQUIRE(oss.str() == "readout successful\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Mythen3 Specific */
|
/* Mythen3 Specific */
|
||||||
|
|
||||||
TEST_CASE("counters", "[.cmd][.new]") {
|
TEST_CASE("counters", "[.cmd][.new]") {
|
||||||
|
@ -1423,15 +1423,15 @@ TEST_CASE("scan", "[.cmd][.new]") {
|
|||||||
if (det_type == defs::MYTHEN3 || defs::EIGER) {
|
if (det_type == defs::MYTHEN3 || defs::EIGER) {
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
proxy.Call("scan", {"trimbit_scan", "0", "63", "16", "2s"}, -1, PUT,
|
proxy.Call("scan", {"trimbits", "0", "63", "16", "2s"}, -1, PUT,
|
||||||
oss);
|
oss);
|
||||||
CHECK(oss.str() == "scan [trimbit_scan, 0, 63, 16, 2s]\n");
|
CHECK(oss.str() == "scan [trimbits, 0, 63, 16, 2s]\n");
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
proxy.Call("scan", {}, -1, GET, oss);
|
proxy.Call("scan", {}, -1, GET, oss);
|
||||||
CHECK(oss.str() ==
|
CHECK(oss.str() ==
|
||||||
"scan [enabled\ndac trimbit_scan\nstart 0\nstop 48\nstep "
|
"scan [enabled\ndac trimbits\nstart 0\nstop 48\nstep "
|
||||||
"16\nsettleTime 2s\n]\n");
|
"16\nsettleTime 2s\n]\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -585,7 +585,7 @@ void Implementation::stopReceiver() {
|
|||||||
// udp port number could be the second if selected interface is
|
// udp port number could be the second if selected interface is
|
||||||
// 2 for jungfrau
|
// 2 for jungfrau
|
||||||
"Summary of Port " << udpPortNum[i]
|
"Summary of Port " << udpPortNum[i]
|
||||||
<< "\n\tMissing Packets\t\t: " << mp[i]
|
<< "\n\tMissing Packets\t\t: " << (int64_t)mp[i]
|
||||||
<< "\n\tComplete Frames\t\t: " << nf
|
<< "\n\tComplete Frames\t\t: " << nf
|
||||||
<< "\n\tLast Frame Caught\t: "
|
<< "\n\tLast Frame Caught\t: "
|
||||||
<< listener[i]->GetLastFrameIndexCaught();
|
<< listener[i]->GetLastFrameIndexCaught();
|
||||||
|
@ -30,9 +30,12 @@ void sigInterruptHandler(int p) { sem_post(&semaphore); }
|
|||||||
* prints usage of this example program
|
* prints usage of this example program
|
||||||
*/
|
*/
|
||||||
void printHelp() {
|
void printHelp() {
|
||||||
cprintf(RESET, "Usage:\n"
|
cprintf(
|
||||||
|
RESET,
|
||||||
|
"Usage:\n"
|
||||||
"./slsMultiReceiver(detReceiver) [start_tcp_port] "
|
"./slsMultiReceiver(detReceiver) [start_tcp_port] "
|
||||||
"[num_receivers] [1 for call back, 0 for none]\n\n");
|
"[num_receivers] [optional: 1 for call back (print frame header for "
|
||||||
|
"debugging), 0 for none (default)]\n\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,10 +160,16 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
/** - get number of receivers and start tcp port from command line
|
/** - get number of receivers and start tcp port from command line
|
||||||
* arguments */
|
* arguments */
|
||||||
if ((argc != 4) || (!sscanf(argv[1], "%d", &startTCPPort)) ||
|
if (argc != 3 && argc != 4)
|
||||||
(!sscanf(argv[2], "%d", &numReceivers)) ||
|
|
||||||
(!sscanf(argv[3], "%d", &withCallback)))
|
|
||||||
printHelp();
|
printHelp();
|
||||||
|
if ((argc == 3) && ((!sscanf(argv[1], "%d", &startTCPPort)) ||
|
||||||
|
(!sscanf(argv[2], "%d", &numReceivers))))
|
||||||
|
printHelp();
|
||||||
|
if ((argc == 4) && ((!sscanf(argv[1], "%d", &startTCPPort)) ||
|
||||||
|
(!sscanf(argv[2], "%d", &numReceivers)) ||
|
||||||
|
(!sscanf(argv[3], "%d", &withCallback))))
|
||||||
|
printHelp();
|
||||||
|
|
||||||
cprintf(BLUE, "Parent Process Created [ Tid: %ld ]\n",
|
cprintf(BLUE, "Parent Process Created [ Tid: %ld ]\n",
|
||||||
(long)syscall(SYS_gettid));
|
(long)syscall(SYS_gettid));
|
||||||
cprintf(RESET, "Number of Receivers: %d\n", numReceivers);
|
cprintf(RESET, "Number of Receivers: %d\n", numReceivers);
|
||||||
|
@ -214,6 +214,7 @@ enum detFuncs {
|
|||||||
F_RECONFIGURE_UDP,
|
F_RECONFIGURE_UDP,
|
||||||
F_VALIDATE_UDP_CONFIG,
|
F_VALIDATE_UDP_CONFIG,
|
||||||
F_GET_BURSTS_LEFT,
|
F_GET_BURSTS_LEFT,
|
||||||
|
F_START_READOUT,
|
||||||
|
|
||||||
NUM_DET_FUNCTIONS,
|
NUM_DET_FUNCTIONS,
|
||||||
RECEIVER_ENUM_START = 256, /**< detector function should not exceed this
|
RECEIVER_ENUM_START = 256, /**< detector function should not exceed this
|
||||||
@ -533,6 +534,7 @@ const char* getFunctionNameFromEnum(enum detFuncs func) {
|
|||||||
case F_RECONFIGURE_UDP: return "F_RECONFIGURE_UDP";
|
case F_RECONFIGURE_UDP: return "F_RECONFIGURE_UDP";
|
||||||
case F_VALIDATE_UDP_CONFIG: return "F_VALIDATE_UDP_CONFIG";
|
case F_VALIDATE_UDP_CONFIG: return "F_VALIDATE_UDP_CONFIG";
|
||||||
case F_GET_BURSTS_LEFT: return "F_GET_BURSTS_LEFT";
|
case F_GET_BURSTS_LEFT: return "F_GET_BURSTS_LEFT";
|
||||||
|
case F_START_READOUT: return "F_START_READOUT";
|
||||||
|
|
||||||
case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS";
|
case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS";
|
||||||
case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START";
|
case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START";
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
/** API versions */
|
/** API versions */
|
||||||
#define GITBRANCH "5.0.0-rc2"
|
#define GITBRANCH "developer"
|
||||||
#define APICTB 0x201008
|
|
||||||
#define APIGOTTHARD 0x201008
|
|
||||||
#define APIGOTTHARD2 0x201008
|
|
||||||
#define APIJUNGFRAU 0x201008
|
|
||||||
#define APIMYTHEN3 0x201008
|
|
||||||
#define APIMOENCH 0x201008
|
|
||||||
#define APIEIGER 0x201008
|
|
||||||
#define APILIB 0x201008
|
#define APILIB 0x201008
|
||||||
#define APIRECEIVER 0x201008
|
#define APIRECEIVER 0x201008
|
||||||
#define APIGUI 0x201009
|
#define APIGUI 0x201009
|
||||||
|
#define APIEIGER 0x201009
|
||||||
|
#define APICTB 0x201016
|
||||||
|
#define APIGOTTHARD 0x201016
|
||||||
|
#define APIJUNGFRAU 0x201016
|
||||||
|
#define APIMOENCH 0x201013
|
||||||
|
#define APIMYTHEN3 0x201027
|
||||||
|
#define APIGOTTHARD2 0x201027
|
||||||
|
@ -488,7 +488,7 @@ std::string ToString(const defs::dacIndex s) {
|
|||||||
case defs::ADC_VPP:
|
case defs::ADC_VPP:
|
||||||
return std::string("adcvpp");
|
return std::string("adcvpp");
|
||||||
case defs::TRIMBIT_SCAN:
|
case defs::TRIMBIT_SCAN:
|
||||||
return std::string("trimbit_scan");
|
return std::string("trimbits");
|
||||||
case defs::HIGH_VOLTAGE:
|
case defs::HIGH_VOLTAGE:
|
||||||
return std::string("highvoltage");
|
return std::string("highvoltage");
|
||||||
case defs::IO_DELAY:
|
case defs::IO_DELAY:
|
||||||
@ -848,7 +848,7 @@ template <> defs::dacIndex StringTo(const std::string &s) {
|
|||||||
return defs::IBIAS_SFP;
|
return defs::IBIAS_SFP;
|
||||||
if (s == "adcvpp")
|
if (s == "adcvpp")
|
||||||
return defs::ADC_VPP;
|
return defs::ADC_VPP;
|
||||||
if (s == "trimbit_scan")
|
if (s == "trimbits")
|
||||||
return defs::TRIMBIT_SCAN;
|
return defs::TRIMBIT_SCAN;
|
||||||
if (s == "highvoltage")
|
if (s == "highvoltage")
|
||||||
return defs::HIGH_VOLTAGE;
|
return defs::HIGH_VOLTAGE;
|
||||||
|
Reference in New Issue
Block a user