Compare commits

...

65 Commits

Author SHA1 Message Date
be5fee8126 M3: fixed gain bits with negative polarity 2021-04-12 16:44:47 +02:00
d9cd780386 p gaincap 0 2021-04-12 13:31:10 +02:00
55b4a92453 using setChipStatusRegister 2021-04-07 16:27:40 +02:00
0299d315d5 added command line option 2021-04-01 10:06:37 +02:00
779a2a0199 CSR in trim files 2021-04-01 08:09:04 +02:00
01c785271f WIP 2021-03-31 16:26:36 +02:00
fa25340e5c allow bitwise op on the gain cap 2021-03-29 16:14:10 +02:00
7d605c2c87 names 2021-03-29 14:50:08 +02:00
043d582616 initial implementation 2021-03-29 14:21:48 +02:00
7c4f9ee044 read back of csr 2021-03-26 17:46:11 +01:00
a2007b78e7 updated pybind also for my3regs 2021-03-23 11:48:35 +01:00
7004f43a9a Merge branch 'developer' into my3regs 2021-03-23 11:44:52 +01:00
2b3b5af303 report developer as version 2021-03-23 11:44:25 +01:00
7a67d7e88a minor cmake and servers now reflect developer 2021-03-23 10:54:01 +01:00
60e3fb8aab fixing conflics after merging back release to developer 2021-03-23 10:50:09 +01:00
7955426682 my3: added function to change the gain + some functions for my3 flags added 2021-02-26 18:02:48 +01:00
63259ec5c8 Modified my3 functions for the pattern generator and moved to separate file; created loadPattern function - but should still be used in readDefaultPattern 2021-02-26 16:53:30 +01:00
e8fe203940 New server for JF to go with the new FW (#232)
* Modified Jungfrau speed settings for HW1.0 - FW fix version 1.1.1, compilation date 210218

* Corrected bug. DBIT clk phase is implemented in both HW version 1.0 and 2.0. Previous version did not update the DBIT phase shift on the configuration of a speed.

The new server has been compiled

Co-authored-by: lopez_c <carlos.lopez-cuenca@psi.ch>
2021-02-25 10:26:39 +01:00
10b315c2bd Mythen3 improved synchronization (#231)
Disabling scans for multi module Mythen3, since there is no feedback of the detectors being ready
startDetector first starts the slaves then the master
acquire firs calls startDetector for the slaves then acquire on the master
getMaster to read back from hardware which one is master
2021-02-08 13:28:37 +01:00
f35de3bc2b updated pybind11 to 2.6.2 2021-02-02 14:38:16 +01:00
4caf4cced2 replacing dac values that are out of range after interpolation 2021-01-26 18:11:18 +01:00
1eb70f63ad replacing out of range trimbits with edge values 2021-01-26 17:04:09 +01:00
997e5dd96c fixed buffer overflow but caused by using global instead of local enum 2021-01-26 16:15:40 +01:00
7aeb394514 Pattern.h as a public header files (#229)
It is used in Detector.h.
2021-01-18 08:30:34 +01:00
f9f50f1d84 M3settings (#228)
* added temp m3 settings files

* renames settings noise to trim

* get threshold for M3

* some changes to compile on RH7 and in the server to load the default chip status register at startup

* Updated mythen3DeectorServer_developer executable with correct initialization at startup

Co-authored-by: Erik Frojdh <erik.frojdh@gmail.com>
Co-authored-by: Anna Bergamaschi <anna.bergamaschi@psi.ch>
2021-01-14 12:34:13 +01:00
a62e068a9a M3defaultpattern (#227)
* default pattern for m3 and moench including Python bindings

Co-authored-by: Erik Frojdh <erik.frojdh@gmail.com>
2020-12-09 13:28:39 +01:00
85bc37f04d release updated 2020-12-04 17:01:57 +01:00
a3f5315015 updated RELEASE.txt 2020-12-04 16:49:49 +01:00
d63a182996 updated RELEASE.txt 2020-12-04 14:37:29 +01:00
f147c7bfcb updated RELEASE.txt 2020-12-04 14:36:08 +01:00
4218fe5f2f bugfix from 5.0.2: potentital memory leak in receiver if setDetectorType called directly from outside 2020-12-04 14:33:53 +01:00
511f5a7ca5 Update RELEASE.txt 2020-12-04 14:33:11 +01:00
a5ab5c1fa0 additional constructors for scanPrameters in python 2020-12-04 14:31:08 +01:00
8b7023d9a3 added scanParameters in Python 2020-12-04 14:27:57 +01:00
c8c7bca6e0 bugfix: avoid potentital memory leak in receiver if called outside constructor context 2020-12-04 14:18:16 +01:00
8ddc407e62 Merge pull request #226 from esrf-bliss/potential-generaldata-memory-leak
slsReceiver: avoid potential memory leak: Implementation::generalData
2020-12-04 14:15:12 +01:00
7a2827f693 additional constructors for scanPrameters in python 2020-12-04 13:50:08 +01:00
f4be0b8efa slsReceiver: avoid potential memory leak around Implementation::generalData 2020-12-04 13:20:50 +01:00
a6e23b0509 added scanParameters in Python 2020-12-01 18:40:45 +01:00
9048e7f6c4 Merge pull request #223 from slsdetectorgroup/savepatternbackup
Savepatternbackup
2020-11-30 14:00:31 +01:00
1ce56764fa binaries in 2020-11-30 13:59:55 +01:00
8c091eece2 WIP 2020-11-27 17:06:07 +01:00
d69e238e67 Python binding for Pattern 2020-11-27 17:05:39 +01:00
95fe1720c0 removed commented out lines 2020-11-27 14:44:15 +01:00
69f558c072 constexpr not compiling for rhel7 and warning left 2020-11-27 14:31:43 +01:00
e382df21b9 updated binaries, links in serverBin and deleted v5.0.0 binaries 2020-11-27 14:26:15 +01:00
8e773c97dd pattern load and save works 2020-11-27 14:19:38 +01:00
c043e74c07 wIP 2020-11-27 14:08:06 +01:00
d4518b2ca3 WIP 2020-11-27 13:56:57 +01:00
fd3108a61b WIP 2020-11-27 12:46:54 +01:00
e8fedfa55f uncommented WIP 2020-11-27 12:45:16 +01:00
0eb204bfd3 compile for servers too 2020-11-27 12:37:22 +01:00
d9b2a90651 Introduced pattern class 2020-11-27 10:03:15 +01:00
8ca1d9c50c python wrapper 2020-11-26 14:44:39 +01:00
baff0518bb WIP 2020-11-26 14:13:04 +01:00
2e669c585b WIP 2020-11-26 11:25:29 +01:00
ca0bc3e0f3 WIP 2020-11-26 10:29:09 +01:00
557cab9c50 Merge branch '5.0.1-rc' into developer 2020-11-25 16:24:35 +01:00
a12dd153ef WIP 2020-11-25 15:29:46 +01:00
8bf9f974a3 fixing typo 2020-11-24 20:39:36 +01:00
e63fa1d7c2 Setting pattern from memory (#218)
* ToString accepts c-style arrays

* added patternParameters to python

* fixed patwait time bug in validation

* moved load from file function to patterParameters

* server using patternparamters structure to get pattern

Co-authored-by: Erik Frojdh <erik.frojdh@gmail.com>
2020-11-24 20:32:07 +01:00
9e8c8f4bbc Merge branch '5.0.1-rc' into developer 2020-11-23 11:55:30 +01:00
c120c70678 Merge branch '5.0.1-rc' into developer 2020-11-23 09:20:22 +01:00
10fa57ebb9 binaries updated to reflected developer branch 2020-11-19 16:44:40 +01:00
0ca9115cb8 updating client api branch back to developer 2020-11-19 16:43:58 +01:00
44 changed files with 979 additions and 406 deletions

View File

@ -167,7 +167,7 @@ if (NOT TARGET libzmq)
HINTS ${ZeroMQ_DIR} HINTS ${ZeroMQ_DIR}
) )
else() else()
find_package(ZeroMQ 4) find_package(ZeroMQ 4 QUIET)
endif() endif()

View File

@ -1,7 +1,7 @@
SLS Detector Package 5.1.0 released on 22.03.2020 (Minor Release) SLS Detector Package 5.X.X released on XX.XX.2021 (Minor Release)
=================================================================== ===================================================================
This document describes the differences between 5.1.0 and 5.0.1 releases. This document describes the differences between X and Y releases.
@ -19,69 +19,21 @@ This document describes the differences between 5.1.0 and 5.0.1 releases.
1. New Features 1. New Features
=============== ===============
Client Setting Mythen3 gain from command line
------
1. Added settings and threshold features for Mythen3. 4. Firmware Requirements
2. Internal modification of acquire for Mythen3.
3. Added getMaster for Mythen3
4. Mythen3, API function to set pattern from memory
Mythen3 server
-----------------
1. Setting timing to auto, sets timing to trigger for slaves
2. Resolved Issues
==================
Receiver
--------
1. Current code only calls Implementation::setDetectorType from constructor,
but potential memory leak if called out of constructor context. Fixed.
Client
------
1. Fixed missing scanParameters class in Python
2. cmk.sh refactored to have better option handling
3. Fixed hardcoded path accidentally ending up in the exported CMake package
Server
--------
1. Bottom port not mirrored correctly for Eiger quad
3. Firmware Requirements
======================== ========================
Mythen3: 0x210201
Jungfrau: 0x210218 (1.0 pcb)
0x200721 (2.0 pcb, not changed)
Other detectors no updates from 5.0.0
5. Known Issues
4. Known Issues
=============== ===============
No updates from 5.0.0 No updates from 5.0.0
5. Download, Documentation & Support 6. Download, Documentation & Support
==================================== ====================================
Download Download

View File

@ -49,13 +49,13 @@ args = parser.parse_args()
servers = [ servers = [
"eigerDetectorServer", # "eigerDetectorServer",
"jungfrauDetectorServer", # "jungfrauDetectorServer",
"mythen3DetectorServer", "mythen3DetectorServer",
"gotthard2DetectorServer", # "gotthard2DetectorServer",
"gotthardDetectorServer", # "gotthardDetectorServer",
"ctbDetectorServer", # "ctbDetectorServer",
"moenchDetectorServer", # "moenchDetectorServer",
] ]

View File

@ -11,6 +11,8 @@ import subprocess
from parse import remove_comments from parse import remove_comments
allow_bitwise_op = ["M3_GainCaps"]
def single_line_enum(line): def single_line_enum(line):
sub = line[line.find('{')+1:line.find('}')] sub = line[line.find('{')+1:line.find('}')]
return sub.strip().split(',') return sub.strip().split(',')
@ -49,7 +51,11 @@ def extract_enums(lines):
def generate_enum_string(enums): def generate_enum_string(enums):
data = [] data = []
for key, value in enums.items(): for key, value in enums.items():
data.append(f'py::enum_<slsDetectorDefs::{key}>(Defs, "{key}")\n') if key in allow_bitwise_op:
tag=", py::arithmetic()"
else:
tag=""
data.append(f'py::enum_<slsDetectorDefs::{key}>(Defs, "{key}"{tag})\n')
for v in value: for v in value:
data.append(f'\t.value("{v}", slsDetectorDefs::{key}::{v})\n') data.append(f'\t.value("{v}", slsDetectorDefs::{key}::{v})\n')
data.append('.export_values();\n\n') data.append('.export_values();\n\n')

View File

@ -15,3 +15,4 @@ readoutMode = _slsdet.slsDetectorDefs.readoutMode
masterFlags = _slsdet.slsDetectorDefs.masterFlags masterFlags = _slsdet.slsDetectorDefs.masterFlags
burstMode = _slsdet.slsDetectorDefs.burstMode burstMode = _slsdet.slsDetectorDefs.burstMode
timingSourceType = _slsdet.slsDetectorDefs.timingSourceType timingSourceType = _slsdet.slsDetectorDefs.timingSourceType
M3_GainCaps = _slsdet.slsDetectorDefs.M3_GainCaps

View File

@ -1136,6 +1136,16 @@ void init_det(py::module &m) {
(Result<bool>(Detector::*)(sls::Positions) const) & (Result<bool>(Detector::*)(sls::Positions) const) &
Detector::getMaster, Detector::getMaster,
py::arg() = Positions{}) py::arg() = Positions{})
.def("getChipStatusRegister",
(Result<int>(Detector::*)(sls::Positions) const) &
Detector::getChipStatusRegister,
py::arg() = Positions{})
.def("setGainCaps",
(void (Detector::*)(int, sls::Positions)) & Detector::setGainCaps,
py::arg(), py::arg() = Positions{})
.def("getGainCaps",
(Result<int>(Detector::*)(sls::Positions)) & Detector::getGainCaps,
py::arg() = Positions{})
.def("getNumberOfAnalogSamples", .def("getNumberOfAnalogSamples",
(Result<int>(Detector::*)(sls::Positions) const) & (Result<int>(Detector::*)(sls::Positions) const) &
Detector::getNumberOfAnalogSamples, Detector::getNumberOfAnalogSamples,

View File

@ -277,4 +277,14 @@ void init_enums(py::module &m) {
.value("TIMING_EXTERNAL", .value("TIMING_EXTERNAL",
slsDetectorDefs::timingSourceType::TIMING_EXTERNAL) slsDetectorDefs::timingSourceType::TIMING_EXTERNAL)
.export_values(); .export_values();
py::enum_<slsDetectorDefs::M3_GainCaps>(Defs, "M3_GainCaps",
py::arithmetic())
.value("M3_C10pre", slsDetectorDefs::M3_GainCaps::M3_C10pre)
.value("M3_C15sh", slsDetectorDefs::M3_GainCaps::M3_C15sh)
.value("M3_C30sh", slsDetectorDefs::M3_GainCaps::M3_C30sh)
.value("M3_C50sh", slsDetectorDefs::M3_GainCaps::M3_C50sh)
.value("M3_C225ACsh", slsDetectorDefs::M3_GainCaps::M3_C225ACsh)
.value("M3_C15pre", slsDetectorDefs::M3_GainCaps::M3_C15pre)
.export_values();
} }

View File

@ -1,5 +1,6 @@
add_executable(mythen3DetectorServer_virtual add_executable(mythen3DetectorServer_virtual
slsDetectorFunctionList.c slsDetectorFunctionList.c
mythen3.c
../slsDetectorServer/src/slsDetectorServer.c ../slsDetectorServer/src/slsDetectorServer.c
../slsDetectorServer/src/slsDetectorServer_funcs.c ../slsDetectorServer/src/slsDetectorServer_funcs.c
../slsDetectorServer/src/communication_funcs.c ../slsDetectorServer/src/communication_funcs.c
@ -11,6 +12,7 @@ add_executable(mythen3DetectorServer_virtual
../slsDetectorServer/src/ALTERA_PLL_CYCLONE10.c ../slsDetectorServer/src/ALTERA_PLL_CYCLONE10.c
../slsDetectorServer/src/programFpgaNios.c ../slsDetectorServer/src/programFpgaNios.c
../slsDetectorServer/src/readDefaultPattern.c ../slsDetectorServer/src/readDefaultPattern.c
../slsDetectorServer/src/loadPattern.c
../slsDetectorServer/src/sharedMemory.c ../slsDetectorServer/src/sharedMemory.c
) )

View File

@ -13,7 +13,7 @@ DESTDIR ?= bin
INSTMODE = 0777 INSTMODE = 0777
SRCS = slsDetectorFunctionList.c 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)readDefaultPattern.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)DAC6571.c $(main_src)common.c $(main_src)LTC2620_Driver.c $(main_src)ALTERA_PLL_CYCLONE10.c $(main_src)/programFpgaNios.c $(main_src)readDefaultPattern.c $(main_src)/sharedMemory.c $(main_src)/loadPattern.c mythen3.c
OBJS = $(SRCS:.c=.o) OBJS = $(SRCS:.c=.o)

View File

@ -0,0 +1,374 @@
#include "clogger.h"
#include "common.h"
#include "mythen3.h"
#include "sls/ansi.h"
#include "sls/sls_detector_defs.h"
#include "slsDetectorServer_defs.h"
#include <string.h>
/*
// Common C/C++ structure to handle pattern data
typedef struct __attribute__((packed)) {
uint64_t word[MAX_PATTERN_LENGTH];
uint64_t ioctrl;
uint32_t limits[2];
// loop0 start, loop0 stop .. loop2 start, loop2 stop
uint32_t loop[6];
uint32_t nloop[3];
uint32_t wait[3];
uint64_t waittime[3];
} patternParameters;
*/
int chipStatusRegister=0;
int setBit(int ibit, int patword) { return patword |= (1 << ibit); }
int clearBit(int ibit, int patword) { return patword &= ~(1 << ibit); }
extern enum TLogLevel trimmingPrint ;
int getChipStatusRegister(){
return chipStatusRegister;
}
int gainCapsToCsr(int caps){
//Translates bit representation
int csr = 0;
if (!(caps & M3_C10pre))
csr |= 1 << _CSR_C10pre;
if (caps & M3_C15sh)
csr |= 1 << CSR_C15sh;
if (caps & M3_C30sh)
csr |= 1 << CSR_C30sh;
if (caps & M3_C50sh)
csr |= 1 << CSR_C50sh;
if (caps & M3_C225ACsh)
csr |= 1 << CSR_C225ACsh;
if (!(caps & M3_C15pre))
csr |= 1 << _CSR_C15pre;
return csr;
}
int csrToGainCaps(int csr){
//Translates bit representation
int caps = 0;
if (!(csr & (1 << _CSR_C10pre)))
caps |= M3_C10pre;
if (csr & (1 << CSR_C15sh))
caps |= M3_C15sh;
if (csr & (1 << CSR_C30sh))
caps |= M3_C30sh;
if (csr & (1 << CSR_C50sh))
caps |= M3_C50sh;
if (csr & (1 << CSR_C225ACsh))
caps |= M3_C225ACsh;
if (!(csr & (1 << _CSR_C15pre)))
caps |= M3_C15pre;
return caps;
}
patternParameters *setChipStatusRegisterPattern(int csr) {
int iaddr=0;
int nbits=18;
int error=0;
//int start=0, stop=MAX_PATTERN_LENGTH, loop=0;
int patword=0;
patternParameters *pat = malloc(sizeof(patternParameters));
memset(pat, 0, sizeof(patternParameters));
patword=setBit(SIGNAL_STATLOAD,patword);
for (int i=0; i<2; i++)
pat->word[iaddr++]=patword;
patword=setBit(SIGNAL_resStorage,patword);
patword=setBit(SIGNAL_resCounter,patword);
for (int i=0; i<8; i++)
pat->word[iaddr++]=patword;
patword=clearBit(SIGNAL_resStorage,patword);
patword=clearBit(SIGNAL_resCounter,patword);
for (int i=0; i<8; i++)
pat->word[iaddr++]=patword;
//#This version of the serializer pushes in the MSB first (compatible with the CSR bit numbering)
for (int ib=nbits-1; ib>=0; ib--) {
if (csr&(1<<ib))
patword=setBit(SIGNAL_serialIN,patword);
else
patword=clearBit(SIGNAL_serialIN,patword);
for (int i=0; i<4; i++)
pat->word[iaddr++]=patword;
patword=setBit(SIGNAL_CHSclk,patword);
pat->word[iaddr++]=patword;
patword=clearBit(SIGNAL_CHSclk,patword);
pat->word[iaddr++]=patword;
}
patword=clearBit(SIGNAL_serialIN,patword);
for (int i=0; i<2; i++)
pat->word[iaddr++]=patword;
patword=setBit(SIGNAL_STO,patword);
for (int i=0; i<5; i++)
pat->word[iaddr++]=patword;
patword=clearBit(SIGNAL_STO,patword);
for (int i=0; i<5; i++)
pat->word[iaddr++]=patword;
patword=clearBit(SIGNAL_STATLOAD,patword);
for (int i=0; i<5; i++)
pat->word[iaddr++]=patword;
if (iaddr >= MAX_PATTERN_LENGTH) {
LOG(logERROR, ("Addr 0x%x is past max_address_length 0x%x!\n",
iaddr, MAX_PATTERN_LENGTH));
error = 1;
}
// set pattern wait address
for (int i = 0; i <= 2; i++)
pat->wait[i]=MAX_PATTERN_LENGTH - 1;
// pattern loop
for (int i = 0; i <= 2; i++) {
//int stop = MAX_PATTERN_LENGTH - 1, nloop = 0;
pat->loop[i * 2 + 0]=MAX_PATTERN_LENGTH - 1;
pat->loop[i * 2 + 1]=MAX_PATTERN_LENGTH - 1;
pat->nloop[i]=0;
}
// pattern limits
{
pat->limits[0]=0;
pat->limits[1]=iaddr;
}
if (error != 0) {
free(pat);
return NULL;
}
chipStatusRegister=csr;
return pat;
}
patternParameters *setInterpolation(int mask) {
int csr;
if (mask)
csr=chipStatusRegister|(1<< CSR_interp);
else
csr=chipStatusRegister & ~(1<< CSR_interp);
return setChipStatusRegisterPattern(csr);
}
patternParameters *setPumpProbe(int mask) {
int csr;
if (mask)
csr=chipStatusRegister|(1<< CSR_pumprobe);
else
csr=chipStatusRegister & ~(1<< CSR_pumprobe);
return setChipStatusRegisterPattern(csr);
}
patternParameters *setDigitalPulsing(int mask) {
int csr;
if (mask)
csr=chipStatusRegister|(1<< CSR_dpulse);
else
csr=chipStatusRegister & ~(1<< CSR_dpulse);
return setChipStatusRegisterPattern(csr);
}
patternParameters *setAnalogPulsing(int mask){
int csr;
if (mask)
csr=chipStatusRegister|(1<< CSR_apulse);
else
csr=chipStatusRegister & ~(1<< CSR_apulse);
return setChipStatusRegisterPattern(csr);
}
patternParameters *setNegativePolarity(int mask){
int csr;
if (mask)
csr=chipStatusRegister|(1<< CSR_invpol);
else
csr=chipStatusRegister & ~(1<< CSR_invpol);
return setChipStatusRegisterPattern(csr);
}
patternParameters *setChannelRegisterChip(int ichip, int *mask, int *trimbits) {
patternParameters *pat = malloc(sizeof(patternParameters));
memset(pat, 0, sizeof(patternParameters));
// validate
for (int ichan = ichip * NCHAN_1_COUNTER * NCOUNTERS; ichan < ichip * NCHAN_1_COUNTER * NCOUNTERS+NCHAN_1_COUNTER*NCOUNTERS; ichan++) {
if (trimbits[ichan]<0) {
LOG(logERROR, ("Trimbit value (%d) for channel %d is invalid - setting it to 0\n",
trimbits[ichan], ichan));
trimbits[ichan]=0;
}
if (trimbits[ichan] > 63) {
LOG(logERROR, ("Trimbit value (%d) for channel %d is invalid - settings it to 63\n",
trimbits[ichan], ichan));
trimbits[ichan]=63;
}
}
LOG(logINFO, ("Trimbits validated\n"));
trimmingPrint = logDEBUG5;
// trimming
int error = 0;
uint64_t patword = 0;
int iaddr = 0;
LOG(logDEBUG1, (" Chip %d\n", ichip));
iaddr = 0;
patword = 0;
pat->word[iaddr++]=patword;
// chip select
patword = setBit(SIGNAL_TBLoad_1 + ichip, patword);
pat->word[iaddr++]=patword;
// reset trimbits
patword = setBit(SIGNAL_resStorage, patword);
patword = setBit(SIGNAL_resCounter, patword);
pat->word[iaddr++]=patword;
pat->word[iaddr++]=patword;
patword = clearBit(SIGNAL_resStorage, patword);
patword = clearBit(SIGNAL_resCounter, patword);
pat->word[iaddr++]=patword;
pat->word[iaddr++]=patword;
// select first channel
patword = setBit(SIGNAL_CHSserialIN, patword);
pat->word[iaddr++]=patword;
// 1 clk pulse
patword = setBit(SIGNAL_CHSclk, patword);
pat->word[iaddr++]=patword;
patword = clearBit(SIGNAL_CHSclk, patword);
// clear 1st channel
pat->word[iaddr++]=patword;
patword = clearBit(SIGNAL_CHSserialIN, patword);
// 2 clk pulses
for (int i = 0; i < 2; i++) {
patword = setBit(SIGNAL_CHSclk, patword);
pat->word[iaddr++]=patword;
patword = clearBit(SIGNAL_CHSclk, patword);
pat->word[iaddr++]=patword;
}
// for each channel (all chips)
for (int ich = 0; ich < NCHAN_1_COUNTER; ich++) {
LOG(logDEBUG1, (" Chip %d, Channel %d\n", ichip, ich));
int val = trimbits[ichip * NCHAN_1_COUNTER * NCOUNTERS +
NCOUNTERS * ich] +
trimbits[ichip * NCHAN_1_COUNTER * NCOUNTERS +
NCOUNTERS * ich + 1] *
64 +
trimbits[ichip * NCHAN_1_COUNTER * NCOUNTERS +
NCOUNTERS * ich + 2] *
64 * 64;
// push 6 0 bits
for (int i = 0; i < 3; i++) {
patword = clearBit(SIGNAL_serialIN, patword);
patword = clearBit(SIGNAL_clk, patword);
pat->word[iaddr++]=patword;
patword = setBit(SIGNAL_clk, patword);
pat->word[iaddr++]=patword;
}
for (int i = 0; i < 3; i++) {
if (mask[i])
patword = setBit(SIGNAL_serialIN, patword);
else
patword = clearBit(SIGNAL_serialIN, patword);
patword = clearBit(SIGNAL_clk, patword);
pat->word[iaddr++]=patword;
patword = setBit(SIGNAL_clk, patword);
pat->word[iaddr++]=patword;
}
// deserialize
for (int i = 0; i < 18; i++) {
if (val & (1 << i)) {
patword = setBit(SIGNAL_serialIN, patword);
} else {
patword = clearBit(SIGNAL_serialIN, patword);
}
patword = clearBit(SIGNAL_clk, patword);
pat->word[iaddr++]=patword;
patword = setBit(SIGNAL_clk, patword);
pat->word[iaddr++]=patword;
}
pat->word[iaddr++]=patword;
pat->word[iaddr++]=patword;
// move to next channel
for (int i = 0; i < 3; i++) {
patword = setBit(SIGNAL_CHSclk, patword);
pat->word[iaddr++]=patword;
patword = clearBit(SIGNAL_CHSclk, patword);
pat->word[iaddr++]=patword;
}
}
// chip unselect
patword = clearBit(SIGNAL_TBLoad_1 + ichip, patword);
pat->word[iaddr++]=patword;
// last iaddr check
if (iaddr >= MAX_PATTERN_LENGTH) {
LOG(logERROR, ("Addr 0x%x is past max_address_length 0x%x!\n",
iaddr, MAX_PATTERN_LENGTH));
error = 1;
}
if (iaddr >= MAX_PATTERN_LENGTH) {
LOG(logERROR, ("Addr 0x%x is past max_address_length 0x%x!\n",
iaddr, MAX_PATTERN_LENGTH));
error = 1;
}
// set pattern wait address
for (int i = 0; i <= 2; i++)
pat->wait[i]=MAX_PATTERN_LENGTH - 1;
// pattern loop
for (int i = 0; i <= 2; i++) {
//int stop = MAX_PATTERN_LENGTH - 1, nloop = 0;
pat->loop[i * 2 + 0]=MAX_PATTERN_LENGTH - 1;
pat->loop[i * 2 + 1]=MAX_PATTERN_LENGTH - 1;
pat->nloop[i]=0;
}
// pattern limits
{
pat->limits[0]=0;
pat->limits[1]=iaddr;
}
trimmingPrint = logINFO;
if (error == 0) {
LOG(logINFO, ("All trimbits have been loaded\n"));
} else {
free(pat);
return NULL;
}
return pat;
}

View File

@ -0,0 +1,68 @@
#ifndef MYTHEN3_H
#define MYTHEN3_H
#include "Pattern.h"
/** Signal Definitions */
#define SIGNAL_TBLoad_1 (0)
#define SIGNAL_TBLoad_2 (1)
#define SIGNAL_TBLoad_3 (2)
#define SIGNAL_TBLoad_4 (3)
#define SIGNAL_TBLoad_5 (4)
#define SIGNAL_TBLoad_6 (5)
#define SIGNAL_TBLoad_7 (6)
#define SIGNAL_TBLoad_8 (7)
#define SIGNAL_TBLoad_9 (8)
#define SIGNAL_TBLoad_10 (9)
#define SIGNAL_AnaMode (10)
#define SIGNAL_CHSserialIN (11)
#define SIGNAL_READOUT (12)
#define SIGNAL_pulse (13)
#define SIGNAL_EN1 (14)
#define SIGNAL_EN2 (15)
#define SIGNAL_EN3 (16)
#define SIGNAL_clk (17)
#define SIGNAL_SRmode (18)
#define SIGNAL_serialIN (19)
#define SIGNAL_STO (20)
#define SIGNAL_STATLOAD (21)
#define SIGNAL_resStorage (22)
#define SIGNAL_resCounter (23)
#define SIGNAL_CHSclk (24)
#define SIGNAL_exposing (25)
//CHIP STARTUS REGISTER BITS
#define CSR_spypads 0
#define CSR_invpol 4
#define CSR_dpulse 5
#define CSR_interp 6
#define _CSR_C10pre 7 //#default, negative polarity
#define CSR_pumprobe 8
#define CSR_apulse 9
#define CSR_C15sh 10
#define CSR_C30sh 11 //#default
#define CSR_C50sh 12
#define CSR_C225ACsh 13 // Connects 225fF SHAPER AC cap (1: 225 to shaper, 225 to GND. 0: 450 to shaper)
#define _CSR_C15pre 14 // negative polarity
#define CSR_default (1<<_CSR_C10pre )|(1<< CSR_C30sh)
#define GAIN_MASK ((1 << _CSR_C10pre) | ( 1 << CSR_C15sh) | (1 << CSR_C30sh) | (1 << CSR_C50sh) | (1 << CSR_C225ACsh) | ( 1 << _CSR_C15pre))
int setBit(int ibit, int patword);
int clearBit(int ibit, int patword);
int getChipStatusRegister();
int gainCapsToCsr(int caps);
int csrToGainCaps(int csr);
patternParameters *setChipStatusRegisterPattern(int csr);
patternParameters *setChannelRegisterChip(int ichip, int *mask, int *trimbits);
patternParameters *setInterpolation(int mask);
patternParameters *setPumpProbe(int mask);
patternParameters *setDigitalPulsing(int mask);
patternParameters *setAnalogPulsing(int mask);
patternParameters *setNegativePolarity(int mask);
#endif

View File

@ -5,6 +5,8 @@
#include "RegisterDefs.h" #include "RegisterDefs.h"
#include "clogger.h" #include "clogger.h"
#include "common.h" #include "common.h"
#include "mythen3.h"
#include "loadPattern.h"
#include "sharedMemory.h" #include "sharedMemory.h"
#include "sls/versionAPI.h" #include "sls/versionAPI.h"
#ifdef VIRTUAL #ifdef VIRTUAL
@ -19,8 +21,6 @@
#include <time.h> #include <time.h>
#endif #endif
/// NOT the right place to put it!
int setChipStatusRegister(int csr);
// Global variable from slsDetectorServer_funcs // Global variable from slsDetectorServer_funcs
extern int debugflag; extern int debugflag;
@ -47,11 +47,12 @@ enum detectorSettings thisSettings;
sls_detector_module *detectorModules = NULL; sls_detector_module *detectorModules = NULL;
int *detectorChans = NULL; int *detectorChans = NULL;
int *detectorDacs = NULL; int *detectorDacs = NULL;
int *channelMask=NULL;
enum TLogLevel trimmingPrint = logINFO;
int32_t clkPhase[NUM_CLOCKS] = {}; int32_t clkPhase[NUM_CLOCKS] = {};
uint32_t clkDivider[NUM_CLOCKS] = {}; uint32_t clkDivider[NUM_CLOCKS] = {};
enum TLogLevel trimmingPrint = logINFO;
int highvoltage = 0; int highvoltage = 0;
int detPos[2] = {}; int detPos[2] = {};
int64_t exptimeReg[NCOUNTERS] = {0, 0, 0}; int64_t exptimeReg[NCOUNTERS] = {0, 0, 0};
@ -374,7 +375,11 @@ void allocateDetectorStructureMemory() {
// Allocation of memory // Allocation of memory
detectorModules = malloc(sizeof(sls_detector_module)); detectorModules = malloc(sizeof(sls_detector_module));
detectorChans = malloc(NCHIP * NCHAN * sizeof(int)); detectorChans = malloc(NCHIP * NCHAN * sizeof(int));
channelMask = malloc(NCHIP * NCHAN * sizeof(char));
memset(channelMask, 0, NCHIP * NCHAN * sizeof(char));
detectorDacs = malloc(NDAC * sizeof(int)); detectorDacs = malloc(NDAC * sizeof(int));
LOG(logDEBUG1, LOG(logDEBUG1,
("modules from 0x%x to 0x%x\n", detectorModules, detectorModules)); ("modules from 0x%x to 0x%x\n", detectorModules, detectorModules));
LOG(logDEBUG1, ("chans from 0x%x to 0x%x\n", detectorChans, detectorChans)); LOG(logDEBUG1, ("chans from 0x%x to 0x%x\n", detectorChans, detectorChans));
@ -512,11 +517,11 @@ void setupDetector() {
} }
powerChip(1); powerChip(1);
if (initError != FAIL) {
initError = setChipStatusRegister(CSR_default); if (!initError) {
//loadDefaultPattern(DEFAULT_PATTERN_FILE, initErrorMessage); setChipStatusRegister(CSR_default);
//startStateMachine(); //this was missing in previous code! runs the default pattern
} }
setAllTrimbits(DEFAULT_TRIMBIT_VALUE); setAllTrimbits(DEFAULT_TRIMBIT_VALUE);
} }
@ -1052,72 +1057,44 @@ int64_t getMeasurementTime() {
/* parameters - module, speed, readout */ /* parameters - module, speed, readout */
int setModule(sls_detector_module myMod, char *mess) { int setDACS(int* dacs){
LOG(logINFO, ("Setting module\n"));
// settings
if (myMod.reg >= 0) {
setSettings((enum detectorSettings)myMod.reg);
if (getSettings() != (enum detectorSettings)myMod.reg) {
sprintf(
mess,
"Could not set module. Could not set settings to %d, read %d\n",
myMod.reg, (int)getSettings());
LOG(logERROR, (mess));
return FAIL;
}
detectorModules->reg = myMod.reg;
}
// custom trimbit file
else {
// changed for setsettings (direct),
// custom trimbit file (setmodule with myMod.reg as -1),
// change of dac (direct)
for (int i = 0; i < NCOUNTERS; ++i) {
setThresholdEnergy(i, -1);
}
}
// dacs
for (int i = 0; i < NDAC; ++i) { for (int i = 0; i < NDAC; ++i) {
// ignore dacs with -1 if (dacs[i] != -1) {
if (myMod.dacs[i] != -1) { setDAC((enum DACINDEX)i, dacs[i], 0);
setDAC((enum DACINDEX)i, myMod.dacs[i], 0); if (dacs[i] != detectorDacs[i]) {
if (myMod.dacs[i] != detectorDacs[i]) {
// dont complain if that counter was disabled // dont complain if that counter was disabled
if ((i == M_VTH1 || i == M_VTH2 || i == M_VTH3) && if ((i == M_VTH1 || i == M_VTH2 || i == M_VTH3) &&
(detectorDacs[i] == DEFAULT_COUNTER_DISABLED_VTH_VAL)) { (detectorDacs[i] == DEFAULT_COUNTER_DISABLED_VTH_VAL)) {
continue; continue;
} }
sprintf(mess,
"Could not set module. Could not set dac %d, wrote %d, "
"read %d\n",
i, myMod.dacs[i], detectorDacs[i]);
LOG(logERROR, (mess));
return FAIL; return FAIL;
} }
} }
} }
return OK;
}
// if settings given and cannot be validated (after setting dacs), return
// error int setModule(sls_detector_module myMod, char *mess) {
if (myMod.reg >= 0) { LOG(logINFO, ("Setting module\n"));
if (getSettings() != (enum detectorSettings)myMod.reg) {
sprintf( if (setChipStatusRegister(myMod.reg)){
mess, sprintf(mess, "Could not CSR from module\n");
"Could not set module. The dacs in file do not correspond to "
"settings %d\n",
myMod.reg);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
return FAIL; return FAIL;
} }
if (setDACS(myMod.dacs)){
sprintf(mess, "Could not set dacs\n");
LOG(logERROR, (mess));
return FAIL;
} }
// threshold
for (int i = 0; i < NCOUNTERS; ++i) { for (int i = 0; i < NCOUNTERS; ++i) {
if (myMod.eV[i] >= 0) { if (myMod.eV[i] >= 0) {
setThresholdEnergy(i, myMod.eV[i]); setThresholdEnergy(i, myMod.eV[i]);
}else{
setThresholdEnergy(i, -1);
} }
} }
@ -1136,155 +1113,31 @@ int setModule(sls_detector_module myMod, char *mess) {
return OK; return OK;
} }
int setBit(int ibit, int patword) { return patword |= (1 << ibit); }
int clearBit(int ibit, int patword) { return patword &= ~(1 << ibit); }
int setTrimbits(int *trimbits) { int setTrimbits(int *trimbits) {
LOG(logINFOBLUE, ("Setting trimbits\n"));
// validate
for (int ichan = 0; ichan < ((detectorModules)->nchan); ++ichan) {
if (trimbits[ichan] < 0 || trimbits[ichan] > 63) {
LOG(logERROR, ("Trimbit value (%d) for channel %d is invalid\n",
trimbits[ichan], ichan));
return FAIL;
}
}
LOG(logINFO, ("Trimbits validated\n"));
trimmingPrint = logDEBUG5;
// remember previous run clock // remember previous run clock
uint32_t prevRunClk = clkDivider[SYSTEM_C0]; uint32_t prevRunClk = clkDivider[SYSTEM_C0];
patternParameters *pat = NULL;
int error = 0;
// set to trimming clock // set to trimming clock
if (setClockDivider(SYSTEM_C0, DEFAULT_TRIMMING_RUN_CLKDIV) == FAIL) { if (setClockDivider(SYSTEM_C0, DEFAULT_TRIMMING_RUN_CLKDIV) == FAIL) {
LOG(logERROR, LOG(logERROR,
("Could not start trimming. Could not set to trimming clock\n")); ("Could not start trimming. Could not set to trimming clock\n"));
return FAIL; return FAIL;
} }
/////////////////////////////////////////////////////////////////
// trimming
int error = 0;
uint64_t patword = 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));
iaddr = 0;
patword = 0;
writePatternWord(iaddr++, patword);
// chip select pat = setChannelRegisterChip(ichip, channelMask,
patword = setBit(SIGNAL_TBLoad_1 + ichip, patword); trimbits); // change here!!!
writePatternWord(iaddr++, patword); if (pat) {
error |= loadPattern(pat);
// reset trimbits if (error == 0)
patword = setBit(SIGNAL_resStorage, patword);
patword = setBit(SIGNAL_resCounter, patword);
writePatternWord(iaddr++, patword);
writePatternWord(iaddr++, patword);
patword = clearBit(SIGNAL_resStorage, patword);
patword = clearBit(SIGNAL_resCounter, patword);
writePatternWord(iaddr++, patword);
writePatternWord(iaddr++, patword);
// select first channel
patword = setBit(SIGNAL_CHSserialIN, patword);
writePatternWord(iaddr++, patword);
// 1 clk pulse
patword = setBit(SIGNAL_CHSclk, patword);
writePatternWord(iaddr++, patword);
patword = clearBit(SIGNAL_CHSclk, patword);
// clear 1st channel
writePatternWord(iaddr++, patword);
patword = clearBit(SIGNAL_CHSserialIN, patword);
// 2 clk pulses
for (int i = 0; i < 2; i++) {
patword = setBit(SIGNAL_CHSclk, patword);
writePatternWord(iaddr++, patword);
patword = clearBit(SIGNAL_CHSclk, patword);
writePatternWord(iaddr++, patword);
}
// for each channel (all chips)
for (int ich = 0; ich < NCHAN_1_COUNTER; ich++) {
LOG(logDEBUG1, (" Chip %d, Channel %d\n", ichip, ich));
int val = trimbits[ichip * NCHAN_1_COUNTER * NCOUNTERS +
NCOUNTERS * ich] +
trimbits[ichip * NCHAN_1_COUNTER * NCOUNTERS +
NCOUNTERS * ich + 1] *
64 +
trimbits[ichip * NCHAN_1_COUNTER * NCOUNTERS +
NCOUNTERS * ich + 2] *
64 * 64;
// push 6 0 bits
for (int i = 0; i < 6; i++) {
patword = clearBit(SIGNAL_serialIN, patword);
patword = clearBit(SIGNAL_clk, patword);
writePatternWord(iaddr++, patword);
patword = setBit(SIGNAL_clk, patword);
writePatternWord(iaddr++, patword);
}
// deserialize
for (int i = 0; i < 18; i++) {
if (val & (1 << i)) {
patword = setBit(SIGNAL_serialIN, patword);
} else {
patword = clearBit(SIGNAL_serialIN, patword);
}
patword = clearBit(SIGNAL_clk, patword);
writePatternWord(iaddr++, patword);
patword = setBit(SIGNAL_clk, patword);
writePatternWord(iaddr++, patword);
}
writePatternWord(iaddr++, patword);
writePatternWord(iaddr++, patword);
// move to next channel
for (int i = 0; i < 3; i++) {
patword = setBit(SIGNAL_CHSclk, patword);
writePatternWord(iaddr++, patword);
patword = clearBit(SIGNAL_CHSclk, patword);
writePatternWord(iaddr++, patword);
}
}
// chip unselect
patword = clearBit(SIGNAL_TBLoad_1 + ichip, patword);
writePatternWord(iaddr++, patword);
// last iaddr check
if (iaddr >= MAX_PATTERN_LENGTH) {
LOG(logERROR, ("Addr 0x%x is past max_address_length 0x%x!\n",
iaddr, MAX_PATTERN_LENGTH));
error = 1;
break;
}
// set pattern wait address
for (int i = 0; i <= 2; i++)
setPatternWaitAddress(i, MAX_PATTERN_LENGTH - 1);
// pattern loop
for (int i = 0; i <= 2; i++) {
int stop = MAX_PATTERN_LENGTH - 1, nloop = 0;
setPatternLoop(i, &stop, &stop, &nloop);
}
// pattern limits
{
int start = 0, nloop = 0;
setPatternLoop(-1, &start, &iaddr, &nloop);
}
// send pattern to the chips
startPattern(); startPattern();
free(pat);
} else
error = 1;
} }
/////////////////////////////////////////////////////////////////
if (error == 0) { 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) {
@ -1292,7 +1145,6 @@ int setTrimbits(int *trimbits) {
} }
LOG(logINFO, ("All trimbits have been loaded\n")); LOG(logINFO, ("All trimbits have been loaded\n"));
} }
trimmingPrint = logINFO; trimmingPrint = logINFO;
// set back to previous clock // set back to previous clock
if (setClockDivider(SYSTEM_C0, prevRunClk) == FAIL) { if (setClockDivider(SYSTEM_C0, prevRunClk) == FAIL) {
@ -1303,7 +1155,6 @@ int setTrimbits(int *trimbits) {
if (error != 0) { if (error != 0) {
return FAIL; return FAIL;
} }
return OK; return OK;
} }
@ -2780,76 +2631,51 @@ int getNumberOfDACs() { return NDAC; }
int getNumberOfChannelsPerChip() { return NCHAN; } int getNumberOfChannelsPerChip() { return NCHAN; }
int setChipStatusRegister(int csr) { int setChipStatusRegister(int csr) {
int iaddr=0; uint32_t prevRunClk = clkDivider[SYSTEM_C0];
int nbits=18; patternParameters *pat = NULL;
int error=0;
//int start=0, stop=MAX_PATTERN_LENGTH, loop=0;
int patword=0;
patword=setBit(SIGNAL_STATLOAD,patword);
for (int i=0; i<2; i++)
writePatternWord(iaddr++, patword);
patword=setBit(SIGNAL_resStorage,patword);
patword=setBit(SIGNAL_resCounter,patword);
for (int i=0; i<8; i++)
writePatternWord(iaddr++, patword);
patword=clearBit(SIGNAL_resStorage,patword);
patword=clearBit(SIGNAL_resCounter,patword);
for (int i=0; i<8; i++)
writePatternWord(iaddr++, patword);
//#This version of the serializer pushes in the MSB first (compatible with the CSR bit numbering)
for (int ib=nbits-1; ib>=0; ib--) {
if (csr&(1<<ib))
patword=setBit(SIGNAL_serialIN,patword);
else
patword=clearBit(SIGNAL_serialIN,patword);
for (int i=0; i<4; i++)
writePatternWord(iaddr++, patword);
patword=setBit(SIGNAL_CHSclk,patword);
writePatternWord(iaddr++, patword);
patword=clearBit(SIGNAL_CHSclk,patword);
writePatternWord(iaddr++, patword);
}
patword=clearBit(SIGNAL_serialIN,patword); int error = 0;
for (int i=0; i<2; i++) if (setClockDivider(SYSTEM_C0, DEFAULT_TRIMMING_RUN_CLKDIV) == FAIL) {
writePatternWord(iaddr++, patword); LOG(logERROR,
patword=setBit(SIGNAL_STO,patword); ("Could not set to trimming clock in order to change CSR\n"));
for (int i=0; i<5; i++)
writePatternWord(iaddr++, patword);
patword=clearBit(SIGNAL_STO,patword);
for (int i=0; i<5; i++)
writePatternWord(iaddr++, patword);
patword=clearBit(SIGNAL_STATLOAD,patword);
for (int i=0; i<5; i++)
writePatternWord(iaddr++, patword);
if (iaddr >= MAX_PATTERN_LENGTH) {
LOG(logERROR, ("Addr 0x%x is past max_address_length 0x%x!\n",
iaddr, MAX_PATTERN_LENGTH));
error = 1;
}
// set pattern wait address
for (int i = 0; i <= 2; i++)
setPatternWaitAddress(i, MAX_PATTERN_LENGTH - 1);
// pattern loop
for (int i = 0; i <= 2; i++) {
int stop = MAX_PATTERN_LENGTH - 1, nloop = 0;
setPatternLoop(i, &stop, &stop, &nloop);
}
// pattern limits
{
int start = 0, nloop = 0;
setPatternLoop(-1, &start, &iaddr, &nloop);
}
// send pattern to the chips
startPattern();
if (error != 0) {
return FAIL; return FAIL;
} }
pat = setChipStatusRegisterPattern(csr);
if (pat) {
error |= loadPattern(pat);
if (!error)
startPattern();
free(pat);
} else {
error = 1;
}
if (!error) {
LOG(logINFO, ("CSR is now: 0x%x\n", csr));
}
if (setClockDivider(SYSTEM_C0, prevRunClk) == FAIL) {
LOG(logERROR,
("Could not set to previous run clock after changing CSR\n"));
return FAIL;
}
return OK; return OK;
}
int setGainCaps(int caps){
// Update only gain caps, leave the rest of the CSR unchanged
int csr = getChipStatusRegister();
csr &= ~GAIN_MASK;
caps = gainCapsToCsr(caps);
// caps &= GAIN_MASK;
csr |= caps;
return setChipStatusRegister(csr);
}
int getGainCaps(){
int csr = getChipStatusRegister();
int caps = csrToGainCaps(csr);
return caps;
} }

View File

@ -158,47 +158,3 @@ typedef struct udp_header_struct {
#define UDP_IP_HEADER_LENGTH_BYTES (28) #define UDP_IP_HEADER_LENGTH_BYTES (28)
#define PACKETS_PER_FRAME_10G (2) #define PACKETS_PER_FRAME_10G (2)
#define PACKETS_PER_FRAME_1G (20) #define PACKETS_PER_FRAME_1G (20)
/** Signal Definitions */
#define SIGNAL_TBLoad_1 (0)
#define SIGNAL_TBLoad_2 (1)
#define SIGNAL_TBLoad_3 (2)
#define SIGNAL_TBLoad_4 (3)
#define SIGNAL_TBLoad_5 (4)
#define SIGNAL_TBLoad_6 (5)
#define SIGNAL_TBLoad_7 (6)
#define SIGNAL_TBLoad_8 (7)
#define SIGNAL_TBLoad_9 (8)
#define SIGNAL_TBLoad_10 (9)
#define SIGNAL_AnaMode (10)
#define SIGNAL_CHSserialIN (11)
#define SIGNAL_READOUT (12)
#define SIGNAL_pulse (13)
#define SIGNAL_EN1 (14)
#define SIGNAL_EN2 (15)
#define SIGNAL_EN3 (16)
#define SIGNAL_clk (17)
#define SIGNAL_SRmode (18)
#define SIGNAL_serialIN (19)
#define SIGNAL_STO (20)
#define SIGNAL_STATLOAD (21)
#define SIGNAL_resStorage (22)
#define SIGNAL_resCounter (23)
#define SIGNAL_CHSclk (24)
#define SIGNAL_exposing (25)
//CHIP STARTUS REGISTER BITS
#define CSR_spypads 0
#define CSR_invpol 4
#define CSR_dpulse 5
#define CSR_interp 6
#define CSR_C10pre 7 //#default
#define CSR_pumprobe 8
#define CSR_apulse 9
#define CSR_C15sh 10
#define CSR_C30sh 11 //#default
#define CSR_C50sh 12
#define CSR_C225ACsh 13 // Connects 225fF SHAPER AC cap (1: 225 to shaper, 225 to GND. 0: 450 to shaper)
#define CSR_C15pre 14
#define CSR_default (1<<CSR_C10pre )|(1<< CSR_C30sh)

View File

@ -0,0 +1,6 @@
#ifndef LOADPATTERN_H
#define LOADPATTERN_H
#include "Pattern.h"
int loadPattern(patternParameters *pat);
#endif

View File

@ -25,6 +25,10 @@
#include "blackfin.h" #include "blackfin.h"
#endif #endif
#if defined(MYTHEN3D)
#include "mythen3.h"
#endif
#include <stdio.h> // FILE #include <stdio.h> // FILE
#include <stdlib.h> #include <stdlib.h>
#include <sys/types.h> #include <sys/types.h>
@ -353,6 +357,10 @@ enum timingMode getTiming();
#ifdef MYTHEN3D #ifdef MYTHEN3D
void setInitialExtSignals(); void setInitialExtSignals();
int isMaster(); int isMaster();
int setGainCaps(int caps);
int getGainCaps();
int setChipStatusRegister(int csr);
int setDACS(int* dacs);
#endif #endif
#if defined(GOTTHARDD) || defined(MYTHEN3D) #if defined(GOTTHARDD) || defined(MYTHEN3D)
void setExtSignal(int signalIndex, enum externalSignalFlag mode); void setExtSignal(int signalIndex, enum externalSignalFlag mode);

View File

@ -247,3 +247,6 @@ int get_pattern(int);
int load_default_pattern(int); int load_default_pattern(int);
int get_all_threshold_energy(int); int get_all_threshold_energy(int);
int get_master(int); int get_master(int);
int get_csr();
int set_gain_caps(int);
int get_gain_caps(int);

View File

@ -0,0 +1,105 @@
#include "readDefaultPattern.h"
#include "loadPattern.h"
#include "clogger.h"
#include "common.h"
#include "sls/ansi.h"
#include "sls/sls_detector_defs.h"
#include "slsDetectorServer_defs.h"
#if defined(CHIPTESTBOARDD) || defined(MOENCHD) || defined(MYTHEN3D)
#include "Pattern.h"
#endif
#include <string.h>
#include <unistd.h>
extern char initErrorMessage[MAX_STR_LENGTH];
#ifndef MYTHEN3D
extern uint64_t writePatternIOControl(uint64_t word);
#endif
extern uint64_t writePatternWord(int addr, uint64_t word);
extern int setPatternWaitAddress(int level, int addr);
extern uint64_t setPatternWaitTime(int level, uint64_t t);
extern void setPatternLoop(int level, int *startAddr, int *stopAddr,
int *nLoop);
int loadPattern(patternParameters *pat) {
int ret=OK;
for (int i = 0; i < MAX_PATTERN_LENGTH; ++i) {
if ((i % 10 == 0) && pat->word[i] != 0) {
LOG(logINFO, ("Setting Pattern Word (addr:0x%x, word:0x%llx)\n",
i, (long long int)pat->word[i]));
}
writePatternWord(i, pat->word[i]);
}
#ifndef MYTHEN3D
if (ret == OK) {
uint64_t retval64 = writePatternIOControl(pat->ioctrl);
//validate64(pat->ioctrl, retval64, "set pattern IO Control", HEX);
}
#endif
if (ret == OK) {
int numLoops = -1;
int retval0 = pat->limits[0];
int retval1 = pat->limits[1];
setPatternLoop(-1, &retval0, &retval1, &numLoops);
//validate(pat->limits[0], retval0,
// "set pattern Limits start address", HEX);
//validate(pat->limits[1], retval1,
// "set pattern Limits start address", HEX);
}
uint64_t retval64;
if (ret == OK) {
for (int i = 0; i <= 2; ++i) {
char msg[128];
int retval0 = -1, retval1 = -1, numLoops = -1;
// patloop
retval0 = pat->loop[i * 2 + 0];
retval1 = pat->loop[i * 2 + 1];
numLoops = pat->nloop[i];
setPatternLoop(i, &retval0, &retval1, &numLoops);
memset(msg, 0, sizeof(msg));
sprintf(msg, "set pattern Loop %d start address", i);
//validate(pat->loop[i * 2 + 0], retval0, msg, HEX);
if (ret == FAIL) {
break;
}
memset(msg, 0, sizeof(msg));
sprintf(msg, "set pattern Loop %d stop address", i);
//validate(pat->loop[i * 2 + 1], retval1, msg, HEX);
if (ret == FAIL) {
break;
}
memset(msg, 0, sizeof(msg));
sprintf(msg, "set pattern Loop %d num loops", i);
//validate(pat->nloop[i], numLoops, msg, HEX);
if (ret == FAIL) {
break;
}
// patwait
memset(msg, 0, sizeof(msg));
sprintf(msg, "set pattern Loop %d wait address", i);
retval0 = setPatternWaitAddress(i, pat->wait[i]);
//validate(pat->wait[i], retval0, msg, HEX);
if (ret == FAIL) {
break;
}
// patwaittime
memset(msg, 0, sizeof(msg));
sprintf(msg, "set pattern Loop %d wait time", i);
retval64 = setPatternWaitTime(i, pat->waittime[i]);
//validate64(pat->waittime[i], retval64, msg, HEX);
if (retval64 == FAIL) {
break;
}
}
}
return ret;
}

View File

@ -1,4 +1,5 @@
#include "readDefaultPattern.h" #include "readDefaultPattern.h"
#include "loadPattern.h"
#include "clogger.h" #include "clogger.h"
#include "common.h" #include "common.h"
#include "sls/ansi.h" #include "sls/ansi.h"

View File

@ -369,6 +369,9 @@ void function_table() {
flist[F_LOAD_DEFAULT_PATTERN] = &load_default_pattern; flist[F_LOAD_DEFAULT_PATTERN] = &load_default_pattern;
flist[F_GET_ALL_THRESHOLD_ENERGY] = &get_all_threshold_energy; flist[F_GET_ALL_THRESHOLD_ENERGY] = &get_all_threshold_energy;
flist[F_GET_MASTER] = &get_master; flist[F_GET_MASTER] = &get_master;
flist[F_GET_CSR] = &get_csr;
flist[F_SET_GAIN_CAPS] = &set_gain_caps;
flist[F_GET_GAIN_CAPS] = &get_gain_caps;
// check // check
if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) { if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) {
@ -1547,18 +1550,11 @@ int set_module(int file_des) {
// only set // only set
else if (Server_VerifyLock() == OK) { else if (Server_VerifyLock() == OK) {
// check index // check index
#if !(defined(EIGERD) || defined(MYTHEN3D))
//TODO! Check if this is used for any detector
switch (module.reg) { switch (module.reg) {
#ifdef EIGERD #ifdef JUNGFRAUD
case STANDARD:
case HIGHGAIN:
case LOWGAIN:
case VERYHIGHGAIN:
case VERYLOWGAIN:
#elif MYTHEN3D
case STANDARD:
case FAST:
case HIGHGAIN:
#elif JUNGFRAUD
case DYNAMICGAIN: case DYNAMICGAIN:
case DYNAMICHG0: case DYNAMICHG0:
case FIXGAIN1: case FIXGAIN1:
@ -1577,10 +1573,12 @@ int set_module(int file_des) {
modeNotImplemented("Settings", (int)module.reg); modeNotImplemented("Settings", (int)module.reg);
break; break;
} }
#endif
ret = setModule(module, mess); ret = setModule(module, mess);
enum detectorSettings retval = getSettings(); enum detectorSettings retval = getSettings();
#if !(defined(EIGERD) || defined(MYTHEN3D))
validate(module.reg, (int)retval, "set module (settings)", DEC); validate(module.reg, (int)retval, "set module (settings)", DEC);
#endif
LOG(logDEBUG1, ("Settings: %d\n", retval)); LOG(logDEBUG1, ("Settings: %d\n", retval));
} }
free(myChan); free(myChan);
@ -7578,7 +7576,6 @@ int set_pattern(int file_des) {
patternParameters *pat = malloc(sizeof(patternParameters)); patternParameters *pat = malloc(sizeof(patternParameters));
memset(pat, 0, sizeof(patternParameters)); memset(pat, 0, sizeof(patternParameters));
// ignoring endianness for eiger // ignoring endianness for eiger
if (receiveData(file_des, pat, sizeof(patternParameters), INT32) < 0) { if (receiveData(file_des, pat, sizeof(patternParameters), INT32) < 0) {
if (pat != NULL) if (pat != NULL)
@ -7590,6 +7587,11 @@ int set_pattern(int file_des) {
LOG(logINFO, ("Setting Pattern from structure\n")); LOG(logINFO, ("Setting Pattern from structure\n"));
LOG(logINFO, LOG(logINFO,
("Setting Pattern Word (printing every 10 words that are not 0\n")); ("Setting Pattern Word (printing every 10 words that are not 0\n"));
/****************************************************************************************************************/
/* I SUGGEST TO VALIDATE THE VALUES HERE AND THEN WRITE THE PATTERN IN A SEPARATE FUNCTION WHICH COULD BE REUSED*/
/* added loadPattern.c/h - the same func could be reused also in readDefaultPattern */
/***************************************************************************************************************/
for (int i = 0; i < MAX_PATTERN_LENGTH; ++i) { for (int i = 0; i < MAX_PATTERN_LENGTH; ++i) {
if ((i % 10 == 0) && pat->word[i] != 0) { if ((i % 10 == 0) && pat->word[i] != 0) {
LOG(logINFO, ("Setting Pattern Word (addr:0x%x, word:0x%llx)\n", LOG(logINFO, ("Setting Pattern Word (addr:0x%x, word:0x%llx)\n",
@ -7662,6 +7664,7 @@ int set_pattern(int file_des) {
} }
} }
} }
/******* DOWN TO HERE ***********/
} }
if (pat != NULL) if (pat != NULL)
free(pat); free(pat);
@ -8383,3 +8386,63 @@ int get_master(int file_des){
#endif #endif
return Server_SendResult(file_des, INT32, &retval, sizeof(retval)); return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
} }
int get_csr(int file_des){
ret = OK;
memset(mess, 0, sizeof(mess));
int retval = -1;
LOG(logDEBUG1, ("Getting csr\n"));
#ifndef MYTHEN3D
functionNotImplemented();
#else
retval = getChipStatusRegister();
#endif
return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
}
int set_gain_caps(int file_des){
ret = OK;
memset(mess, 0, sizeof(mess));
int arg = 0;
if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0)
return printSocketReadError();
LOG(logINFO, ("Setting gain caps to: %u\n", arg));
int retval = -1;
#ifndef MYTHEN3D
functionNotImplemented();
#else
if (Server_VerifyLock() == OK) {
setGainCaps(arg);
retval = getChipStatusRegister(); //TODO! fix
LOG(logDEBUG1, ("gain caps retval: %u\n", retval));
}
#endif
return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
}
int get_gain_caps(int file_des){
ret = OK;
memset(mess, 0, sizeof(mess));
// int arg = 0;
// if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0)
// return printSocketReadError();
LOG(logINFO, ("Getting gain caps\n"));
int retval = -1;
#ifndef MYTHEN3D
functionNotImplemented();
#else
if (Server_VerifyLock() == OK) {
retval = getGainCaps();
LOG(logDEBUG1, ("Gain caps: %u\n", retval));
}
#endif
return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
}

View File

@ -1308,6 +1308,14 @@ class Detector {
Result<bool> getMaster(Positions pos = {}) const; Result<bool> getMaster(Positions pos = {}) const;
//TODO! check if we really want to expose this !!!!!
Result<int> getChipStatusRegister(Positions pos = {}) const;
void setGainCaps(int caps, Positions pos = {});
Result<int> getGainCaps(Positions pos = {});
///@{ ///@{
/** @name CTB / Moench Specific */ /** @name CTB / Moench Specific */

View File

@ -55,6 +55,12 @@ void CmdParser::Parse(const std::string &s) {
command_ = arguments_[0]; command_ = arguments_[0];
arguments_.erase(begin(arguments_)); arguments_.erase(begin(arguments_));
} }
//allow comma sep
for (auto& arg : arguments_){
if (arg.back() == ',')
arg.pop_back();
}
DecodeIdAndPosition(command_.c_str()); DecodeIdAndPosition(command_.c_str());
} }

View File

@ -1981,6 +1981,43 @@ std::string CmdProxy::GateDelay(int action) {
return os.str(); return os.str();
} }
std::string CmdProxy::GainCaps(int action){
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "[cap1, cap2, ...]\n\t[Mythen3] gain, options: C10pre, C15sh, C30sh, C50sh, C225ACsh, C15pre"
<< '\n';
} else if (action == defs::GET_ACTION) {
if (!args.empty())
WrongNumberOfParameters(0);
auto tmp = det->getGainCaps();
sls::Result<defs::M3_GainCaps> csr;
for (auto val : tmp){
if (val)
csr.push_back(static_cast<defs::M3_GainCaps>(val));
}
os << OutString(csr) << '\n';
} else if (action == defs::PUT_ACTION) {
if (args.size() < 1) {
WrongNumberOfParameters(1);
}
int caps = 0;
for (const auto& arg:args){
if (arg != "0")
caps |= sls::StringTo<defs::M3_GainCaps>(arg);
}
det->setGainCaps(caps);
os << OutString(args) << '\n';
} else {
throw sls::RuntimeError("Unknown action");
}
return os.str();
}
/* CTB / Moench Specific */ /* CTB / Moench Specific */
std::string CmdProxy::Samples(int action) { std::string CmdProxy::Samples(int action) {

View File

@ -571,19 +571,6 @@ class CmdProxy {
return ToString(value, unit); return ToString(value, unit);
} }
// inline unsigned int stoiHex(const std::string& s) {
// unsigned long lresult = stoul(s, nullptr, 16);
// unsigned int result = lresult;
// if (result != lresult) {
// throw std::out_of_range("cannot convert to unsigned int");
// }
// return result;
// }
// inline unsigned long int stoulHex(const std::string& s) {
// unsigned long result = stoul(s, nullptr, 16);
// return result;
// }
using FunctionMap = std::map<std::string, std::string (CmdProxy::*)(int)>; using FunctionMap = std::map<std::string, std::string (CmdProxy::*)(int)>;
using StringMap = std::map<std::string, std::string>; using StringMap = std::map<std::string, std::string>;
@ -970,6 +957,7 @@ class CmdProxy {
{"gatedelay1", &CmdProxy::GateDelay}, {"gatedelay1", &CmdProxy::GateDelay},
{"gatedelay2", &CmdProxy::GateDelay}, {"gatedelay2", &CmdProxy::GateDelay},
{"gatedelay3", &CmdProxy::GateDelay}, {"gatedelay3", &CmdProxy::GateDelay},
{"gaincaps", &CmdProxy::GainCaps},
/* CTB/ Moench Specific */ /* CTB/ Moench Specific */
{"samples", &CmdProxy::Samples}, {"samples", &CmdProxy::Samples},
@ -1137,6 +1125,7 @@ class CmdProxy {
/* Mythen3 Specific */ /* Mythen3 Specific */
std::string Counters(int action); std::string Counters(int action);
std::string GateDelay(int action); std::string GateDelay(int action);
std::string GainCaps(int action);
/* CTB/ Moench Specific */ /* CTB/ Moench Specific */
std::string Samples(int action); std::string Samples(int action);
/* CTB Specific */ /* CTB Specific */

View File

@ -1615,6 +1615,18 @@ Result<bool> Detector::getMaster(Positions pos) const{
return pimpl->Parallel(&Module::isMaster, pos); return pimpl->Parallel(&Module::isMaster, pos);
} }
Result<int> Detector::getChipStatusRegister(Positions pos) const{
return pimpl->Parallel(&Module::getChipStatusRegister, pos);
}
void Detector::setGainCaps(int caps, Positions pos){
return pimpl->Parallel(&Module::setGainCaps, pos, caps);
}
Result<int> Detector::getGainCaps(Positions pos){
return pimpl->Parallel(&Module::getGainCaps, pos);
}
// CTB/ Moench Specific // CTB/ Moench Specific

View File

@ -1998,6 +1998,18 @@ bool Module::isMaster() const{
return sendToDetector<int>(F_GET_MASTER); return sendToDetector<int>(F_GET_MASTER);
} }
int Module::getChipStatusRegister() const{
return sendToDetector<int>(F_GET_CSR);
}
void Module::setGainCaps(int caps){
sendToDetector<int>(F_SET_GAIN_CAPS, caps);
}
int Module::getGainCaps(){
return sendToDetector<int>(F_GET_GAIN_CAPS);
}
// CTB / Moench Specific // CTB / Moench Specific
int Module::getNumberOfAnalogSamples() const { int Module::getNumberOfAnalogSamples() const {
return sendToDetector<int>(F_GET_NUM_ANALOG_SAMPLES); return sendToDetector<int>(F_GET_NUM_ANALOG_SAMPLES);
@ -3195,6 +3207,9 @@ sls_detector_module Module::readSettingsFile(const std::string &fname,
throw RuntimeError("Could not open settings file: " + fname); throw RuntimeError("Could not open settings file: " + fname);
} }
auto file_size = getFileSize(infile);
// eiger // eiger
if (shm()->myDetectorType == EIGER) { if (shm()->myDetectorType == EIGER) {
infile.read(reinterpret_cast<char *>(myMod.dacs), infile.read(reinterpret_cast<char *>(myMod.dacs),
@ -3220,6 +3235,16 @@ sls_detector_module Module::readSettingsFile(const std::string &fname,
// mythen3 (dacs, trimbits) // mythen3 (dacs, trimbits)
else if (shm()->myDetectorType == MYTHEN3) { else if (shm()->myDetectorType == MYTHEN3) {
int expected_size =
sizeof(int) * myMod.ndac + sizeof(int) * myMod.nchan + sizeof(myMod.reg);
if (file_size != expected_size) {
throw RuntimeError("The size of the settings file: " + fname +
" differs from the expected size, " +
std::to_string(file_size) + " instead of " +
std::to_string(expected_size) + " bytes");
}
infile.read(reinterpret_cast<char *>(&myMod.reg),
sizeof(myMod.reg));
infile.read(reinterpret_cast<char *>(myMod.dacs), infile.read(reinterpret_cast<char *>(myMod.dacs),
sizeof(int) * (myMod.ndac)); sizeof(int) * (myMod.ndac));
for (int i = 0; i < myMod.ndac; ++i) { for (int i = 0; i < myMod.ndac; ++i) {

View File

@ -426,6 +426,9 @@ class Module : public virtual slsDetectorDefs {
void setGateDelay(int gateIndex, int64_t value); void setGateDelay(int gateIndex, int64_t value);
std::array<time::ns, 3> getGateDelayForAllGates() const; std::array<time::ns, 3> getGateDelayForAllGates() const;
bool isMaster() const; bool isMaster() const;
int getChipStatusRegister() const;
void setGainCaps(int caps);
int getGainCaps();
/************************************************** /**************************************************
* * * *

View File

@ -10,6 +10,7 @@ set(SOURCES
src/ZmqSocket.cpp src/ZmqSocket.cpp
src/UdpRxSocket.cpp src/UdpRxSocket.cpp
src/sls_detector_exceptions.cpp src/sls_detector_exceptions.cpp
# src/sls_detector_defs.cpp
) )
# Header files to install as a part of the library # Header files to install as a part of the library

View File

@ -36,6 +36,7 @@ std::string ToString(const defs::dacIndex s);
std::string ToString(const std::vector<defs::dacIndex> &vec); std::string ToString(const std::vector<defs::dacIndex> &vec);
std::string ToString(const defs::burstMode s); std::string ToString(const defs::burstMode s);
std::string ToString(const defs::timingSourceType s); std::string ToString(const defs::timingSourceType s);
std::string ToString(const defs::M3_GainCaps s);
std::string ToString(const slsDetectorDefs::xy &coord); std::string ToString(const slsDetectorDefs::xy &coord);
std::ostream &operator<<(std::ostream &os, const slsDetectorDefs::xy &coord); std::ostream &operator<<(std::ostream &os, const slsDetectorDefs::xy &coord);
@ -297,6 +298,7 @@ template <> defs::readoutMode StringTo(const std::string &s);
template <> defs::dacIndex StringTo(const std::string &s); template <> defs::dacIndex StringTo(const std::string &s);
template <> defs::burstMode StringTo(const std::string &s); template <> defs::burstMode StringTo(const std::string &s);
template <> defs::timingSourceType StringTo(const std::string &s); template <> defs::timingSourceType StringTo(const std::string &s);
template <> defs::M3_GainCaps StringTo(const std::string &s);
template <> uint32_t StringTo(const std::string &s); template <> uint32_t StringTo(const std::string &s);
template <> uint64_t StringTo(const std::string &s); template <> uint64_t StringTo(const std::string &s);

View File

@ -48,3 +48,7 @@ int writeDataFile(std::string fname, int nch, short int *data);
// mkdir -p path implemented by recursive calls // mkdir -p path implemented by recursive calls
void mkdir_p(const std::string &path, std::string dir = ""); void mkdir_p(const std::string &path, std::string dir = "");
namespace sls {
int getFileSize(std::ifstream &ifs);
}

View File

@ -394,6 +394,16 @@ typedef struct {
*/ */
enum timingSourceType { TIMING_INTERNAL, TIMING_EXTERNAL }; enum timingSourceType { TIMING_INTERNAL, TIMING_EXTERNAL };
//gain caps Mythen3
enum M3_GainCaps {
M3_C10pre= 1<<7,
M3_C15sh = 1<<10,
M3_C30sh = 1<<11,
M3_C50sh = 1<<12,
M3_C225ACsh = 1<<13,
M3_C15pre = 1<<14,
};
#ifdef __cplusplus #ifdef __cplusplus
/** scan structure */ /** scan structure */
@ -625,6 +635,10 @@ typedef struct {
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
// TODO! discuss this // TODO! discuss this
#include <vector> //hmm... but currently no way around #include <vector> //hmm... but currently no way around
namespace sls { namespace sls {

View File

@ -221,6 +221,9 @@ enum detFuncs {
F_LOAD_DEFAULT_PATTERN, F_LOAD_DEFAULT_PATTERN,
F_GET_ALL_THRESHOLD_ENERGY, F_GET_ALL_THRESHOLD_ENERGY,
F_GET_MASTER, F_GET_MASTER,
F_GET_CSR,
F_SET_GAIN_CAPS,
F_GET_GAIN_CAPS,
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

View File

@ -1,5 +1,5 @@
/** API versions */ /** API versions */
#define GITBRANCH "5.1.0" #define GITBRANCH "developer"
#define APICTB 0x210225 #define APICTB 0x210225
#define APIGOTTHARD 0x210225 #define APIGOTTHARD 0x210225
#define APIGOTTHARD2 0x210225 #define APIGOTTHARD2 0x210225

View File

@ -859,6 +859,44 @@ template <> defs::timingSourceType StringTo(const std::string &s) {
throw sls::RuntimeError("Unknown timing source type " + s); throw sls::RuntimeError("Unknown timing source type " + s);
} }
template <> defs::M3_GainCaps StringTo(const std::string &s){
if (s == "C10pre")
return defs::M3_C10pre;
if (s == "C15sh")
return defs::M3_C15sh;
if (s == "C30sh")
return defs::M3_C30sh;
if (s == "C50sh")
return defs::M3_C50sh;
if (s == "C225ACsh")
return defs::M3_C225ACsh;
if (s == "C15pre")
return defs::M3_C15pre;
throw sls::RuntimeError("Unknown gain cap " + s);
}
std::string ToString(defs::M3_GainCaps s){
std::ostringstream os;
if (s & defs::M3_C10pre)
os << "C10pre, ";
if (s & defs::M3_C15sh)
os << "C15sh, ";
if (s & defs::M3_C30sh)
os << "C30sh, ";
if (s & defs::M3_C50sh)
os << "C50sh, ";
if (s & defs::M3_C225ACsh)
os << "C225ACsh, ";
if (s & defs::M3_C15pre)
os << "C15pre, ";
auto rs = os.str();
rs.erase(rs.end()-2);
return rs;
}
template <> uint32_t StringTo(const std::string &s) { template <> uint32_t StringTo(const std::string &s) {
int base = s.find("0x") != std::string::npos ? 16 : 10; int base = s.find("0x") != std::string::npos ? 16 : 10;
return std::stoul(s, nullptr, base); return std::stoul(s, nullptr, base);

View File

@ -3,6 +3,7 @@
#include "sls/sls_detector_exceptions.h" #include "sls/sls_detector_exceptions.h"
#include <errno.h> #include <errno.h>
#include <ios>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <sys/stat.h> #include <sys/stat.h>
@ -92,3 +93,13 @@ void mkdir_p(const std::string &path, std::string dir) {
if (i + 1 < path.length()) if (i + 1 < path.length())
mkdir_p(path.substr(i + 1), dir); mkdir_p(path.substr(i + 1), dir);
} }
namespace sls {
int getFileSize(std::ifstream &ifs) {
auto current_pos = ifs.tellg();
ifs.seekg(0, std::ios::end);
int file_size = ifs.tellg();
ifs.seekg(current_pos);
return file_size;
}
} // namespace sls

View File

@ -1,5 +1,6 @@
target_sources(tests PRIVATE target_sources(tests PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/test-bit_utils.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test-bit_utils.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-file_utils.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-container_utils.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test-container_utils.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-network_utils.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test-network_utils.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-string_utils.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test-string_utils.cpp

View File

@ -0,0 +1,28 @@
#include "catch.hpp"
#include "sls/file_utils.h"
#include <stdio.h>
#include <unistd.h>
#include <iostream>
#include <vector>
TEST_CASE("Get size of empty file") {
char fname[] = "temfile_XXXXXX";
int fh = mkstemp(fname);
std::ifstream ifs(fname);
auto size = sls::getFileSize(ifs);
REQUIRE(size == 0);
}
TEST_CASE("Get size of file with data") {
constexpr size_t n_bytes = 137;
std::vector<char> data(n_bytes);
char fname[] = "temfile_XXXXXX";
int fh = mkstemp(fname);
write(fh, data.data(), n_bytes);
std::ifstream ifs(fname);
auto size = sls::getFileSize(ifs);
REQUIRE(size == n_bytes);
REQUIRE(ifs.tellg() == 0); //getting size resets pos!
}