Compare commits

..

45 Commits

Author SHA1 Message Date
337e56d9bf cleaned up LTO detection 2020-04-23 08:23:36 +02:00
eb257154c6 added triggers 2020-04-22 09:15:31 +02:00
c1ae67ac46 Small refactor on ThreadObject and listener (#93)
* removed pointer, slight cleaning of loop

* removed semaphore, use getters

* removed redundant log msg

* removed comment

* added const

* removed comment

* changed header
2020-04-21 09:45:29 +02:00
68f76e5356 more like UdpRxSocket 2020-04-20 17:24:53 +02:00
8afa11ed33 removed pointer to server socket 2020-04-20 17:20:33 +02:00
bc389f4825 moved data members to top 2020-04-20 14:51:48 +02:00
095ced153c removed need for pointer 2020-04-20 14:31:10 +02:00
a1a5a20845 from thread sanitizer 2020-04-17 09:35:38 +02:00
c725a05ef8 fix RH7 2020-04-16 15:51:28 +02:00
815b6a37aa moved flag to base class 2020-04-16 13:22:51 +02:00
655a410d43 cleaned up UdpRxSocket 2020-04-16 09:45:44 +02:00
97ba81d923 fixed test 2020-04-14 16:58:37 +02:00
3d00eed0f0 Change SetTrimbits() and SaveAllTrimbits() to rely on top/bottom signal instead of TopAddressIsValid() for further cleanup. 2020-04-14 16:13:26 +02:00
a7f5300455 Merge pull request #92 from slsdetectorgroup/setrxhostname
Setrxhostname
2020-04-09 11:52:46 +02:00
2f33a1a479 updated binaries 2020-04-09 09:35:46 +02:00
39fa5e0185 client recieve rx parameters as a struct 2020-04-09 09:34:20 +02:00
ba4985ed4d Merge branch 'developer' of github.com:slsdetectorgroup/slsDetectorPackage into developer 2020-04-09 09:32:09 +02:00
f811c065d1 corrected a delete [] in multiThreadedAnalogDetector 2020-04-09 09:31:43 +02:00
3a1d87728c updated client api 2020-04-09 08:38:37 +02:00
0652ff6b5a updated binaries 2020-04-09 08:37:27 +02:00
373e177274 WIP 2020-04-09 08:35:30 +02:00
6dd6685e7d minor 2020-04-09 08:24:16 +02:00
38c31fdada WIP 2020-04-08 20:27:10 +02:00
b3fe0e79bc WIP 2020-04-08 16:43:28 +02:00
215e4a56fd Merge branch 'developer' into setrxhostname 2020-04-08 12:00:21 +02:00
71a68c2022 eiger transmitting fix in 10g mode (stop servers informed about 10g mode) 2020-04-08 11:58:59 +02:00
55f8497eac WIP 2020-04-08 11:05:06 +02:00
738f341265 eiger server compiled from previous commit 2020-04-08 08:41:39 +02:00
c4ae876ca7 Add Eiger server Init() modification also to initStopServer() 2020-04-07 17:45:53 +02:00
07cd71f0c7 removed update shared memory from detector, check if eiger firmware >=26: have same top and bottom addresses 2020-04-07 17:19:47 +02:00
9f3ad4e2f4 merge from 4.2.0 2020-04-07 15:14:27 +02:00
ab9fed45fb Merge pull request #91 from slsdetectorgroup/testing
Testing
2020-04-07 12:15:37 +02:00
a86ae0cb47 WIP 2020-04-07 12:14:22 +02:00
bdf0f9e2b9 fixed start stop tests 2020-04-07 10:39:50 +02:00
fad10273ed fix for server crashing when sending udp packets if no udp server present to listen to it (receiver): cannot use connect and write 2020-04-07 09:57:22 +02:00
83283b672a WIP 2020-04-06 19:38:35 +02:00
456b96446f WIP 2020-04-06 17:59:06 +02:00
80e55cd4da WIP 2020-04-06 17:28:05 +02:00
47b0e46f15 Merge branch 'developer' into testing 2020-04-06 10:55:41 +02:00
fdb6e3f3d4 Removeshm (#90)
* eiger: moved rate correction outside, fixed threshold energy bug in client (binaries not  updated yet)

* removed dr and deadtiem from shm

* help for rx_status and status to point them to rx_Start, rx_stop, start and stop

* moved progress to receiver

* removed currentsettings from eiger shm

* updated server binaries, and client api

* moench and ctb virtual servers compile fix

* gui: moved acquire to a concurrent qt thread so it doesnt block updateplot
2020-04-06 10:44:44 +02:00
eeed102bf3 somewhere between fork and pipes, crashes at sendingudppacket at print 2020-04-03 20:18:16 +02:00
7c7f7e8c70 testing WIP 2020-04-03 16:20:05 +02:00
262b4b0b16 more tests 2020-03-31 18:19:32 +02:00
83010de9f4 updated all binaries, previous ones may not work 2020-03-31 16:58:35 +02:00
f2dd146e56 updates on servers (mainly virtual): indices, dbit clock not allowed for moench anymore 2020-03-31 16:54:35 +02:00
92 changed files with 3765 additions and 2781 deletions

View File

@ -46,6 +46,11 @@ option(SLS_BUILD_DOCS "docs" OFF)
option(SLS_BUILD_EXAMPLES "examples" OFF) option(SLS_BUILD_EXAMPLES "examples" OFF)
option(SLS_TUNE_LOCAL "tune to local machine" OFF) option(SLS_TUNE_LOCAL "tune to local machine" OFF)
#Enable LTO if available
check_ipo_supported(RESULT SLS_LTO_AVAILABLE)
# Use ld.gold if it is available and isn't disabled explicitly # Use ld.gold if it is available and isn't disabled explicitly
option(SLS_USE_LD_GOLD "Use GNU gold linker" ON) option(SLS_USE_LD_GOLD "Use GNU gold linker" ON)
if (SLS_USE_LD_GOLD) if (SLS_USE_LD_GOLD)

View File

@ -160,6 +160,13 @@ class Detector(CppDetectorApi):
def frames(self, n_frames): def frames(self, n_frames):
self.setNumberOfFrames(n_frames) self.setNumberOfFrames(n_frames)
@property
def triggers(self):
return element_if_equal(self.getNumberOfTriggers())
@triggers.setter
def triggers(self, n_triggers):
self.setNumberOfTriggers(n_triggers)
@property @property
def exptime(self): def exptime(self):

View File

@ -320,7 +320,7 @@ public:
// int nnx, nny, ns; // int nnx, nny, ns;
int nn=dets[0]->getImageSize(nnx, nny,ns, nsy); int nn=dets[0]->getImageSize(nnx, nny,ns, nsy);
if (image) { if (image) {
delete image; delete [] image;
image=NULL; image=NULL;
} }
image=new int[nn]; image=new int[nn];

View File

@ -59,11 +59,9 @@ class qDrawPlot : public QWidget, private Ui::PlotObject {
private slots: private slots:
void SetSaveFileName(QString val); void SetSaveFileName(QString val);
void AcquireThread();
void UpdatePlot(); void UpdatePlot();
signals: signals:
void StartAcquireSignal();
void AcquireFinishedSignal(); void AcquireFinishedSignal();
void AbortSignal(); void AbortSignal();
void UpdateSignal(); void UpdateSignal();
@ -74,6 +72,7 @@ class qDrawPlot : public QWidget, private Ui::PlotObject {
void SetupPlots(); void SetupPlots();
void GetStatistics(double &min, double &max, double &sum); void GetStatistics(double &min, double &max, double &sum);
void DetachHists(); void DetachHists();
void AcquireThread();
static void GetAcquisitionFinishedCallBack(double currentProgress, static void GetAcquisitionFinishedCallBack(double currentProgress,
int detectorStatus, int detectorStatus,
void *this_pointer); void *this_pointer);

View File

@ -87,7 +87,6 @@ void qDrawPlot::SetupWidgetWindow() {
void qDrawPlot::Initialization() { void qDrawPlot::Initialization() {
connect(this, SIGNAL(UpdateSignal()), this, SLOT(UpdatePlot())); connect(this, SIGNAL(UpdateSignal()), this, SLOT(UpdatePlot()));
connect(this, SIGNAL(StartAcquireSignal()), this, SLOT(AcquireThread()));
} }
void qDrawPlot::SetupPlots() { void qDrawPlot::SetupPlots() {
@ -657,7 +656,8 @@ void qDrawPlot::StartAcquisition() {
xyRangeChanged = true; xyRangeChanged = true;
} }
emit StartAcquireSignal(); QtConcurrent::run(this, &qDrawPlot::AcquireThread);
LOG(logDEBUG) << "End of Starting Acquisition in qDrawPlot"; LOG(logDEBUG) << "End of Starting Acquisition in qDrawPlot";
} }

View File

@ -16,6 +16,7 @@ add_executable(ctbDetectorServer_virtual
../slsDetectorServer/src/LTC2620.c ../slsDetectorServer/src/LTC2620.c
../slsDetectorServer/src/MAX1932.c ../slsDetectorServer/src/MAX1932.c
../slsDetectorServer/src/programFpgaBlackfin.c ../slsDetectorServer/src/programFpgaBlackfin.c
../slsDetectorServer/src/communication_virtual.c
) )
include_directories( include_directories(
@ -33,6 +34,7 @@ target_compile_definitions(ctbDetectorServer_virtual
target_link_libraries(ctbDetectorServer_virtual target_link_libraries(ctbDetectorServer_virtual
PUBLIC pthread rt slsProjectCWarnings PUBLIC pthread rt slsProjectCWarnings
m
) )
set_target_properties(ctbDetectorServer_virtual PROPERTIES set_target_properties(ctbDetectorServer_virtual PROPERTIES

View File

@ -10,6 +10,9 @@
#include "MAX1932.h" // hv #include "MAX1932.h" // hv
#include "INA226.h" // i2c #include "INA226.h" // i2c
#include "ALTERA_PLL.h" // pll #include "ALTERA_PLL.h" // pll
#ifdef VIRTUAL
#include "communication_virtual.h"
#endif
#include <string.h> #include <string.h>
#include <unistd.h> // usleep #include <unistd.h> // usleep
@ -30,6 +33,7 @@ extern uint64_t udpFrameNumber;
extern uint32_t udpPacketNumber; extern uint32_t udpPacketNumber;
// Global variable from communication_funcs.c // Global variable from communication_funcs.c
extern int isControlServer;
extern void getMacAddressinString(char* cmac, int size, uint64_t mac); extern void getMacAddressinString(char* cmac, int size, uint64_t mac);
extern void getIpAddressinString(char* cip, uint32_t ip); extern void getIpAddressinString(char* cip, uint32_t ip);
@ -427,6 +431,12 @@ void initStopServer() {
LOG(logERROR, ("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n")); LOG(logERROR, ("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n"));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
#ifdef VIRTUAL
virtual_stop = 0;
if (!isControlServer) {
ComVirtual_setStop(virtual_stop);
}
#endif
} }
@ -469,7 +479,12 @@ void setupDetector() {
digitalEnable = 0; digitalEnable = 0;
naSamples = 1; naSamples = 1;
ndSamples = 1; ndSamples = 1;
#ifdef VIRTUAL
virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
#endif
ALTERA_PLL_ResetPLLAndReconfiguration(); ALTERA_PLL_ResetPLLAndReconfiguration();
resetCore(); resetCore();
@ -1386,12 +1401,6 @@ int getADC(enum ADCINDEX ind){
int setHighVoltage(int val){ int setHighVoltage(int val){
#ifdef VIRTUAL
if (val >= 0)
highvoltage = val;
return highvoltage;
#endif
// setting hv // setting hv
if (val >= 0) { if (val >= 0) {
LOG(logINFO, ("Setting High voltage: %d V\n", val)); LOG(logINFO, ("Setting High voltage: %d V\n", val));
@ -1400,7 +1409,7 @@ int setHighVoltage(int val){
// switch to external high voltage // switch to external high voltage
bus_w(addr, bus_r(addr) & (~POWER_HV_INTERNAL_SLCT_MSK)); bus_w(addr, bus_r(addr) & (~POWER_HV_INTERNAL_SLCT_MSK));
MAX1932_Set(val); MAX1932_Set(&val);
// switch on internal high voltage, if set // switch on internal high voltage, if set
if (val > 0) if (val > 0)
@ -2159,10 +2168,21 @@ int startStateMachine(){
} }
LOG(logINFOBLUE, ("Starting State Machine\n")); LOG(logINFOBLUE, ("Starting State Machine\n"));
virtual_status = 1; virtual_status = 1;
virtual_stop = 0; if (isControlServer) {
ComVirtual_setStatus(virtual_status);
virtual_stop = ComVirtual_getStop();
if (virtual_stop != 0) {
LOG(logERROR, ("Cant start acquisition. "
"Stop server has not updated stop status to 0\n"));
return FAIL;
}
}
if(pthread_create(&pthread_virtual_tid, NULL, &start_timer, NULL)) { if(pthread_create(&pthread_virtual_tid, NULL, &start_timer, NULL)) {
LOG(logERROR, ("Could not start Virtual acquisition thread\n")); LOG(logERROR, ("Could not start Virtual acquisition thread\n"));
virtual_status = 0; virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
return FAIL; return FAIL;
} }
LOG(logINFOGREEN, ("Virtual Acquisition started\n")); LOG(logINFOGREEN, ("Virtual Acquisition started\n"));
@ -2196,6 +2216,10 @@ int startStateMachine(){
#ifdef VIRTUAL #ifdef VIRTUAL
void* start_timer(void* arg) { void* start_timer(void* arg) {
if (!isControlServer) {
return NULL;
}
int64_t periodNs = getPeriod(); int64_t periodNs = getPeriod();
int numFrames = (getNumFrames() * int numFrames = (getNumFrames() *
getNumTriggers() ); getNumTriggers() );
@ -2222,6 +2246,8 @@ void* start_timer(void* arg) {
// loop over number of frames // loop over number of frames
for(frameNr = 0; frameNr != numFrames; ++frameNr ) { for(frameNr = 0; frameNr != numFrames; ++frameNr ) {
// update the virtual stop from stop server
virtual_stop = ComVirtual_getStop();
//check if virtual_stop is high //check if virtual_stop is high
if(virtual_stop == 1){ if(virtual_stop == 1){
break; break;
@ -2274,6 +2300,9 @@ void* start_timer(void* arg) {
closeUDPSocket(0); closeUDPSocket(0);
virtual_status = 0; virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
LOG(logINFOBLUE, ("Finished Acquiring\n")); LOG(logINFOBLUE, ("Finished Acquiring\n"));
return NULL; return NULL;
} }
@ -2282,7 +2311,18 @@ void* start_timer(void* arg) {
int stopStateMachine(){ int stopStateMachine(){
LOG(logINFORED, ("Stopping State Machine\n")); LOG(logINFORED, ("Stopping State Machine\n"));
#ifdef VIRTUAL #ifdef VIRTUAL
virtual_stop = 0; if (!isControlServer) {
virtual_stop = 1;
ComVirtual_setStop(virtual_stop);
// read till status is idle
int tempStatus = 1;
while(tempStatus == 1) {
tempStatus = ComVirtual_getStatus();
}
virtual_stop = 0;
ComVirtual_setStop(virtual_stop);
LOG(logINFO, ("Stopped State Machine\n"));
}
return OK; return OK;
#endif #endif
//stop state machine //stop state machine
@ -2301,7 +2341,10 @@ int stopStateMachine(){
enum runStatus getRunStatus(){ enum runStatus getRunStatus(){
#ifdef VIRTUAL #ifdef VIRTUAL
if(virtual_status == 0){ if (!isControlServer) {
virtual_status = ComVirtual_getStatus();
}
if(virtual_status == 0) {
LOG(logINFOBLUE, ("Status: IDLE\n")); LOG(logINFOBLUE, ("Status: IDLE\n"));
return IDLE; return IDLE;
}else{ }else{
@ -2573,6 +2616,9 @@ int readFrameFromFifo() {
uint32_t runBusy() { uint32_t runBusy() {
#ifdef VIRTUAL #ifdef VIRTUAL
if (!isControlServer) {
virtual_status = ComVirtual_getStatus();
}
return virtual_status; return virtual_status;
#endif #endif
uint32_t s = (bus_r(STATUS_REG) & STATUS_RN_BSY_MSK); uint32_t s = (bus_r(STATUS_REG) & STATUS_RN_BSY_MSK);

View File

@ -178,120 +178,100 @@ void Beb_GetModuleConfiguration(int* master, int* top, int* normal) {
void Beb_EndofDataSend(int tengiga) { int Beb_IsTransmitting(int* retval, int tengiga, int waitForDelay) {
//mapping new memory //mapping new memory
u_int32_t* csp0base=0; u_int32_t* csp0base = 0;
int l_framepktLsbcounter, l_framepktMsbcounter, l_txndelaycounter, l_framedelaycounter; int addr_l_txndelaycounter = 0, addr_l_framedelaycounter = 0;
int r_framepktLsbcounter, r_framepktMsbcounter, r_txndelaycounter, r_framedelaycounter; int addr_r_txndelaycounter = 0, addr_r_framedelaycounter = 0;
int l_framepktLsbcounter_new, l_framepktMsbcounter_new, l_txndelaycounter_new, l_framedelaycounter_new; int addr_l_framepktLsbcounter = 0, addr_l_framepktMsbcounter = 0;
int r_framepktLsbcounter_new, r_framepktMsbcounter_new, r_txndelaycounter_new, r_framedelaycounter_new; int addr_r_framepktLsbcounter = 0, addr_r_framepktMsbcounter = 0;
int addr_l_framepktLsbcounter, addr_l_framepktMsbcounter, addr_l_txndelaycounter, addr_l_framedelaycounter; if (tengiga) {
int addr_r_framepktLsbcounter, addr_r_framepktMsbcounter, addr_r_txndelaycounter, addr_r_framedelaycounter;
switch(tengiga) {
case 0:
addr_l_framepktLsbcounter = ONE_GIGA_LEFT_INDEX_LSB_COUNTER;
addr_l_framepktMsbcounter = ONE_GIGA_LEFT_INDEX_MSB_COUNTER;
addr_l_txndelaycounter = ONE_GIGA_LEFT_TXN_DELAY_COUNTER;
addr_l_framedelaycounter = ONE_GIGA_LEFT_FRAME_DELAY_COUNTER;
addr_r_framepktLsbcounter = ONE_GIGA_RIGHT_INDEX_LSB_COUNTER;
addr_r_framepktMsbcounter = ONE_GIGA_RIGHT_INDEX_MSB_COUNTER;
addr_r_txndelaycounter = ONE_GIGA_RIGHT_TXN_DELAY_COUNTER;
addr_r_framedelaycounter = ONE_GIGA_RIGHT_FRAME_DELAY_COUNTER;
break;
case 1:
addr_l_framepktLsbcounter = TEN_GIGA_LEFT_INDEX_LSB_COUNTER;
addr_l_framepktMsbcounter = TEN_GIGA_LEFT_INDEX_MSB_COUNTER;
addr_l_txndelaycounter = TEN_GIGA_LEFT_TXN_DELAY_COUNTER; addr_l_txndelaycounter = TEN_GIGA_LEFT_TXN_DELAY_COUNTER;
addr_l_framedelaycounter = TEN_GIGA_LEFT_FRAME_DELAY_COUNTER; addr_l_framedelaycounter = TEN_GIGA_LEFT_FRAME_DELAY_COUNTER;
addr_r_framepktLsbcounter = TEN_GIGA_RIGHT_INDEX_LSB_COUNTER;
addr_r_framepktMsbcounter = TEN_GIGA_RIGHT_INDEX_MSB_COUNTER;
addr_r_txndelaycounter = TEN_GIGA_RIGHT_TXN_DELAY_COUNTER; addr_r_txndelaycounter = TEN_GIGA_RIGHT_TXN_DELAY_COUNTER;
addr_r_framedelaycounter = TEN_GIGA_RIGHT_FRAME_DELAY_COUNTER; addr_r_framedelaycounter = TEN_GIGA_RIGHT_FRAME_DELAY_COUNTER;
break; addr_l_framepktLsbcounter = TEN_GIGA_LEFT_INDEX_LSB_COUNTER;
addr_l_framepktMsbcounter = TEN_GIGA_LEFT_INDEX_MSB_COUNTER;
addr_r_framepktLsbcounter = TEN_GIGA_RIGHT_INDEX_LSB_COUNTER;
addr_r_framepktMsbcounter = TEN_GIGA_RIGHT_INDEX_MSB_COUNTER;
} else {
addr_l_txndelaycounter = ONE_GIGA_LEFT_TXN_DELAY_COUNTER;
addr_l_framedelaycounter = ONE_GIGA_LEFT_FRAME_DELAY_COUNTER;
addr_r_txndelaycounter = ONE_GIGA_RIGHT_TXN_DELAY_COUNTER;
addr_r_framedelaycounter = ONE_GIGA_RIGHT_FRAME_DELAY_COUNTER;
addr_l_framepktLsbcounter = ONE_GIGA_LEFT_INDEX_LSB_COUNTER;
addr_l_framepktMsbcounter = ONE_GIGA_LEFT_INDEX_MSB_COUNTER;
addr_r_framepktLsbcounter = ONE_GIGA_RIGHT_INDEX_LSB_COUNTER;
addr_r_framepktMsbcounter = ONE_GIGA_RIGHT_INDEX_MSB_COUNTER;
} }
//open file pointer //open file pointer
int fd = Beb_open(&csp0base,XPAR_COUNTER_BASEADDR); int fd = Beb_open(&csp0base,XPAR_COUNTER_BASEADDR);
if (fd < 0) { if(fd < 0){
LOG(logERROR, ("Delay read counter fail\n")); cprintf(BG_RED,"Could not read Beb Delay read counter\n");
return; return FAIL;
} else { } else {
//read data first time //read data first time
l_framepktLsbcounter = Beb_Read32(csp0base, addr_l_framepktLsbcounter); int l_txndelaycounter = Beb_Read32(csp0base, addr_l_txndelaycounter);
l_framepktMsbcounter = Beb_Read32(csp0base, addr_l_framepktMsbcounter); int l_framedelaycounter = Beb_Read32(csp0base, addr_l_framedelaycounter);
l_txndelaycounter = Beb_Read32(csp0base, addr_l_txndelaycounter); int r_txndelaycounter = Beb_Read32(csp0base, addr_r_txndelaycounter);
l_framedelaycounter = Beb_Read32(csp0base, addr_l_framedelaycounter); int r_framedelaycounter = Beb_Read32(csp0base, addr_r_framedelaycounter);
r_framepktLsbcounter = Beb_Read32(csp0base, addr_r_framepktLsbcounter); int l_framepktLsbcounter = Beb_Read32(csp0base, addr_l_framepktLsbcounter);
r_framepktMsbcounter = Beb_Read32(csp0base, addr_r_framepktMsbcounter); int l_framepktMsbcounter = Beb_Read32(csp0base, addr_l_framepktMsbcounter);
r_txndelaycounter = Beb_Read32(csp0base, addr_r_txndelaycounter); int r_framepktLsbcounter = Beb_Read32(csp0base, addr_r_framepktLsbcounter);
r_framedelaycounter = Beb_Read32(csp0base, addr_r_framedelaycounter); int r_framepktMsbcounter = Beb_Read32(csp0base, addr_r_framepktMsbcounter);
LOG(logDEBUG1, ("\nLeft\n" #ifdef VERBOSE
"FramepacketLsbcounter: %d\n" printf("\nFirst Read:\n"
"FramepacketMsbcounter: %d\n" "\tLeft [Txndelaycounter:%d, Framedelaycounter:%d]\n"
"Txndelaycounter:%d\n" "\tRight [Txndelaycounter:%d, Framedelaycounter:%d]\n",
"Framedelaycounter:%d\n" "\tLeft [FramepacketLsbcounter:%d, FramepacketMsbcounter:%d]\n"
"\nRight\n" "\tRight [FramepacketLsbcounter:%d, FramepacketMsbcounter:%d]\n",
"FramepacketLsbcounter: %d\n" l_txndelaycounter,l_framedelaycounter, r_txndelaycounter,r_framedelaycounter,
"FramepacketMsbcounter: %d\n" l_framepktLsbcounter, l_framepktMsbcounter, r_framepktLsbcounter, r_framepktMsbcounter);
"Txndelaycounter:%d\n" #endif
"Framedelaycounter:%d\n\n", // wait for max counter delay
l_framepktLsbcounter,l_framepktMsbcounter,l_txndelaycounter,l_framedelaycounter, if (waitForDelay) {
r_framepktLsbcounter,r_framepktMsbcounter,r_txndelaycounter,r_framedelaycounter)); int maxtimer = (MAX(MAX(l_txndelaycounter,l_framedelaycounter),MAX(r_txndelaycounter,r_framedelaycounter))) / 100; // counter values in 10 ns
printf("Will wait for %d us\n", maxtimer);
//keep comparing with previous values usleep (maxtimer);
int maxtimer; }
while(1) { // wait for 1 ms
maxtimer = MAX(MAX(l_txndelaycounter,l_framedelaycounter),MAX(r_txndelaycounter,r_framedelaycounter)); else {
maxtimer /= 100; printf("Will wait for 1 ms\n");
LOG(logDEBUG1, ("Will wait for %d us\n",maxtimer)); usleep (1 * 1000);
usleep(maxtimer);
//read new values
l_framepktLsbcounter_new = Beb_Read32(csp0base, addr_l_framepktLsbcounter);
l_framepktMsbcounter_new = Beb_Read32(csp0base, addr_l_framepktMsbcounter);
l_txndelaycounter_new = Beb_Read32(csp0base, addr_l_txndelaycounter);
l_framedelaycounter_new = Beb_Read32(csp0base, addr_l_framedelaycounter);
r_framepktLsbcounter_new = Beb_Read32(csp0base, addr_r_framepktLsbcounter);
r_framepktMsbcounter_new = Beb_Read32(csp0base, addr_r_framepktMsbcounter);
r_txndelaycounter_new = Beb_Read32(csp0base, addr_r_txndelaycounter);
r_framedelaycounter_new = Beb_Read32(csp0base, addr_r_framedelaycounter);
LOG(logDEBUG1, ("\nLeft\n"
"FramepacketLsbcounter: %d\n"
"FramepacketMsbcounter: %d\n"
"Txndelaycounter:%d\n"
"Framedelaycounter:%d\n"
"\nRight\n"
"FramepacketLsbcounter: %d\n"
"FramepacketMsbcounter: %d\n"
"Txndelaycounter:%d\n"
"Framedelaycounter:%d\n\n",
l_framepktLsbcounter_new,l_framepktMsbcounter_new,l_txndelaycounter_new,l_framedelaycounter_new,
r_framepktLsbcounter_new,r_framepktMsbcounter_new,r_txndelaycounter_new,r_framedelaycounter_new));
if ((l_framepktLsbcounter == l_framepktLsbcounter_new) &&
(l_framepktMsbcounter == l_framepktMsbcounter_new) &&
(r_framepktLsbcounter == r_framepktLsbcounter_new) &&
(r_framepktMsbcounter == r_framepktMsbcounter_new))
break;
//update old values
l_framepktLsbcounter = l_framepktLsbcounter_new;
l_framepktMsbcounter = l_framepktMsbcounter_new;
l_txndelaycounter = l_txndelaycounter_new;
l_framedelaycounter = l_framedelaycounter_new;
r_framepktLsbcounter = r_framepktLsbcounter_new;
r_framepktMsbcounter = r_framepktMsbcounter_new;
r_txndelaycounter = r_txndelaycounter_new;
r_framedelaycounter = r_framedelaycounter_new;
} }
LOG(logINFO, ("Detector has sent all data\n")); // read values again
int l_txndelaycounter2 = Beb_Read32(csp0base, addr_l_txndelaycounter);
int l_framedelaycounter2 = Beb_Read32(csp0base, addr_l_framedelaycounter);
int r_txndelaycounter2 = Beb_Read32(csp0base, addr_r_txndelaycounter);
int r_framedelaycounter2 = Beb_Read32(csp0base, addr_r_framedelaycounter);
int l_framepktLsbcounter2 = Beb_Read32(csp0base, addr_l_framepktLsbcounter);
int l_framepktMsbcounter2 = Beb_Read32(csp0base, addr_l_framepktMsbcounter);
int r_framepktLsbcounter2 = Beb_Read32(csp0base, addr_r_framepktLsbcounter);
int r_framepktMsbcounter2 = Beb_Read32(csp0base, addr_r_framepktMsbcounter);
#ifdef VERBOSE
printf("\nSecond Read:\n"
"\tLeft [Txndelaycounter:%d, Framedelaycounter:%d]\n"
"\tRight [Txndelaycounter:%d, Framedelaycounter:%d]\n",
"\tLeft [FramepacketLsbcounter:%d, FramepacketMsbcounter:%d]\n"
"\tRight [FramepacketLsbcounter:%d, FramepacketMsbcounter:%d]\n",
l_txndelaycounter2,l_framedelaycounter2, r_txndelaycounter2,r_framedelaycounter2,
l_framepktLsbcounter2, l_framepktMsbcounter2, r_framepktLsbcounter2, r_framepktMsbcounter2);
#endif
// any change in values, it is still transmitting
if (l_txndelaycounter != l_txndelaycounter2 || l_framedelaycounter != l_framedelaycounter2 ||
r_txndelaycounter != r_txndelaycounter2 || r_framedelaycounter != r_framedelaycounter2 ||
l_framepktLsbcounter != l_framepktLsbcounter2 || l_framepktMsbcounter != l_framepktMsbcounter2 ||
r_framepktLsbcounter != r_framepktLsbcounter2 || r_framepktMsbcounter != r_framepktMsbcounter2) {
*retval = 1;
} else {
*retval = 0;
}
//close file pointer //close file pointer
Beb_close(fd,csp0base); Beb_close(fd,csp0base);
} }
return OK;
} }

View File

@ -34,7 +34,7 @@ unsigned int Beb_GetBebInfoIndex(unsigned int beb_numb);
void Beb_GetModuleConfiguration(int* master, int* top, int* normal); void Beb_GetModuleConfiguration(int* master, int* top, int* normal);
void Beb_EndofDataSend(int tengiga); int Beb_IsTransmitting(int* retval, int tengiga, int waitForDelay);
int Beb_SetMasterViaSoftware(); int Beb_SetMasterViaSoftware();
int Beb_SetSlaveViaSoftware(); int Beb_SetSlaveViaSoftware();

View File

@ -5,6 +5,7 @@ set(src
../slsDetectorServer/src/communication_funcs.c ../slsDetectorServer/src/communication_funcs.c
../slsDetectorServer/src/communication_funcs_UDP.c ../slsDetectorServer/src/communication_funcs_UDP.c
../slsDetectorServer/src/common.c ../slsDetectorServer/src/common.c
../slsDetectorServer/src/communication_virtual.c
) )
include_directories( include_directories(

View File

@ -898,7 +898,7 @@ int Feb_Control_SendDACValue(unsigned int dst_num, unsigned int ch, unsigned int
int Feb_Control_SetTrimbits(unsigned int module_num, unsigned int *trimbits) { int Feb_Control_SetTrimbits(unsigned int module_num, unsigned int *trimbits, int top) {
LOG(logINFO, ("Setting Trimbits\n")); LOG(logINFO, ("Setting Trimbits\n"));
//for (int iy=10000;iy<20020;++iy)//263681 //for (int iy=10000;iy<20020;++iy)//263681
@ -963,7 +963,7 @@ int Feb_Control_SetTrimbits(unsigned int module_num, unsigned int *trimbits) {
int i; int i;
for(i=0;i<8;i++) { // column loop i for(i=0;i<8;i++) { // column loop i
if (Module_TopAddressIsValid(&modules[1])) { if (top==1) {
trimbits_to_load_l[offset+chip_sc] |= ( 0x7 & trimbits[row_set*16480+super_column_start_position_l+i])<<((7-i)*4);//low trimbits_to_load_l[offset+chip_sc] |= ( 0x7 & trimbits[row_set*16480+super_column_start_position_l+i])<<((7-i)*4);//low
trimbits_to_load_l[offset+chip_sc+32] |= ((0x38 & trimbits[row_set*16480+super_column_start_position_l+i])>>3)<<((7-i)*4);//upper trimbits_to_load_l[offset+chip_sc+32] |= ((0x38 & trimbits[row_set*16480+super_column_start_position_l+i])>>3)<<((7-i)*4);//upper
trimbits_to_load_r[offset+chip_sc] |= ( 0x7 & trimbits[row_set*16480+super_column_start_position_r+i])<<((7-i)*4);//low trimbits_to_load_r[offset+chip_sc] |= ( 0x7 & trimbits[row_set*16480+super_column_start_position_r+i])<<((7-i)*4);//low
@ -1572,12 +1572,12 @@ int Feb_Control_StopAcquisition() {
int Feb_Control_SaveAllTrimbitsTo(int value) { int Feb_Control_SaveAllTrimbitsTo(int value, int top) {
unsigned int chanregs[Feb_Control_trimbit_size]; unsigned int chanregs[Feb_Control_trimbit_size];
int i; int i;
for(i=0;i<Feb_Control_trimbit_size;i++) for(i=0;i<Feb_Control_trimbit_size;i++)
chanregs[i] = value; chanregs[i] = value;
return Feb_Control_SetTrimbits(0,chanregs); return Feb_Control_SetTrimbits(0,chanregs, top);
} }

View File

@ -93,9 +93,9 @@ int Feb_Control_SetDAC(char* s, int value, int is_a_voltage_mv);
int Feb_Control_GetDAC(char* s, int* ret_value, int voltage_mv); int Feb_Control_GetDAC(char* s, int* ret_value, int voltage_mv);
int Feb_Control_GetDACName(unsigned int dac_num,char* s); int Feb_Control_GetDACName(unsigned int dac_num,char* s);
int Feb_Control_SetTrimbits(unsigned int module_num, unsigned int* trimbits); int Feb_Control_SetTrimbits(unsigned int module_num, unsigned int* trimbits, int top);
unsigned int* Feb_Control_GetTrimbits(); unsigned int* Feb_Control_GetTrimbits();
int Feb_Control_SaveAllTrimbitsTo(int value); int Feb_Control_SaveAllTrimbitsTo(int value, int top);
int Feb_Control_Reset(); int Feb_Control_Reset();
int Feb_Control_PrepareForAcquisition(); int Feb_Control_PrepareForAcquisition();

View File

@ -6,6 +6,8 @@
#ifndef VIRTUAL #ifndef VIRTUAL
#include "FebControl.h" #include "FebControl.h"
#include "Beb.h" #include "Beb.h"
#else
#include "communication_virtual.h"
#endif #endif
#include <unistd.h> //to gethostname #include <unistd.h> //to gethostname
@ -67,9 +69,13 @@ int eiger_extgating = 0;
int eiger_extgatingpolarity = 0; int eiger_extgatingpolarity = 0;
int eiger_nexposures = 1; int eiger_nexposures = 1;
int eiger_ntriggers = 1; int eiger_ntriggers = 1;
int eiger_tau_ns = 0;
#ifdef VIRTUAL #ifdef VIRTUAL
pthread_t virtual_tid;
int virtual_status=0;
int virtual_stop = 0;
//values for virtual server //values for virtual server
int64_t eiger_virtual_exptime = 0; int64_t eiger_virtual_exptime = 0;
int64_t eiger_virtual_subexptime = 0; int64_t eiger_virtual_subexptime = 0;
@ -83,11 +89,8 @@ int eiger_virtual_transmission_delay_left=0;
int eiger_virtual_transmission_delay_right=0; int eiger_virtual_transmission_delay_right=0;
int eiger_virtual_transmission_delay_frame=0; int eiger_virtual_transmission_delay_frame=0;
int eiger_virtual_transmission_flowcontrol_10g=0; int eiger_virtual_transmission_flowcontrol_10g=0;
int eiger_virtual_status=0;
int eiger_virtual_activate=1; int eiger_virtual_activate=1;
pthread_t eiger_virtual_tid; uint64_t eiger_virtual_startingframenumber = 1;
int eiger_virtual_stop = 0;
uint64_t eiger_virtual_startingframenumber = 0;
int eiger_virtual_detPos[2] = {0, 0}; int eiger_virtual_detPos[2] = {0, 0};
int eiger_virtual_test_mode = 0; int eiger_virtual_test_mode = 0;
int eiger_virtual_quad_mode = 0; int eiger_virtual_quad_mode = 0;
@ -324,7 +327,14 @@ void initControlServer() {
getModuleConfiguration(); getModuleConfiguration();
Feb_Interface_FebInterface(); Feb_Interface_FebInterface();
Feb_Control_FebControl(); Feb_Control_FebControl();
Feb_Control_Init(master,top,normal, getDetectorNumber()); // different addresses for top and bottom
if (getFirmwareVersion() < FIRMWARE_VERSION_SAME_TOP_BOT_ADDR) {
Feb_Control_Init(master,top,normal, getDetectorNumber());
}
// same addresses for top and bottom
else {
Feb_Control_Init(master,1, normal, getDetectorNumber());
}
//master of 9M, check high voltage serial communication to blackfin //master of 9M, check high voltage serial communication to blackfin
if (master && !normal) { if (master && !normal) {
if (Feb_Control_OpenSerialCommunication()) if (Feb_Control_OpenSerialCommunication())
@ -352,12 +362,23 @@ void initControlServer() {
void initStopServer() { void initStopServer() {
#ifdef VIRTUAL #ifdef VIRTUAL
getModuleConfiguration(); getModuleConfiguration();
virtual_stop = 0;
if (!isControlServer) {
ComVirtual_setStop(virtual_stop);
}
return; return;
#else #else
getModuleConfiguration(); getModuleConfiguration();
Feb_Interface_FebInterface(); Feb_Interface_FebInterface();
Feb_Control_FebControl(); Feb_Control_FebControl();
Feb_Control_Init(master,top,normal,getDetectorNumber()); // different addresses for top and bottom
if (getFirmwareVersion() < FIRMWARE_VERSION_SAME_TOP_BOT_ADDR) {
Feb_Control_Init(master,top,normal, getDetectorNumber());
}
// same addresses for top and bottom
else {
Feb_Control_Init(master,1, normal, getDetectorNumber());
}
LOG(logDEBUG1, ("Stop server: FEB Initialization done\n")); LOG(logDEBUG1, ("Stop server: FEB Initialization done\n"));
// activate (if it gets ip) (later FW will deactivate at startup) // activate (if it gets ip) (later FW will deactivate at startup)
// also needed for stop server for status // also needed for stop server for status
@ -468,6 +489,12 @@ void setupDetector() {
} }
} }
} }
#ifdef VIRTUAL
virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
#endif
LOG(logINFOBLUE, ("Setting Default Parameters\n")); LOG(logINFOBLUE, ("Setting Default Parameters\n"));
//setting default measurement parameters //setting default measurement parameters
@ -477,6 +504,7 @@ void setupDetector() {
getSubExpTime(DEFAULT_SUBFRAME_DEADTIME); getSubExpTime(DEFAULT_SUBFRAME_DEADTIME);
setPeriod(DEFAULT_PERIOD); setPeriod(DEFAULT_PERIOD);
setNumTriggers(DEFAULT_NUM_CYCLES); setNumTriggers(DEFAULT_NUM_CYCLES);
eiger_dynamicrange = DEFAULT_DYNAMIC_RANGE;
setDynamicRange(DEFAULT_DYNAMIC_RANGE); setDynamicRange(DEFAULT_DYNAMIC_RANGE);
eiger_photonenergy = DEFAULT_PHOTON_ENERGY; eiger_photonenergy = DEFAULT_PHOTON_ENERGY;
setParallelMode(DEFAULT_PARALLEL_MODE); setParallelMode(DEFAULT_PARALLEL_MODE);
@ -488,6 +516,7 @@ void setupDetector() {
setStartingFrameNumber(DEFAULT_STARTING_FRAME_NUMBER); setStartingFrameNumber(DEFAULT_STARTING_FRAME_NUMBER);
setReadNLines(MAX_ROWS_PER_READOUT); setReadNLines(MAX_ROWS_PER_READOUT);
//SetPhotonEnergyCalibrationParameters(-5.8381e-5,1.838515,5.09948e-7,-4.32390e-11,1.32527e-15); //SetPhotonEnergyCalibrationParameters(-5.8381e-5,1.838515,5.09948e-7,-4.32390e-11,1.32527e-15);
eiger_tau_ns = DEFAULT_RATE_CORRECTION;
setRateCorrection(DEFAULT_RATE_CORRECTION); setRateCorrection(DEFAULT_RATE_CORRECTION);
int enable[2] = {DEFAULT_EXT_GATING_ENABLE, DEFAULT_EXT_GATING_POLARITY}; int enable[2] = {DEFAULT_EXT_GATING_ENABLE, DEFAULT_EXT_GATING_POLARITY};
setExternalGating(enable);//disable external gating setExternalGating(enable);//disable external gating
@ -532,31 +561,27 @@ int readRegister(uint32_t offset, uint32_t* retval) {
int setDynamicRange(int dr) { int setDynamicRange(int dr) {
#ifdef VIRTUAL // setting dr
if (dr > 0) {
LOG(logINFO, ("Setting dynamic range: %d\n", dr));
eiger_dynamicrange = dr;
}
return eiger_dynamicrange;
#else
if (dr > 0) { if (dr > 0) {
LOG(logDEBUG1, ("Setting dynamic range: %d\n", dr)); LOG(logDEBUG1, ("Setting dynamic range: %d\n", dr));
#ifndef VIRTUAL
if (Feb_Control_SetDynamicRange(dr)) { if (Feb_Control_SetDynamicRange(dr)) {
//EigerSetBitMode(dr);
on_dst = 0; on_dst = 0;
int i; int i;
for(i=0;i<32;i++) dst_requested[i] = 0; //clear dst requested for(i=0;i<32;i++) dst_requested[i] = 0; //clear dst requested
if (Beb_SetUpTransferParameters(dr)) if (!Beb_SetUpTransferParameters(dr)) {
eiger_dynamicrange = dr; LOG(logERROR, ("Could not set bit mode in the back end\n"));
else LOG(logERROR, ("Could not set bit mode in the back end\n")); return eiger_dynamicrange;
}
} }
}
//make sure back end and front end have the same bit mode
dr= Feb_Control_GetDynamicRange();
return dr;
#endif #endif
eiger_dynamicrange = dr;
}
// getting dr
#ifndef VIRTUAL
eiger_dynamicrange = Feb_Control_GetDynamicRange();
#endif
return eiger_dynamicrange;
} }
@ -734,7 +759,7 @@ int64_t getSubExpTime() {
#endif #endif
} }
int setDeadTime(int64_t val) { int setSubDeadTime(int64_t val) {
LOG(logINFO, ("Setting subdeadtime %lld ns\n", (long long int)val)); LOG(logINFO, ("Setting subdeadtime %lld ns\n", (long long int)val));
#ifndef VIRTUAL #ifndef VIRTUAL
// get subexptime // get subexptime
@ -756,7 +781,7 @@ int setDeadTime(int64_t val) {
return OK; return OK;
} }
int64_t getDeadTime() { int64_t getSubDeadTime() {
#ifndef VIRTUAL #ifndef VIRTUAL
// get subexptime // get subexptime
int64_t subexptime = Feb_Control_GetSubFrameExposureTime(); int64_t subexptime = Feb_Control_GetSubFrameExposureTime();
@ -842,8 +867,9 @@ int setModule(sls_detector_module myMod, char* mess) {
} }
} }
} }
// trimbits
#ifndef VIRTUAL #ifndef VIRTUAL
// trimbits
if (myMod.nchan == 0) { if (myMod.nchan == 0) {
LOG(logINFO, ("Setting module without trimbits\n")); LOG(logINFO, ("Setting module without trimbits\n"));
} else { } else {
@ -864,7 +890,7 @@ int setModule(sls_detector_module myMod, char* mess) {
} }
//set trimbits //set trimbits
if (!Feb_Control_SetTrimbits(Feb_Control_GetModuleNumber(), tt)) { if (!Feb_Control_SetTrimbits(Feb_Control_GetModuleNumber(), tt,top)) {
sprintf(mess, "Could not set module. Could not set trimbits\n"); sprintf(mess, "Could not set module. Could not set trimbits\n");
LOG(logERROR, (mess)); LOG(logERROR, (mess));
setSettings(UNDEFINED); setSettings(UNDEFINED);
@ -872,6 +898,7 @@ int setModule(sls_detector_module myMod, char* mess) {
return FAIL; return FAIL;
} }
} }
#endif
//rate correction //rate correction
@ -891,17 +918,24 @@ int setModule(sls_detector_module myMod, char* mess) {
else { else {
setDefaultSettingsTau_in_nsec(myMod.tau); setDefaultSettingsTau_in_nsec(myMod.tau);
if (getRateCorrectionEnable()) { if (getRateCorrectionEnable()) {
int64_t retvalTau = setRateCorrection(myMod.tau); if (setRateCorrection(myMod.tau) == FAIL) {
if (myMod.tau != retvalTau) { sprintf(mess, "Cannot set module. Rate correction failed.\n");
sprintf(mess, "Cannot set module. Could not set rate correction\n");
LOG(logERROR, (mess)); LOG(logERROR, (mess));
setSettings(UNDEFINED); setSettings(UNDEFINED);
LOG(logERROR, ("Settings has been changed to undefined (random trim file)\n")); LOG(logERROR, ("Settings has been changed to undefined (random trim file)\n"));
return FAIL; return FAIL;
} else {
int64_t retvalTau = getCurrentTau();
if (myMod.tau != retvalTau) {
sprintf(mess, "Cannot set module. Could not set rate correction\n");
LOG(logERROR, (mess));
setSettings(UNDEFINED);
LOG(logERROR, ("Settings has been changed to undefined (random trim file)\n"));
return FAIL;
}
} }
} }
} }
#endif
return OK; return OK;
} }
@ -1246,7 +1280,7 @@ int configureMAC() {
int i=0; int i=0;
/* for(i=0;i<32;i++) { modified for Aldo*/ /* for(i=0;i<32;i++) { modified for Aldo*/
if (Beb_SetBebSrcHeaderInfos(beb_num,send_to_ten_gig,src_mac,src_ip,src_port) && if (Beb_SetBebSrcHeaderInfos(beb_num,send_to_ten_gig,src_mac,src_ip,srcport) &&
Beb_SetUpUDPHeader(beb_num,send_to_ten_gig,header_number+i,dst_mac,dst_ip, dst_port)) { Beb_SetUpUDPHeader(beb_num,send_to_ten_gig,header_number+i,dst_mac,dst_ip, dst_port)) {
LOG(logDEBUG1, ("\tset up left ok\n")); LOG(logDEBUG1, ("\tset up left ok\n"));
} else { } else {
@ -1260,7 +1294,7 @@ int configureMAC() {
dst_port = dstport; dst_port = dstport;
/*for(i=0;i<32;i++) {*//** modified for Aldo*/ /*for(i=0;i<32;i++) {*//** modified for Aldo*/
if (Beb_SetBebSrcHeaderInfos(beb_num,send_to_ten_gig,src_mac,src_ip,src_port) && if (Beb_SetBebSrcHeaderInfos(beb_num,send_to_ten_gig,src_mac,src_ip,srcport) &&
Beb_SetUpUDPHeader(beb_num,send_to_ten_gig,header_number+i,dst_mac,dst_ip, dst_port)) { Beb_SetUpUDPHeader(beb_num,send_to_ten_gig,header_number+i,dst_mac,dst_ip, dst_port)) {
LOG(logDEBUG1, (" set up right ok\n")); LOG(logDEBUG1, (" set up right ok\n"));
} else { } else {
@ -1449,12 +1483,59 @@ int pulseChip(int n) {
return OK; return OK;
} }
int64_t setRateCorrection(int64_t custom_tau_in_nsec) {//in nanosec (will never be -1) int updateRateCorrection(char* mess) {
int ret = OK;
// recalculates rate correction table, or switches off in wrong bit mode
if (eiger_tau_ns != 0) {
switch (eiger_dynamicrange) {
case 16:
case 32:
ret = setRateCorrection(eiger_tau_ns);
break;
default:
setRateCorrection(0);
strcpy(mess, "Rate correction Deactivated, must be in 32 or 16 bit mode");
ret = FAIL;
break;
}
}
getCurrentTau(); // update eiger_tau_ns
return ret;
}
int validateAndSetRateCorrection(int64_t tau_ns, char* mess) {
// switching on in wrong bit mode
if ((tau_ns != 0) &&
(eiger_dynamicrange != 32) && (eiger_dynamicrange != 16)) {
strcpy(mess,"Rate correction Deactivated, must be in 32 or 16 bit mode\n");
LOG(logERROR,(mess));
return FAIL;
}
// default tau (-1, get proper value)
if (tau_ns < 0) {
tau_ns = getDefaultSettingsTau_in_nsec();
if (tau_ns < 0) {
strcpy(mess,"Default settings file not loaded. No default tau yet\n");
LOG(logERROR,(mess));
return FAIL;
}
eiger_tau_ns = -1;
}
// user defined value (settings become undefined)
else if (tau_ns > 0) {
setSettings(UNDEFINED);
LOG(logERROR, ("Settings has been changed to undefined (tau changed)\n"));
eiger_tau_ns = tau_ns;
}
return setRateCorrection(tau_ns);
}
int setRateCorrection(int64_t custom_tau_in_nsec) {//in nanosec (will never be -1)
#ifdef VIRTUAL #ifdef VIRTUAL
//deactivating rate correction //deactivating rate correction
if (custom_tau_in_nsec==0) { if (custom_tau_in_nsec==0) {
eiger_virtual_ratecorrection_variable = 0; eiger_virtual_ratecorrection_variable = 0;
return 0; return OK;
} }
//when dynamic range changes, use old tau //when dynamic range changes, use old tau
@ -1484,22 +1565,21 @@ int64_t setRateCorrection(int64_t custom_tau_in_nsec) {//in nanosec (will never
//different setting, calculate table //different setting, calculate table
else { else {
eiger_virtual_ratetable_tau_in_ns = custom_tau_in_nsec; eiger_virtual_ratetable_tau_in_ns = custom_tau_in_nsec;
double period_in_sec = (double)(eiger_virtual_subexptime*10)/(double)1e9; eiger_virtual_ratetable_period_in_ns = eiger_virtual_subexptime*10;
if (eiger_dynamicrange == 16) if (eiger_dynamicrange == 16)
period_in_sec = eiger_virtual_exptime; eiger_virtual_ratetable_period_in_ns = eiger_virtual_exptime;
eiger_virtual_ratetable_period_in_ns = period_in_sec*1e9;
} }
//activating rate correction //activating rate correction
eiger_virtual_ratecorrection_variable = 1; eiger_virtual_ratecorrection_variable = 1;
LOG(logINFO, ("Rate Correction Value set to %lld ns\n",(long long int)eiger_virtual_ratetable_tau_in_ns)); LOG(logINFO, ("Rate Correction Value set to %lld ns\n",(long long int)eiger_virtual_ratetable_tau_in_ns));
return eiger_virtual_ratetable_tau_in_ns; return OK;
#else #else
//deactivating rate correction //deactivating rate correction
if (custom_tau_in_nsec==0) { if (custom_tau_in_nsec==0) {
Feb_Control_SetRateCorrectionVariable(0); Feb_Control_SetRateCorrectionVariable(0);
return 0; return OK;
} }
//when dynamic range changes, use old tau //when dynamic range changes, use old tau
@ -1533,7 +1613,7 @@ int64_t setRateCorrection(int64_t custom_tau_in_nsec) {//in nanosec (will never
if (ret<=0) { if (ret<=0) {
LOG(logERROR, ("Rate correction failed. Deactivating rate correction\n")); LOG(logERROR, ("Rate correction failed. Deactivating rate correction\n"));
Feb_Control_SetRateCorrectionVariable(0); Feb_Control_SetRateCorrectionVariable(0);
return ret; return FAIL;
} }
} }
//activating rate correction //activating rate correction
@ -1541,7 +1621,7 @@ int64_t setRateCorrection(int64_t custom_tau_in_nsec) {//in nanosec (will never
LOG(logINFO, ("Rate Correction Value set to %lld ns\n", (long long int)Feb_Control_Get_RateTable_Tau_in_nsec())); LOG(logINFO, ("Rate Correction Value set to %lld ns\n", (long long int)Feb_Control_Get_RateTable_Tau_in_nsec()));
Feb_Control_PrintCorrectedValues(); Feb_Control_PrintCorrectedValues();
return Feb_Control_Get_RateTable_Tau_in_nsec(); return OK;
#endif #endif
} }
@ -1559,18 +1639,22 @@ int getDefaultSettingsTau_in_nsec() {
void setDefaultSettingsTau_in_nsec(int t) { void setDefaultSettingsTau_in_nsec(int t) {
default_tau_from_file = t; default_tau_from_file = t;
LOG(logINFO, ("Default tau set to %d\n", default_tau_from_file)); LOG(logINFOBLUE, ("Default tau set to %d\n", default_tau_from_file));
} }
int64_t getCurrentTau() { int64_t getCurrentTau() {
if (!getRateCorrectionEnable()) if (!getRateCorrectionEnable()) {
eiger_tau_ns = 0;
return 0; return 0;
else }
else {
#ifndef VIRTUAL #ifndef VIRTUAL
return Feb_Control_Get_RateTable_Tau_in_nsec(); eiger_tau_ns = Feb_Control_Get_RateTable_Tau_in_nsec();
#else #else
return eiger_virtual_ratetable_tau_in_ns; eiger_tau_ns = eiger_virtual_ratetable_tau_in_ns;
#endif #endif
return eiger_tau_ns;
}
} }
void setExternalGating(int enable[]) { void setExternalGating(int enable[]) {
@ -1587,7 +1671,7 @@ void setExternalGating(int enable[]) {
int setAllTrimbits(int val) { int setAllTrimbits(int val) {
#ifndef VIRTUAL #ifndef VIRTUAL
if (!Feb_Control_SaveAllTrimbitsTo(val)) { if (!Feb_Control_SaveAllTrimbitsTo(val,top)) {
LOG(logERROR, ("Could not set all trimbits\n")); LOG(logERROR, ("Could not set all trimbits\n"));
return FAIL; return FAIL;
} }
@ -1745,11 +1829,22 @@ int startStateMachine() {
return FAIL; return FAIL;
} }
LOG(logINFOBLUE, ("Starting State Machine\n")); LOG(logINFOBLUE, ("Starting State Machine\n"));
eiger_virtual_status = 1; virtual_status = 1;
eiger_virtual_stop = 0; if (isControlServer) {
if (pthread_create(&eiger_virtual_tid, NULL, &start_timer, NULL)) { ComVirtual_setStatus(virtual_status);
virtual_stop = ComVirtual_getStop();
if (virtual_stop != 0) {
LOG(logERROR, ("Cant start acquisition. "
"Stop server has not updated stop status to 0\n"));
return FAIL;
}
}
if (pthread_create(&virtual_tid, NULL, &start_timer, NULL)) {
LOG(logERROR, ("Could not start Virtual acquisition thread\n")); LOG(logERROR, ("Could not start Virtual acquisition thread\n"));
eiger_virtual_status = 0; virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
return FAIL; return FAIL;
} }
LOG(logINFO ,("Virtual Acquisition started\n")); LOG(logINFO ,("Virtual Acquisition started\n"));
@ -1783,6 +1878,10 @@ int startStateMachine() {
#ifdef VIRTUAL #ifdef VIRTUAL
void* start_timer(void* arg) { void* start_timer(void* arg) {
if (!isControlServer) {
return NULL;
}
int64_t periodNs = eiger_virtual_period; int64_t periodNs = eiger_virtual_period;
int numFrames = nimages_per_request; int numFrames = nimages_per_request;
int64_t expUs = eiger_virtual_exptime / 1000; int64_t expUs = eiger_virtual_exptime / 1000;
@ -1836,14 +1935,19 @@ void* start_timer(void* arg) {
// Send data // Send data
{ {
int frameNr = 1; uint64_t frameNr = 0;
getStartingFrameNumber(&frameNr);
// loop over number of frames // loop over number of frames
for(frameNr = 1; frameNr <= numFrames; ++frameNr ) { int iframes = 0;
for(iframes = 0; iframes != numFrames; ++iframes ) {
usleep(eiger_virtual_transmission_delay_frame); usleep(eiger_virtual_transmission_delay_frame);
// update the virtual stop from stop server
virtual_stop = ComVirtual_getStop();
//check if virtual_stop is high //check if virtual_stop is high
if(eiger_virtual_stop == 1){ if(virtual_stop == 1){
setStartingFrameNumber(frameNr + iframes + 1);
break; break;
} }
@ -1865,7 +1969,7 @@ void* start_timer(void* arg) {
sls_detector_header* header = (sls_detector_header*)(packetData); sls_detector_header* header = (sls_detector_header*)(packetData);
header->detType = 3;//(uint16_t)myDetectorType; updated when firmware updates header->detType = 3;//(uint16_t)myDetectorType; updated when firmware updates
header->version = SLS_DETECTOR_HEADER_VERSION - 1; header->version = SLS_DETECTOR_HEADER_VERSION - 1;
header->frameNumber = frameNr; header->frameNumber = frameNr + iframes;
header->packetNumber = i; header->packetNumber = i;
header->row = row; header->row = row;
header->column = colLeft; header->column = colLeft;
@ -1875,7 +1979,7 @@ void* start_timer(void* arg) {
header = (sls_detector_header*)(packetData2); header = (sls_detector_header*)(packetData2);
header->detType = 3;//(uint16_t)myDetectorType; updated when firmware updates header->detType = 3;//(uint16_t)myDetectorType; updated when firmware updates
header->version = SLS_DETECTOR_HEADER_VERSION - 1; header->version = SLS_DETECTOR_HEADER_VERSION - 1;
header->frameNumber = frameNr; header->frameNumber = frameNr + iframes;
header->packetNumber = i; header->packetNumber = i;
header->row = row; header->row = row;
header->column = colRight; header->column = colRight;
@ -1921,25 +2025,29 @@ void* start_timer(void* arg) {
sendUDPPacket(1, packetData2, packetsize); sendUDPPacket(1, packetData2, packetsize);
} }
} }
LOG(logINFO, ("Sent frame: %d\n", frameNr)); LOG(logINFO, ("Sent frame: %d\n", iframes));
clock_gettime(CLOCK_REALTIME, &end); clock_gettime(CLOCK_REALTIME, &end);
int64_t timeNs = ((end.tv_sec - begin.tv_sec) * 1E9 + int64_t timeNs = ((end.tv_sec - begin.tv_sec) * 1E9 +
(end.tv_nsec - begin.tv_nsec)); (end.tv_nsec - begin.tv_nsec));
// sleep for (period - exptime) // sleep for (period - exptime)
if (frameNr < numFrames) { // if there is a next frame if (iframes < numFrames) { // if there is a next frame
if (periodNs > timeNs) { if (periodNs > timeNs) {
usleep((periodNs - timeNs)/ 1000); usleep((periodNs - timeNs)/ 1000);
} }
} }
} }
setStartingFrameNumber(frameNr + numFrames);
} }
closeUDPSocket(0); closeUDPSocket(0);
closeUDPSocket(1); closeUDPSocket(1);
eiger_virtual_status = 0; virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
LOG(logINFOBLUE, ("Finished Acquiring\n")); LOG(logINFOBLUE, ("Finished Acquiring\n"));
return NULL; return NULL;
} }
@ -1951,7 +2059,18 @@ void* start_timer(void* arg) {
int stopStateMachine() { int stopStateMachine() {
LOG(logINFORED, ("Going to stop acquisition\n")); LOG(logINFORED, ("Going to stop acquisition\n"));
#ifdef VIRTUAL #ifdef VIRTUAL
eiger_virtual_stop = 0; if (!isControlServer) {
virtual_stop = 1;
ComVirtual_setStop(virtual_stop);
// read till status is idle
int tempStatus = 1;
while(tempStatus == 1) {
tempStatus = ComVirtual_getStatus();
}
virtual_stop = 0;
ComVirtual_setStop(virtual_stop);
LOG(logINFO, ("Stopped State Machine\n"));
}
return OK; return OK;
#else #else
if ((Feb_Control_StopAcquisition() != STATUS_IDLE) || (!Beb_StopAcquisition()) ) { if ((Feb_Control_StopAcquisition() != STATUS_IDLE) || (!Beb_StopAcquisition()) ) {
@ -2011,7 +2130,10 @@ int startReadOut() {
enum runStatus getRunStatus() { enum runStatus getRunStatus() {
#ifdef VIRTUAL #ifdef VIRTUAL
if (eiger_virtual_status == 0) { if (!isControlServer) {
virtual_status = ComVirtual_getStatus();
}
if (virtual_status == 0) {
LOG(logINFO, ("Status: IDLE\n")); LOG(logINFO, ("Status: IDLE\n"));
return IDLE; return IDLE;
} else { } else {
@ -2021,19 +2143,23 @@ enum runStatus getRunStatus() {
#else #else
int i = Feb_Control_AcquisitionInProgress(); int i = Feb_Control_AcquisitionInProgress();
switch (i) { if (i == STATUS_ERROR) {
case STATUS_ERROR:
LOG(logERROR, ("Status: ERROR reading status register\n")); LOG(logERROR, ("Status: ERROR reading status register\n"));
return ERROR; return ERROR;
case STATUS_IDLE: } else if (i == STATUS_IDLE) {
int isTransmitting = 0;
if (Beb_IsTransmitting(&isTransmitting, send_to_ten_gig, 0) == FAIL) {
return ERROR;
}
if (isTransmitting) {
printf("Status: TRANSMITTING\n");
return TRANSMITTING;
}
LOG(logINFOBLUE, ("Status: IDLE\n")); LOG(logINFOBLUE, ("Status: IDLE\n"));
return IDLE; return IDLE;
default:
LOG(logINFOBLUE, ("Status: RUNNING...\n"));
return RUNNING;
} }
LOG(logINFOBLUE, ("Status: RUNNING...\n"));
return IDLE; return RUNNING;
#endif #endif
} }
@ -2042,7 +2168,7 @@ enum runStatus getRunStatus() {
void readFrame(int *ret, char *mess) { void readFrame(int *ret, char *mess) {
#ifdef VIRTUAL #ifdef VIRTUAL
// wait for status to be done // wait for status to be done
while(eiger_virtual_status == 1){ while(virtual_status == 1){
usleep(500); usleep(500);
} }
LOG(logINFOGREEN, ("acquisition successfully finished\n")); LOG(logINFOGREEN, ("acquisition successfully finished\n"));
@ -2067,7 +2193,18 @@ void readFrame(int *ret, char *mess) {
} }
//wait for detector to send //wait for detector to send
Beb_EndofDataSend(send_to_ten_gig); int isTransmitting = 1;
while (isTransmitting) {
if (Beb_IsTransmitting(&isTransmitting, send_to_ten_gig, 1) == FAIL) {
strcpy(mess,"Could not read delay counters\n");
*ret = (int)FAIL;
return;
}
if (isTransmitting) {
printf("Transmitting...\n");
}
}
printf("Detector has sent all data\n");
LOG(logINFOGREEN, ("Acquisition successfully finished\n")); LOG(logINFOGREEN, ("Acquisition successfully finished\n"));
#endif #endif
} }

View File

@ -3,6 +3,7 @@
#define REQUIRED_FIRMWARE_VERSION (24) #define REQUIRED_FIRMWARE_VERSION (24)
#define IDFILECOMMAND "more /home/root/executables/detid.txt" #define IDFILECOMMAND "more /home/root/executables/detid.txt"
#define FIRMWARE_VERSION_SAME_TOP_BOT_ADDR (26)
#define STATUS_IDLE 0 #define STATUS_IDLE 0
#define STATUS_RUNNING 1 #define STATUS_RUNNING 1
@ -63,10 +64,10 @@ enum CLKINDEX {RUN_CLK, NUM_CLOCKS};
#define DEFAULT_SUBFRAME_DEADTIME (0) #define DEFAULT_SUBFRAME_DEADTIME (0)
#define DEFAULT_DYNAMIC_RANGE (16) #define DEFAULT_DYNAMIC_RANGE (16)
#define DEFAULT_PARALLEL_MODE (0) #define DEFAULT_PARALLEL_MODE (1)
#define DEFAULT_READOUT_STOREINRAM_MODE (0) #define DEFAULT_READOUT_STOREINRAM_MODE (0)
#define DEFAULT_READOUT_OVERFLOW32_MODE (0) #define DEFAULT_READOUT_OVERFLOW32_MODE (0)
#define DEFAULT_CLK_SPEED (HALF_SPEED) #define DEFAULT_CLK_SPEED (FULL_SPEED)
#define DEFAULT_IO_DELAY (650) #define DEFAULT_IO_DELAY (650)
#define DEFAULT_TIMING_MODE (AUTO_TIMING) #define DEFAULT_TIMING_MODE (AUTO_TIMING)
#define DEFAULT_PHOTON_ENERGY (-1) #define DEFAULT_PHOTON_ENERGY (-1)

View File

@ -11,6 +11,7 @@ add_executable(gotthard2DetectorServer_virtual
../slsDetectorServer/src/ALTERA_PLL_CYCLONE10.c ../slsDetectorServer/src/ALTERA_PLL_CYCLONE10.c
../slsDetectorServer/src/ASIC_Driver.c ../slsDetectorServer/src/ASIC_Driver.c
../slsDetectorServer/src/programFpgaNios.c ../slsDetectorServer/src/programFpgaNios.c
../slsDetectorServer/src/communication_virtual.c
) )
include_directories( include_directories(

View File

@ -9,6 +9,7 @@
#include "ASIC_Driver.h" #include "ASIC_Driver.h"
#ifdef VIRTUAL #ifdef VIRTUAL
#include "communication_funcs_UDP.h" #include "communication_funcs_UDP.h"
#include "communication_virtual.h"
#endif #endif
#include <string.h> #include <string.h>
@ -27,6 +28,7 @@ extern udpStruct udpDetails;
extern const enum detectorType myDetectorType; extern const enum detectorType myDetectorType;
// Global variable from communication_funcs.c // Global variable from communication_funcs.c
extern int isControlServer;
extern void getMacAddressinString(char* cmac, int size, uint64_t mac); extern void getMacAddressinString(char* cmac, int size, uint64_t mac);
extern void getIpAddressinString(char* cip, uint32_t ip); extern void getIpAddressinString(char* cip, uint32_t ip);
@ -337,6 +339,12 @@ void initStopServer() {
LOG(logERROR, ("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n")); LOG(logERROR, ("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n"));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
#ifdef VIRTUAL
virtual_stop = 0;
if (!isControlServer) {
ComVirtual_setStop(virtual_stop);
}
#endif
} }
@ -386,9 +394,13 @@ void setupDetector() {
} }
} }
} }
#ifdef VIRTUAL
virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
#endif
#ifndef VIRTUAL
// pll defines // pll defines
ALTERA_PLL_C10_SetDefines(REG_OFFSET, BASE_READOUT_PLL, BASE_SYSTEM_PLL, PLL_RESET_REG, PLL_RESET_REG, PLL_RESET_READOUT_MSK, PLL_RESET_SYSTEM_MSK, READOUT_PLL_VCO_FREQ_HZ, SYSTEM_PLL_VCO_FREQ_HZ); ALTERA_PLL_C10_SetDefines(REG_OFFSET, BASE_READOUT_PLL, BASE_SYSTEM_PLL, PLL_RESET_REG, PLL_RESET_REG, PLL_RESET_READOUT_MSK, PLL_RESET_SYSTEM_MSK, READOUT_PLL_VCO_FREQ_HZ, SYSTEM_PLL_VCO_FREQ_HZ);
ALTERA_PLL_C10_ResetPLL(READOUT_PLL); ALTERA_PLL_C10_ResetPLL(READOUT_PLL);
@ -399,7 +411,6 @@ void setupDetector() {
LTC2620_D_SetDefines(DAC_MAX_MV, DAC_DRIVER_FILE_NAME, NDAC); LTC2620_D_SetDefines(DAC_MAX_MV, DAC_DRIVER_FILE_NAME, NDAC);
// on chip dacs // on chip dacs
ASIC_Driver_SetDefines(ONCHIP_DAC_DRIVER_FILE_NAME); ASIC_Driver_SetDefines(ONCHIP_DAC_DRIVER_FILE_NAME);
#endif
setTimingSource(DEFAULT_TIMING_SOURCE); setTimingSource(DEFAULT_TIMING_SOURCE);
// Default values // Default values
@ -436,12 +447,10 @@ void setupDetector() {
// power on chip // power on chip
powerChip(1); powerChip(1);
#ifndef VIRTUAL
// also sets default dac and on chip dac values // also sets default dac and on chip dac values
if (readConfigFile() == FAIL) { if (readConfigFile() == FAIL) {
return; return;
} }
#endif
setBurstMode(DEFAULT_BURST_MODE); setBurstMode(DEFAULT_BURST_MODE);
setSettings(DEFAULT_SETTINGS); setSettings(DEFAULT_SETTINGS);
@ -1333,6 +1342,9 @@ int* getDetectorPosition() {
// Detector Specific // Detector Specific
int checkDetectorType() { int checkDetectorType() {
#ifdef VIRTUAL
return OK;
#endif
LOG(logINFO, ("Checking type of module\n")); LOG(logINFO, ("Checking type of module\n"));
FILE* fd = fopen(TYPE_FILE_NAME, "r"); FILE* fd = fopen(TYPE_FILE_NAME, "r");
if (fd == NULL) { if (fd == NULL) {
@ -2007,10 +2019,21 @@ int startStateMachine(){
LOG(logINFOBLUE, ("Starting State Machine\n")); LOG(logINFOBLUE, ("Starting State Machine\n"));
// set status to running // set status to running
virtual_status = 1; virtual_status = 1;
virtual_stop = 0; if (isControlServer) {
ComVirtual_setStatus(virtual_status);
virtual_stop = ComVirtual_getStop();
if (virtual_stop != 0) {
LOG(logERROR, ("Cant start acquisition. "
"Stop server has not updated stop status to 0\n"));
return FAIL;
}
}
if(pthread_create(&pthread_virtual_tid, NULL, &start_timer, NULL)) { if(pthread_create(&pthread_virtual_tid, NULL, &start_timer, NULL)) {
LOG(logERROR, ("Could not start Virtual acquisition thread\n")); LOG(logERROR, ("Could not start Virtual acquisition thread\n"));
virtual_status = 0; virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
return FAIL; return FAIL;
} }
LOG(logINFOGREEN, ("Virtual Acquisition started\n")); LOG(logINFOGREEN, ("Virtual Acquisition started\n"));
@ -2029,6 +2052,10 @@ int startStateMachine(){
#ifdef VIRTUAL #ifdef VIRTUAL
void* start_timer(void* arg) { void* start_timer(void* arg) {
if (!isControlServer) {
return NULL;
}
int numRepeats = getNumTriggers(); int numRepeats = getNumTriggers();
if (getTiming() == AUTO_TIMING) { if (getTiming() == AUTO_TIMING) {
if (burstMode == BURST_OFF) { if (burstMode == BURST_OFF) {
@ -2068,6 +2095,8 @@ void* start_timer(void* arg) {
// loop over number of frames // loop over number of frames
for(frameNr = 0; frameNr != numFrames; ++frameNr ) { for(frameNr = 0; frameNr != numFrames; ++frameNr ) {
// update the virtual stop from stop server
virtual_stop = ComVirtual_getStop();
//check if virtual_stop is high //check if virtual_stop is high
if(virtual_stop == 1){ if(virtual_stop == 1){
break; break;
@ -2126,6 +2155,9 @@ void* start_timer(void* arg) {
closeUDPSocket(0); closeUDPSocket(0);
virtual_status = 0; virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
LOG(logINFOBLUE, ("Finished Acquiring\n")); LOG(logINFOBLUE, ("Finished Acquiring\n"));
return NULL; return NULL;
} }
@ -2135,7 +2167,18 @@ void* start_timer(void* arg) {
int stopStateMachine(){ int stopStateMachine(){
LOG(logINFORED, ("Stopping State Machine\n")); LOG(logINFORED, ("Stopping State Machine\n"));
#ifdef VIRTUAL #ifdef VIRTUAL
virtual_stop = 0; if (!isControlServer) {
virtual_stop = 1;
ComVirtual_setStop(virtual_stop);
// read till status is idle
int tempStatus = 1;
while(tempStatus == 1) {
tempStatus = ComVirtual_getStatus();
}
virtual_stop = 0;
ComVirtual_setStop(virtual_stop);
LOG(logINFO, ("Stopped State Machine\n"));
}
return OK; return OK;
#endif #endif
//stop state machine //stop state machine
@ -2146,7 +2189,10 @@ int stopStateMachine(){
enum runStatus getRunStatus(){ enum runStatus getRunStatus(){
#ifdef VIRTUAL #ifdef VIRTUAL
if(virtual_status == 0){ if (!isControlServer) {
virtual_status = ComVirtual_getStatus();
}
if(virtual_status == 0) {
LOG(logINFOBLUE, ("Status: IDLE\n")); LOG(logINFOBLUE, ("Status: IDLE\n"));
return IDLE; return IDLE;
}else{ }else{
@ -2220,6 +2266,9 @@ void readFrame(int *ret, char *mess) {
u_int32_t runBusy() { u_int32_t runBusy() {
#ifdef VIRTUAL #ifdef VIRTUAL
if (!isControlServer) {
virtual_status = ComVirtual_getStatus();
}
return virtual_status; return virtual_status;
#endif #endif
u_int32_t s = (bus_r(FLOW_STATUS_REG) & FLOW_STATUS_RUN_BUSY_MSK); u_int32_t s = (bus_r(FLOW_STATUS_REG) & FLOW_STATUS_RUN_BUSY_MSK);

View File

@ -10,6 +10,7 @@ add_executable(gotthardDetectorServer_virtual
../slsDetectorServer/src/common.c ../slsDetectorServer/src/common.c
../slsDetectorServer/src/commonServerFunctions.c ../slsDetectorServer/src/commonServerFunctions.c
../slsDetectorServer/src/communication_funcs_UDP.c ../slsDetectorServer/src/communication_funcs_UDP.c
../slsDetectorServer/src/communication_virtual.c
) )
include_directories( include_directories(

View File

@ -6,6 +6,7 @@
#include "LTC2620.h" // dacs #include "LTC2620.h" // dacs
#ifdef VIRTUAL #ifdef VIRTUAL
#include "communication_funcs_UDP.h" #include "communication_funcs_UDP.h"
#include "communication_virtual.h"
#endif #endif
#include "string.h" #include "string.h"
@ -23,6 +24,7 @@ extern const enum detectorType myDetectorType;
int phaseShift = DEFAULT_PHASE_SHIFT; int phaseShift = DEFAULT_PHASE_SHIFT;
// Global variable from communication_funcs.c // Global variable from communication_funcs.c
extern int isControlServer;
extern void getMacAddressinString(char* cmac, int size, uint64_t mac); extern void getMacAddressinString(char* cmac, int size, uint64_t mac);
extern void getIpAddressinString(char* cip, uint32_t ip); extern void getIpAddressinString(char* cip, uint32_t ip);
@ -354,6 +356,12 @@ void initStopServer() {
LOG(logERROR, ("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n")); LOG(logERROR, ("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n"));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
#ifdef VIRTUAL
virtual_stop = 0;
if (!isControlServer) {
ComVirtual_setStop(virtual_stop);
}
#endif
} }
@ -362,6 +370,13 @@ void initStopServer() {
void setupDetector() { void setupDetector() {
LOG(logINFO, ("This Server is for 1 Gotthard module (1280 channels)\n")); LOG(logINFO, ("This Server is for 1 Gotthard module (1280 channels)\n"));
#ifdef VIRTUAL
virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
#endif
// Initialization // Initialization
setPhaseShiftOnce(); setPhaseShiftOnce();
@ -1098,11 +1113,6 @@ int getADC(enum ADCINDEX ind){
} }
int setHighVoltage(int val){ int setHighVoltage(int val){
#ifdef VIRTUAL
if (val >= 0)
highvoltage = val;
return highvoltage;
#endif
u_int32_t addr = HV_REG; u_int32_t addr = HV_REG;
u_int32_t sel = 0x0; u_int32_t sel = 0x0;
@ -1501,10 +1511,21 @@ int startStateMachine(){
} }
LOG(logINFOBLUE, ("Starting State Machine\n")); LOG(logINFOBLUE, ("Starting State Machine\n"));
virtual_status = 1; virtual_status = 1;
virtual_stop = 0; if (isControlServer) {
ComVirtual_setStatus(virtual_status);
virtual_stop = ComVirtual_getStop();
if (virtual_stop != 0) {
LOG(logERROR, ("Cant start acquisition. "
"Stop server has not updated stop status to 0\n"));
return FAIL;
}
}
if(pthread_create(&pthread_virtual_tid, NULL, &start_timer, NULL)) { if(pthread_create(&pthread_virtual_tid, NULL, &start_timer, NULL)) {
LOG(logERROR, ("Could not start Virtual acquisition thread\n")); LOG(logERROR, ("Could not start Virtual acquisition thread\n"));
virtual_status = 0; virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
return FAIL; return FAIL;
} }
LOG(logINFOGREEN, ("Virtual Acquisition started\n")); LOG(logINFOGREEN, ("Virtual Acquisition started\n"));
@ -1524,6 +1545,10 @@ int startStateMachine(){
#ifdef VIRTUAL #ifdef VIRTUAL
void* start_timer(void* arg) { void* start_timer(void* arg) {
if (!isControlServer) {
return NULL;
}
int64_t periodNs = getPeriod(); int64_t periodNs = getPeriod();
int numFrames = (getNumFrames() * int numFrames = (getNumFrames() *
getNumTriggers() ); getNumTriggers() );
@ -1542,18 +1567,20 @@ void* start_timer(void* arg) {
if (adcConfigured == -1) { if (adcConfigured == -1) {
*((uint32_t*)(imageData)) = 0xCACACACA; *((uint32_t*)(imageData)) = 0xCACACACA;
} }
for (i = 4; i < imageSize; i += sizeof(uint16_t)) { for (i = sizeof(uint32_t); i < imageSize; i += sizeof(uint16_t)) {
*((uint16_t*)(imageData + i)) = i; *((uint16_t*)(imageData + i)) = (uint16_t)i;
} }
} }
// Send data // Send data
{ {
int frameNr = 0; int frameNr = 0;
int frameHeaderNr = 2; uint16_t frameHeaderNr = 2;
// loop over number of frames // loop over number of frames
for(frameNr = 0; frameNr != numFrames; ++frameNr ) { for(frameNr = 0; frameNr != numFrames; ++frameNr ) {
// update the virtual stop from stop server
virtual_stop = ComVirtual_getStop();
//check if virtual_stop is high //check if virtual_stop is high
if(virtual_stop == 1){ if(virtual_stop == 1){
break; break;
@ -1600,6 +1627,9 @@ void* start_timer(void* arg) {
closeUDPSocket(0); closeUDPSocket(0);
virtual_status = 0; virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
LOG(logINFOBLUE, ("Finished Acquiring\n")); LOG(logINFOBLUE, ("Finished Acquiring\n"));
return NULL; return NULL;
} }
@ -1608,7 +1638,18 @@ void* start_timer(void* arg) {
int stopStateMachine(){ int stopStateMachine(){
LOG(logINFORED, ("Stopping State Machine\n")); LOG(logINFORED, ("Stopping State Machine\n"));
#ifdef VIRTUAL #ifdef VIRTUAL
virtual_stop = 0; if (!isControlServer) {
virtual_stop = 1;
ComVirtual_setStop(virtual_stop);
// read till status is idle
int tempStatus = 1;
while(tempStatus == 1) {
tempStatus = ComVirtual_getStatus();
}
virtual_stop = 0;
ComVirtual_setStop(virtual_stop);
LOG(logINFO, ("Stopped State Machine\n"));
}
return OK; return OK;
#endif #endif
//stop state machine //stop state machine
@ -1630,7 +1671,10 @@ int stopStateMachine(){
enum runStatus getRunStatus(){ enum runStatus getRunStatus(){
#ifdef VIRTUAL #ifdef VIRTUAL
if(virtual_status == 0){ if (!isControlServer) {
virtual_status = ComVirtual_getStatus();
}
if(virtual_status == 0) {
LOG(logINFOBLUE, ("Status: IDLE\n")); LOG(logINFOBLUE, ("Status: IDLE\n"));
return IDLE; return IDLE;
}else{ }else{
@ -1732,6 +1776,9 @@ void readFrame(int *ret, char *mess){
u_int32_t runBusy() { u_int32_t runBusy() {
#ifdef VIRTUAL #ifdef VIRTUAL
if (!isControlServer) {
virtual_status = ComVirtual_getStatus();
}
return virtual_status; return virtual_status;
#endif #endif
return runState(logDEBUG1) & STATUS_RN_BSY_MSK; return runState(logDEBUG1) & STATUS_RN_BSY_MSK;

View File

@ -12,6 +12,7 @@ add_executable(jungfrauDetectorServer_virtual
../slsDetectorServer/src/MAX1932.c ../slsDetectorServer/src/MAX1932.c
../slsDetectorServer/src/programFpgaBlackfin.c ../slsDetectorServer/src/programFpgaBlackfin.c
../slsDetectorServer/src/communication_funcs_UDP.c ../slsDetectorServer/src/communication_funcs_UDP.c
../slsDetectorServer/src/communication_virtual.c
) )
target_include_directories(jungfrauDetectorServer_virtual target_include_directories(jungfrauDetectorServer_virtual

View File

@ -8,6 +8,7 @@
#include "common.h" #include "common.h"
#ifdef VIRTUAL #ifdef VIRTUAL
#include "communication_funcs_UDP.h" #include "communication_funcs_UDP.h"
#include "communication_virtual.h"
#endif #endif
#include <string.h> #include <string.h>
@ -25,6 +26,7 @@ extern udpStruct udpDetails;
extern const enum detectorType myDetectorType; extern const enum detectorType myDetectorType;
// Global variable from communication_funcs.c // Global variable from communication_funcs.c
extern int isControlServer;
extern void getMacAddressinString(char* cmac, int size, uint64_t mac); extern void getMacAddressinString(char* cmac, int size, uint64_t mac);
extern void getIpAddressinString(char* cip, uint32_t ip); extern void getIpAddressinString(char* cip, uint32_t ip);
@ -373,6 +375,12 @@ void initStopServer() {
LOG(logERROR, ("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n")); LOG(logERROR, ("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n"));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
#ifdef VIRTUAL
virtual_stop = 0;
if (!isControlServer) {
ComVirtual_setStop(virtual_stop);
}
#endif
} }
@ -394,6 +402,13 @@ void setupDetector() {
clkPhase[i] = 0; clkPhase[i] = 0;
} }
} }
#ifdef VIRTUAL
virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
#endif
ALTERA_PLL_ResetPLL(); ALTERA_PLL_ResetPLL();
resetCore(); resetCore();
resetPeripheral(); resetPeripheral();
@ -545,16 +560,24 @@ int selectStoragecellStart(int pos) {
int setStartingFrameNumber(uint64_t value) { int setStartingFrameNumber(uint64_t value) {
LOG(logINFO, ("Setting starting frame number: %llu\n",(long long unsigned int)value)); LOG(logINFO, ("Setting starting frame number: %llu\n",(long long unsigned int)value));
#ifdef VIRTUAL
setU64BitReg(value, FRAME_NUMBER_LSB_REG, FRAME_NUMBER_MSB_REG);
#else
// decrement is for firmware // decrement is for firmware
setU64BitReg(value - 1, FRAME_NUMBER_LSB_REG, FRAME_NUMBER_MSB_REG); setU64BitReg(value - 1, FRAME_NUMBER_LSB_REG, FRAME_NUMBER_MSB_REG);
// need to set it twice for the firmware to catch // need to set it twice for the firmware to catch
setU64BitReg(value - 1, FRAME_NUMBER_LSB_REG, FRAME_NUMBER_MSB_REG); setU64BitReg(value - 1, FRAME_NUMBER_LSB_REG, FRAME_NUMBER_MSB_REG);
#endif
return OK; return OK;
} }
int getStartingFrameNumber(uint64_t* retval) { int getStartingFrameNumber(uint64_t* retval) {
#ifdef VIRTUAL
*retval = getU64BitReg(FRAME_NUMBER_LSB_REG, FRAME_NUMBER_MSB_REG);
#else
// increment is for firmware // increment is for firmware
*retval = (getU64BitReg(GET_FRAME_NUMBER_LSB_REG, GET_FRAME_NUMBER_MSB_REG) + 1); *retval = (getU64BitReg(GET_FRAME_NUMBER_LSB_REG, GET_FRAME_NUMBER_MSB_REG) + 1);
#endif
return OK; return OK;
} }
@ -921,16 +944,10 @@ int getADC(enum ADCINDEX ind){
int setHighVoltage(int val){ int setHighVoltage(int val){
#ifdef VIRTUAL
if (val >= 0)
highvoltage = val;
return highvoltage;
#endif
// setting hv // setting hv
if (val >= 0) { if (val >= 0) {
LOG(logINFO, ("Setting High voltage: %d V", val)); LOG(logINFO, ("Setting High voltage: %d V", val));
MAX1932_Set(val); MAX1932_Set(&val);
highvoltage = val; highvoltage = val;
} }
return highvoltage; return highvoltage;
@ -1290,7 +1307,9 @@ int powerChip (int on){
bus_w(CHIP_POWER_REG, bus_r(CHIP_POWER_REG) & ~CHIP_POWER_ENABLE_MSK); bus_w(CHIP_POWER_REG, bus_r(CHIP_POWER_REG) & ~CHIP_POWER_ENABLE_MSK);
} }
} }
#ifdef VIRTUAL
return ((bus_r(CHIP_POWER_REG) & CHIP_POWER_ENABLE_MSK) >> CHIP_POWER_ENABLE_OFST);
#endif
return ((bus_r(CHIP_POWER_REG) & CHIP_POWER_STATUS_MSK) >> CHIP_POWER_STATUS_OFST); return ((bus_r(CHIP_POWER_REG) & CHIP_POWER_STATUS_MSK) >> CHIP_POWER_STATUS_OFST);
} }
@ -1629,10 +1648,21 @@ int startStateMachine(){
} }
LOG(logINFOBLUE, ("starting state machine\n")); LOG(logINFOBLUE, ("starting state machine\n"));
virtual_status = 1; virtual_status = 1;
virtual_stop = 0; if (isControlServer) {
ComVirtual_setStatus(virtual_status);
virtual_stop = ComVirtual_getStop();
if (virtual_stop != 0) {
LOG(logERROR, ("Cant start acquisition. "
"Stop server has not updated stop status to 0\n"));
return FAIL;
}
}
if(pthread_create(&pthread_virtual_tid, NULL, &start_timer, NULL)) { if(pthread_create(&pthread_virtual_tid, NULL, &start_timer, NULL)) {
LOG(logERROR, ("Could not start Virtual acquisition thread\n")); LOG(logERROR, ("Could not start Virtual acquisition thread\n"));
virtual_status = 0; virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
return FAIL; return FAIL;
} }
LOG(logINFOGREEN, ("Virtual Acquisition started\n")); LOG(logINFOGREEN, ("Virtual Acquisition started\n"));
@ -1653,6 +1683,10 @@ int startStateMachine(){
#ifdef VIRTUAL #ifdef VIRTUAL
void* start_timer(void* arg) { void* start_timer(void* arg) {
if (!isControlServer) {
return NULL;
}
int numInterfaces = getNumberofUDPInterfaces(); int numInterfaces = getNumberofUDPInterfaces();
int64_t periodNs = getPeriod(); int64_t periodNs = getPeriod();
int numFrames = (getNumFrames() * int numFrames = (getNumFrames() *
@ -1679,13 +1713,18 @@ void* start_timer(void* arg) {
// Send data // Send data
{ {
int frameNr = 0; uint64_t frameNr = 0;
for(frameNr = 0; frameNr != numFrames; ++frameNr ) { getStartingFrameNumber(&frameNr);
int iframes = 0;
for(iframes = 0; iframes != numFrames; ++iframes ) {
usleep(transmissionDelayUs); usleep(transmissionDelayUs);
// update the virtual stop from stop server
virtual_stop = ComVirtual_getStop();
//check if virtual_stop is high //check if virtual_stop is high
if(virtual_stop == 1){ if(virtual_stop == 1){
setStartingFrameNumber(frameNr + iframes + 1);
break; break;
} }
@ -1706,7 +1745,7 @@ void* start_timer(void* arg) {
sls_detector_header* header = (sls_detector_header*)(packetData); sls_detector_header* header = (sls_detector_header*)(packetData);
header->detType = (uint16_t)myDetectorType; header->detType = (uint16_t)myDetectorType;
header->version = SLS_DETECTOR_HEADER_VERSION - 1; header->version = SLS_DETECTOR_HEADER_VERSION - 1;
header->frameNumber = frameNr; header->frameNumber = frameNr + iframes;
header->packetNumber = i; header->packetNumber = i;
header->modId = 0; header->modId = 0;
header->row = detPos[2]; header->row = detPos[2];
@ -1741,18 +1780,19 @@ void* start_timer(void* arg) {
} }
} }
} }
LOG(logINFO, ("Sent frame: %d\n", frameNr)); LOG(logINFO, ("Sent frame: %d\n", iframes));
clock_gettime(CLOCK_REALTIME, &end); clock_gettime(CLOCK_REALTIME, &end);
int64_t timeNs = ((end.tv_sec - begin.tv_sec) * 1E9 + int64_t timeNs = ((end.tv_sec - begin.tv_sec) * 1E9 +
(end.tv_nsec - begin.tv_nsec)); (end.tv_nsec - begin.tv_nsec));
// sleep for (period - exptime) // sleep for (period - exptime)
if (frameNr < numFrames) { // if there is a next frame if (iframes < numFrames) { // if there is a next frame
if (periodNs > timeNs) { if (periodNs > timeNs) {
usleep((periodNs - timeNs)/ 1000); usleep((periodNs - timeNs)/ 1000);
} }
} }
} }
setStartingFrameNumber(frameNr + numFrames);
} }
closeUDPSocket(0); closeUDPSocket(0);
@ -1761,6 +1801,9 @@ void* start_timer(void* arg) {
} }
virtual_status = 0; virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
LOG(logINFOBLUE, ("Finished Acquiring\n")); LOG(logINFOBLUE, ("Finished Acquiring\n"));
return NULL; return NULL;
} }
@ -1769,7 +1812,18 @@ void* start_timer(void* arg) {
int stopStateMachine(){ int stopStateMachine(){
LOG(logINFORED, ("Stopping State Machine\n")); LOG(logINFORED, ("Stopping State Machine\n"));
#ifdef VIRTUAL #ifdef VIRTUAL
virtual_stop = 0; if (!isControlServer) {
virtual_stop = 1;
ComVirtual_setStop(virtual_stop);
// read till status is idle
int tempStatus = 1;
while(tempStatus == 1) {
tempStatus = ComVirtual_getStatus();
}
virtual_stop = 0;
ComVirtual_setStop(virtual_stop);
LOG(logINFO, ("Stopped State Machine\n"));
}
return OK; return OK;
#endif #endif
//stop state machine //stop state machine
@ -1787,7 +1841,10 @@ int stopStateMachine(){
enum runStatus getRunStatus(){ enum runStatus getRunStatus(){
#ifdef VIRTUAL #ifdef VIRTUAL
if(virtual_status == 0){ if (!isControlServer) {
virtual_status = ComVirtual_getStatus();
}
if(virtual_status == 0) {
LOG(logINFOBLUE, ("Status: IDLE\n")); LOG(logINFOBLUE, ("Status: IDLE\n"));
return IDLE; return IDLE;
}else{ }else{
@ -1861,6 +1918,9 @@ void readFrame(int *ret, char *mess){
u_int32_t runBusy() { u_int32_t runBusy() {
#ifdef VIRTUAL #ifdef VIRTUAL
if (!isControlServer) {
virtual_status = ComVirtual_getStatus();
}
return virtual_status; return virtual_status;
#endif #endif
u_int32_t s = (bus_r(STATUS_REG) & RUN_BUSY_MSK); u_int32_t s = (bus_r(STATUS_REG) & RUN_BUSY_MSK);

View File

@ -14,6 +14,7 @@ add_executable(moenchDetectorServer_virtual
../slsDetectorServer/src/MAX1932.c ../slsDetectorServer/src/MAX1932.c
../slsDetectorServer/src/programFpgaBlackfin.c ../slsDetectorServer/src/programFpgaBlackfin.c
../slsDetectorServer/src/readDefaultPattern.c ../slsDetectorServer/src/readDefaultPattern.c
../slsDetectorServer/src/communication_virtual.c
) )
include_directories( include_directories(
@ -31,6 +32,7 @@ target_compile_definitions(moenchDetectorServer_virtual
target_link_libraries(moenchDetectorServer_virtual target_link_libraries(moenchDetectorServer_virtual
PUBLIC pthread rt slsProjectCWarnings PUBLIC pthread rt slsProjectCWarnings
m
) )
set_target_properties(moenchDetectorServer_virtual PROPERTIES set_target_properties(moenchDetectorServer_virtual PROPERTIES

View File

@ -8,6 +8,9 @@
#include "MAX1932.h" // hv #include "MAX1932.h" // hv
#include "ALTERA_PLL.h" // pll #include "ALTERA_PLL.h" // pll
#include "common.h" #include "common.h"
#ifdef VIRTUAL
#include "communication_virtual.h"
#endif
#include <string.h> #include <string.h>
#include <unistd.h> // usleep #include <unistd.h> // usleep
@ -28,6 +31,7 @@ extern uint64_t udpFrameNumber;
extern uint32_t udpPacketNumber; extern uint32_t udpPacketNumber;
// Global variable from communication_funcs.c // Global variable from communication_funcs.c
extern int isControlServer;
extern void getMacAddressinString(char* cmac, int size, uint64_t mac); extern void getMacAddressinString(char* cmac, int size, uint64_t mac);
extern void getIpAddressinString(char* cip, uint32_t ip); extern void getIpAddressinString(char* cip, uint32_t ip);
@ -422,6 +426,12 @@ void initStopServer() {
LOG(logERROR, ("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n")); LOG(logERROR, ("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n"));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
#ifdef VIRTUAL
virtual_stop = 0;
if (!isControlServer) {
ComVirtual_setStop(virtual_stop);
}
#endif
} }
@ -474,6 +484,12 @@ void setupDetector() {
adcEnableMask_1g = 0; adcEnableMask_1g = 0;
adcEnableMask_10g = 0; adcEnableMask_10g = 0;
nSamples = 1; nSamples = 1;
#ifdef VIRTUAL
virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
#endif
ALTERA_PLL_ResetPLLAndReconfiguration(); ALTERA_PLL_ResetPLLAndReconfiguration();
resetCore(); resetCore();
@ -1049,12 +1065,6 @@ void setVLimit(int l) {
int setHighVoltage(int val){ int setHighVoltage(int val){
#ifdef VIRTUAL
if (val >= 0)
highvoltage = val;
return highvoltage;
#endif
// setting hv // setting hv
if (val >= 0) { if (val >= 0) {
LOG(logINFO, ("Setting High voltage: %d V\n", val)); LOG(logINFO, ("Setting High voltage: %d V\n", val));
@ -1063,7 +1073,7 @@ int setHighVoltage(int val){
// switch to external high voltage // switch to external high voltage
bus_w(addr, bus_r(addr) & (~POWER_HV_INTERNAL_SLCT_MSK)); bus_w(addr, bus_r(addr) & (~POWER_HV_INTERNAL_SLCT_MSK));
MAX1932_Set(val); MAX1932_Set(&val);
// switch on internal high voltage, if set // switch on internal high voltage, if set
if (val > 0) if (val > 0)
@ -1821,10 +1831,21 @@ int startStateMachine(){
} }
LOG(logINFOBLUE, ("Starting State Machine\n")); LOG(logINFOBLUE, ("Starting State Machine\n"));
virtual_status = 1; virtual_status = 1;
virtual_stop = 0; if (isControlServer) {
ComVirtual_setStatus(virtual_status);
virtual_stop = ComVirtual_getStop();
if (virtual_stop != 0) {
LOG(logERROR, ("Cant start acquisition. "
"Stop server has not updated stop status to 0\n"));
return FAIL;
}
}
if(pthread_create(&pthread_virtual_tid, NULL, &start_timer, NULL)) { if(pthread_create(&pthread_virtual_tid, NULL, &start_timer, NULL)) {
LOG(logERROR, ("Could not start Virtual acquisition thread\n")); LOG(logERROR, ("Could not start Virtual acquisition thread\n"));
virtual_status = 0; virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
return FAIL; return FAIL;
} }
LOG(logINFOGREEN, ("Virtual Acquisition started\n")); LOG(logINFOGREEN, ("Virtual Acquisition started\n"));
@ -1858,6 +1879,10 @@ int startStateMachine(){
#ifdef VIRTUAL #ifdef VIRTUAL
void* start_timer(void* arg) { void* start_timer(void* arg) {
if (!isControlServer) {
return NULL;
}
int64_t periodNs = getPeriod(); int64_t periodNs = getPeriod();
int numFrames = (getNumFrames() * int numFrames = (getNumFrames() *
getNumTriggers() ); getNumTriggers() );
@ -1884,6 +1909,8 @@ void* start_timer(void* arg) {
// loop over number of frames // loop over number of frames
for(frameNr = 0; frameNr != numFrames; ++frameNr ) { for(frameNr = 0; frameNr != numFrames; ++frameNr ) {
// update the virtual stop from stop server
virtual_stop = ComVirtual_getStop();
//check if virtual_stop is high //check if virtual_stop is high
if(virtual_stop == 1){ if(virtual_stop == 1){
break; break;
@ -1935,6 +1962,9 @@ void* start_timer(void* arg) {
closeUDPSocket(0); closeUDPSocket(0);
virtual_status = 0; virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
LOG(logINFOBLUE, ("Finished Acquiring\n")); LOG(logINFOBLUE, ("Finished Acquiring\n"));
return NULL; return NULL;
} }
@ -1943,7 +1973,18 @@ void* start_timer(void* arg) {
int stopStateMachine(){ int stopStateMachine(){
LOG(logINFORED, ("Stopping State Machine\n")); LOG(logINFORED, ("Stopping State Machine\n"));
#ifdef VIRTUAL #ifdef VIRTUAL
virtual_stop = 0; if (!isControlServer) {
virtual_stop = 1;
ComVirtual_setStop(virtual_stop);
// read till status is idle
int tempStatus = 1;
while(tempStatus == 1) {
tempStatus = ComVirtual_getStatus();
}
virtual_stop = 0;
ComVirtual_setStop(virtual_stop);
LOG(logINFO, ("Stopped State Machine\n"));
}
return OK; return OK;
#endif #endif
//stop state machine //stop state machine
@ -1962,7 +2003,10 @@ int stopStateMachine(){
enum runStatus getRunStatus(){ enum runStatus getRunStatus(){
#ifdef VIRTUAL #ifdef VIRTUAL
if(virtual_status == 0){ if (!isControlServer) {
virtual_status = ComVirtual_getStatus();
}
if(virtual_status == 0) {
LOG(logINFOBLUE, ("Status: IDLE\n")); LOG(logINFOBLUE, ("Status: IDLE\n"));
return IDLE; return IDLE;
}else{ }else{
@ -2197,6 +2241,9 @@ int readFrameFromFifo() {
uint32_t runBusy() { uint32_t runBusy() {
#ifdef VIRTUAL #ifdef VIRTUAL
if (!isControlServer) {
virtual_status = ComVirtual_getStatus();
}
return virtual_status; return virtual_status;
#endif #endif
uint32_t s = (bus_r(STATUS_REG) & STATUS_RN_BSY_MSK); uint32_t s = (bus_r(STATUS_REG) & STATUS_RN_BSY_MSK);

View File

@ -10,6 +10,7 @@ add_executable(mythen3DetectorServer_virtual
../slsDetectorServer/src/LTC2620_Driver.c ../slsDetectorServer/src/LTC2620_Driver.c
../slsDetectorServer/src/ALTERA_PLL_CYCLONE10.c ../slsDetectorServer/src/ALTERA_PLL_CYCLONE10.c
../slsDetectorServer/src/programFpgaNios.c ../slsDetectorServer/src/programFpgaNios.c
../slsDetectorServer/src/communication_virtual.c
) )
include_directories( include_directories(

View File

@ -8,6 +8,7 @@
#include "ALTERA_PLL_CYCLONE10.h" #include "ALTERA_PLL_CYCLONE10.h"
#ifdef VIRTUAL #ifdef VIRTUAL
#include "communication_funcs_UDP.h" #include "communication_funcs_UDP.h"
#include "communication_virtual.h"
#endif #endif
#include <string.h> #include <string.h>
@ -24,6 +25,7 @@ extern udpStruct udpDetails;
extern const enum detectorType myDetectorType; extern const enum detectorType myDetectorType;
// Global variable from communication_funcs.c // Global variable from communication_funcs.c
extern int isControlServer;
extern void getMacAddressinString(char* cmac, int size, uint64_t mac); extern void getMacAddressinString(char* cmac, int size, uint64_t mac);
extern void getIpAddressinString(char* cip, uint32_t ip); extern void getIpAddressinString(char* cip, uint32_t ip);
@ -324,6 +326,12 @@ void initStopServer() {
LOG(logERROR, ("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n")); LOG(logERROR, ("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n"));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
#ifdef VIRTUAL
virtual_stop = 0;
if (!isControlServer) {
ComVirtual_setStop(virtual_stop);
}
#endif
} }
@ -348,8 +356,13 @@ void setupDetector() {
dacValues[i] = 0; dacValues[i] = 0;
} }
} }
#ifdef VIRTUAL
virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
#endif
#ifndef VIRTUAL
// pll defines // pll defines
ALTERA_PLL_C10_SetDefines(REG_OFFSET, BASE_READOUT_PLL, BASE_SYSTEM_PLL, PLL_RESET_REG, PLL_RESET_REG, PLL_RESET_READOUT_MSK, PLL_RESET_SYSTEM_MSK, READOUT_PLL_VCO_FREQ_HZ, SYSTEM_PLL_VCO_FREQ_HZ); ALTERA_PLL_C10_SetDefines(REG_OFFSET, BASE_READOUT_PLL, BASE_SYSTEM_PLL, PLL_RESET_REG, PLL_RESET_REG, PLL_RESET_READOUT_MSK, PLL_RESET_SYSTEM_MSK, READOUT_PLL_VCO_FREQ_HZ, SYSTEM_PLL_VCO_FREQ_HZ);
ALTERA_PLL_C10_ResetPLL(READOUT_PLL); ALTERA_PLL_C10_ResetPLL(READOUT_PLL);
@ -358,7 +371,6 @@ void setupDetector() {
DAC6571_SetDefines(HV_HARD_MAX_VOLTAGE, HV_DRIVER_FILE_NAME); DAC6571_SetDefines(HV_HARD_MAX_VOLTAGE, HV_DRIVER_FILE_NAME);
//dac //dac
LTC2620_D_SetDefines(DAC_MAX_MV, DAC_DRIVER_FILE_NAME, NDAC); LTC2620_D_SetDefines(DAC_MAX_MV, DAC_DRIVER_FILE_NAME, NDAC);
#endif
resetCore(); resetCore();
resetPeripheral(); resetPeripheral();
@ -1114,6 +1126,9 @@ uint64_t getPatternBitMask() {
} }
int checkDetectorType() { int checkDetectorType() {
#ifdef VIRTUAL
return OK;
#endif
LOG(logINFO, ("Checking type of module\n")); LOG(logINFO, ("Checking type of module\n"));
FILE* fd = fopen(TYPE_FILE_NAME, "r"); FILE* fd = fopen(TYPE_FILE_NAME, "r");
if (fd == NULL) { if (fd == NULL) {
@ -1350,10 +1365,21 @@ int startStateMachine(){
LOG(logINFOBLUE, ("Starting State Machine\n")); LOG(logINFOBLUE, ("Starting State Machine\n"));
// set status to running // set status to running
virtual_status = 1; virtual_status = 1;
virtual_stop = 0; if (isControlServer) {
ComVirtual_setStatus(virtual_status);
virtual_stop = ComVirtual_getStop();
if (virtual_stop != 0) {
LOG(logERROR, ("Cant start acquisition. "
"Stop server has not updated stop status to 0\n"));
return FAIL;
}
}
if(pthread_create(&pthread_virtual_tid, NULL, &start_timer, NULL)) { if(pthread_create(&pthread_virtual_tid, NULL, &start_timer, NULL)) {
LOG(logERROR, ("Could not start Virtual acquisition thread\n")); LOG(logERROR, ("Could not start Virtual acquisition thread\n"));
virtual_status = 0; virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
return FAIL; return FAIL;
} }
LOG(logINFOGREEN, ("Virtual Acquisition started\n")); LOG(logINFOGREEN, ("Virtual Acquisition started\n"));
@ -1374,6 +1400,10 @@ int startStateMachine(){
#ifdef VIRTUAL #ifdef VIRTUAL
void* start_timer(void* arg) { void* start_timer(void* arg) {
if (!isControlServer) {
return NULL;
}
int64_t periodNs = getPeriod(); int64_t periodNs = getPeriod();
int numFrames = (getNumFrames() * int numFrames = (getNumFrames() *
getNumTriggers() ); getNumTriggers() );
@ -1400,6 +1430,8 @@ void* start_timer(void* arg) {
// loop over number of frames // loop over number of frames
for (frameNr = 0; frameNr != numFrames; ++frameNr) { for (frameNr = 0; frameNr != numFrames; ++frameNr) {
// update the virtual stop from stop server
virtual_stop = ComVirtual_getStop();
//check if virtual_stop is high //check if virtual_stop is high
if(virtual_stop == 1){ if(virtual_stop == 1){
break; break;
@ -1454,6 +1486,9 @@ void* start_timer(void* arg) {
closeUDPSocket(0); closeUDPSocket(0);
virtual_status = 0; virtual_status = 0;
if (isControlServer) {
ComVirtual_setStatus(virtual_status);
}
LOG(logINFOBLUE, ("Finished Acquiring\n")); LOG(logINFOBLUE, ("Finished Acquiring\n"));
return NULL; return NULL;
} }
@ -1463,7 +1498,18 @@ void* start_timer(void* arg) {
int stopStateMachine(){ int stopStateMachine(){
LOG(logINFORED, ("Stopping State Machine\n")); LOG(logINFORED, ("Stopping State Machine\n"));
#ifdef VIRTUAL #ifdef VIRTUAL
virtual_stop = 0; if (!isControlServer) {
virtual_stop = 1;
ComVirtual_setStop(virtual_stop);
// read till status is idle
int tempStatus = 1;
while(tempStatus == 1) {
tempStatus = ComVirtual_getStatus();
}
virtual_stop = 0;
ComVirtual_setStop(virtual_stop);
LOG(logINFO, ("Stopped State Machine\n"));
}
return OK; return OK;
#endif #endif
//stop state machine //stop state machine
@ -1474,10 +1520,13 @@ int stopStateMachine(){
enum runStatus getRunStatus(){ enum runStatus getRunStatus(){
#ifdef VIRTUAL #ifdef VIRTUAL
if(virtual_status == 0){ if (!isControlServer) {
virtual_status = ComVirtual_getStatus();
}
if(virtual_status == 0) {
LOG(logINFOBLUE, ("Status: IDLE\n")); LOG(logINFOBLUE, ("Status: IDLE\n"));
return IDLE; return IDLE;
}else{ } else{
LOG(logINFOBLUE, ("Status: RUNNING\n")); LOG(logINFOBLUE, ("Status: RUNNING\n"));
return RUNNING; return RUNNING;
} }
@ -1549,6 +1598,9 @@ void readFrame(int *ret, char *mess) {
u_int32_t runBusy() { u_int32_t runBusy() {
#ifdef VIRTUAL #ifdef VIRTUAL
if (!isControlServer) {
virtual_status = ComVirtual_getStatus();
}
return virtual_status; return virtual_status;
#endif #endif
u_int32_t s = (bus_r(PAT_STATUS_REG) & PAT_STATUS_RUN_BUSY_MSK); u_int32_t s = (bus_r(PAT_STATUS_REG) & PAT_STATUS_RUN_BUSY_MSK);

View File

@ -21,11 +21,11 @@ void MAX1932_SetDefines(uint32_t reg, uint32_t cmsk, uint32_t clkmsk, uint32_t d
void MAX1932_Disable(); void MAX1932_Disable();
/** /**
* Set value * Set value (value is updated to correct range)
* @param val value to set * @param val pointer to value to set
* @return OK or FAIL * @return OK or FAIL
*/ */
int MAX1932_Set (int val) ; int MAX1932_Set (int* val) ;

View File

@ -11,6 +11,13 @@ typedef enum{
OTHER OTHER
}intType; }intType;
// communciate with stop server
#ifdef VIRTUAL
#define FILE_STATUS "/tmp/Sls_virtual_server_status_"
#define FILE_STOP "/tmp/Sls_virtual_server_stop_"
#define FD_STATUS 0
#define FD_STOP 1
#endif
int bindSocket(unsigned short int port_number); int bindSocket(unsigned short int port_number);
int acceptConnection(int socketDescriptor); int acceptConnection(int socketDescriptor);
@ -45,12 +52,11 @@ int Server_VerifyLock();
* Server sends result to client (also set ret to force_update if different clients) * Server sends result to client (also set ret to force_update if different clients)
* @param fileDes file descriptor for the socket * @param fileDes file descriptor for the socket
* @param itype 32 or 64 or others to determine to swap data from big endian to little endian * @param itype 32 or 64 or others to determine to swap data from big endian to little endian
* @param update 1 if one must update if different clients, else 0
* @param retval pointer to result * @param retval pointer to result
* @param retvalSize size of result * @param retvalSize size of result
* @returns result of operation * @returns result of operation
*/ */
int Server_SendResult(int fileDes, intType itype, int update, void* retval, int retvalSize); int Server_SendResult(int fileDes, intType itype, void* retval, int retvalSize);
/** /**
* Convert mac address from integer to char array * Convert mac address from integer to char array

View File

@ -0,0 +1,14 @@
#pragma once
#ifdef VIRTUAL
// communciate between control and stop server
int ComVirtual_createFiles(const int port);
void ComVirtual_setFileNames(const int port);
void ComVirtual_setStatus(int value);
int ComVirtual_getStatus();
void ComVirtual_setStop(int value);
int ComVirtual_getStop();
int ComVirtual_writeToFile(int value, const char* fname, const char* serverName);
int ComVirtual_readFromFile(int* value, const char* fname, const char* serverName);
#endif

View File

@ -206,8 +206,8 @@ int64_t getBurstPeriod();
#ifdef EIGERD #ifdef EIGERD
int setSubExpTime(int64_t val); int setSubExpTime(int64_t val);
int64_t getSubExpTime(); int64_t getSubExpTime();
int setDeadTime(int64_t val); int setSubDeadTime(int64_t val);
int64_t getDeadTime(); int64_t getSubDeadTime();
int64_t getMeasuredPeriod(); int64_t getMeasuredPeriod();
int64_t getMeasuredSubPeriod(); int64_t getMeasuredSubPeriod();
#endif #endif
@ -413,7 +413,9 @@ int setCounterBit(int val);
int pulsePixel(int n, int x, int y); int pulsePixel(int n, int x, int y);
int pulsePixelNMove(int n, int x, int y); int pulsePixelNMove(int n, int x, int y);
int pulseChip(int n); int pulseChip(int n);
int64_t setRateCorrection(int64_t custom_tau_in_nsec); int updateRateCorrection(char* mess);
int validateAndSetRateCorrection(int64_t tau_ns, char* mess);
int setRateCorrection(int64_t custom_tau_in_nsec);
int getRateCorrectionEnable(); int getRateCorrectionEnable();
int getDefaultSettingsTau_in_nsec(); int getDefaultSettingsTau_in_nsec();
void setDefaultSettingsTau_in_nsec(int t); void setDefaultSettingsTau_in_nsec(int t);

View File

@ -88,8 +88,6 @@ int exit_server(int);
int lock_server(int); int lock_server(int);
int get_last_client_ip(int); int get_last_client_ip(int);
int set_port(int); int set_port(int);
int update_client(int);
int send_update(int);
int calibrate_pedestal(int); int calibrate_pedestal(int);
int enable_ten_giga(int); int enable_ten_giga(int);
int set_all_trimbits(int); int set_all_trimbits(int);
@ -217,3 +215,6 @@ int set_current_source(int);
int get_timing_source(int); int get_timing_source(int);
int set_timing_source(int); int set_timing_source(int);
int get_num_channels(int); int get_num_channels(int);
int update_rate_correction(int);
int get_receiver_parameters(int);

View File

@ -42,9 +42,7 @@ int ASIC_Driver_Set (int index, int length, char* buffer) {
LOG(logDEBUG2, ("\t]\n")); LOG(logDEBUG2, ("\t]\n"));
} }
#ifdef VIRTUAL #ifndef VIRTUAL
return OK;
#endif
int fd=open(fname, O_RDWR); int fd=open(fname, O_RDWR);
if (fd == -1) { if (fd == -1) {
LOG(logERROR, ("Could not open file %s for writing to control ASIC (%d)\n", fname, index)); LOG(logERROR, ("Could not open file %s for writing to control ASIC (%d)\n", fname, index));
@ -66,6 +64,7 @@ int ASIC_Driver_Set (int index, int length, char* buffer) {
return FAIL; return FAIL;
} }
close(fd); close(fd);
#endif
return OK; return OK;
} }

View File

@ -36,6 +36,7 @@ int DAC6571_Set (int val) {
LOG(logINFO, ("\t%dV (dacval %d)\n", val, dacvalue)); LOG(logINFO, ("\t%dV (dacval %d)\n", val, dacvalue));
#ifndef VIRTUAL
//open file //open file
FILE* fd=fopen(DAC6571_DriverFileName,"w"); FILE* fd=fopen(DAC6571_DriverFileName,"w");
if (fd==NULL) { if (fd==NULL) {
@ -45,6 +46,7 @@ int DAC6571_Set (int val) {
//convert to string, add 0 and write to file //convert to string, add 0 and write to file
fprintf(fd, "%d\n", dacvalue); fprintf(fd, "%d\n", dacvalue);
fclose(fd); fclose(fd);
#endif
return OK; return OK;
} }

View File

@ -72,6 +72,8 @@ int LTC2620_D_SetDACValue (int dacnum, int val, int mV, char* dacname, int* dacv
if ( (*dacval >= 0) || (*dacval == LTC2620_D_PWR_DOWN_VAL)) { if ( (*dacval >= 0) || (*dacval == LTC2620_D_PWR_DOWN_VAL)) {
LOG(logINFO, ("Setting DAC %2d [%-12s] : %d dac (%d mV)\n",dacnum, dacname, *dacval, dacmV)); LOG(logINFO, ("Setting DAC %2d [%-12s] : %d dac (%d mV)\n",dacnum, dacname, *dacval, dacmV));
#ifndef VIRTUAL
char fname[MAX_STR_LENGTH]; char fname[MAX_STR_LENGTH];
strcpy(fname, LTC2620_D_DriverFileName); strcpy(fname, LTC2620_D_DriverFileName);
char temp[20]; char temp[20];
@ -89,6 +91,8 @@ int LTC2620_D_SetDACValue (int dacnum, int val, int mV, char* dacname, int* dacv
//convert to string, add 0 and write to file //convert to string, add 0 and write to file
fprintf(fd, "%d\n", *dacval); fprintf(fd, "%d\n", *dacval);
fclose(fd); fclose(fd);
#endif
} }
return OK; return OK;
} }

View File

@ -43,33 +43,33 @@ void MAX1932_Disable() {
& ~(MAX1932_DigMask)); & ~(MAX1932_DigMask));
} }
int MAX1932_Set (int val) { int MAX1932_Set (int* val) {
LOG(logDEBUG1, ("Setting high voltage to %d\n", val)); LOG(logDEBUG1, ("Setting high voltage to %d\n", *val));
if (val < 0) if (*val < 0)
return FAIL; return FAIL;
int dacvalue = 0; int dacvalue = 0;
// limit values (normally < 60 => 0 (off)) // limit values (normally < 60 => 0 (off))
if (val < MAX1932_MinVoltage) { if (*val < MAX1932_MinVoltage) {
dacvalue = MAX1932_POWER_OFF_DAC_VAL; dacvalue = MAX1932_POWER_OFF_DAC_VAL;
val = 0; *val = 0;
} }
// limit values (normally > 200 => 0x1 (max)) // limit values (normally > 200 => 0x1 (max))
else if (val > MAX1932_MaxVoltage) { else if (*val > MAX1932_MaxVoltage) {
dacvalue = MAX1932_MAX_DAC_VAL; dacvalue = MAX1932_MAX_DAC_VAL;
val = MAX1932_MaxVoltage; *val = MAX1932_MaxVoltage;
} }
// convert value // convert value
else { else {
// no failure in conversion as limits handled (range from 0x1 to 0xFF) // no failure in conversion as limits handled (range from 0x1 to 0xFF)
ConvertToDifferentRange(MAX1932_MinVoltage, MAX1932_MaxVoltage, ConvertToDifferentRange(MAX1932_MinVoltage, MAX1932_MaxVoltage,
MAX1932_MIN_DAC_VAL, MAX1932_MAX_DAC_VAL, MAX1932_MIN_DAC_VAL, MAX1932_MAX_DAC_VAL,
val, &dacvalue); *val, &dacvalue);
dacvalue &= MAX1932_HV_DATA_MSK; dacvalue &= MAX1932_HV_DATA_MSK;
} }
LOG(logINFO, ("\t%dV (dacval %d)\n", val, dacvalue)); LOG(logINFO, ("\t%dV (dacval %d)\n", *val, dacvalue));
serializeToSPI(MAX1932_Reg, dacvalue, MAX1932_CsMask, MAX1932_HV_NUMBITS, serializeToSPI(MAX1932_Reg, dacvalue, MAX1932_CsMask, MAX1932_HV_NUMBITS,
MAX1932_ClkMask, MAX1932_DigMask, MAX1932_DigOffset, 0); MAX1932_ClkMask, MAX1932_DigMask, MAX1932_DigOffset, 0);
return OK; return OK;

View File

@ -577,11 +577,7 @@ int Server_VerifyLock() {
} }
int Server_SendResult(int fileDes, intType itype, int update, void* retval, int retvalSize) { int Server_SendResult(int fileDes, intType itype, void* retval, int retvalSize) {
// update if different clients (ret can be ok or acquisition finished), not fail to not overwrite e message
if (update && isControlServer && ret != FAIL && differentClients)
ret = FORCE_UPDATE;
// send success of operation // send success of operation
int ret1 = ret; int ret1 = ret;

View File

@ -37,7 +37,7 @@ int setUDPDestinationDetails(int index, const char* ip, unsigned short int port)
// convert ip to internet address // convert ip to internet address
struct addrinfo hints; struct addrinfo hints;
memset(&hints, 0, sizeof(hints)); memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC; hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM; hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = 0; hints.ai_flags = 0;
hints.ai_protocol = 0; hints.ai_protocol = 0;
@ -83,19 +83,16 @@ int createUDPSocket(int index) {
LOG(logINFO, ("Udp client socket created for server (port %d, ip:%s)\n", LOG(logINFO, ("Udp client socket created for server (port %d, ip:%s)\n",
udpDestinationPort[index], udpDestinationIp[index])); udpDestinationPort[index], udpDestinationIp[index]));
// Using connect expects that the receiver (udp server) exists to listen to these packets
// connecting allows to use "send/write" instead of "sendto", avoiding checking for server address for each packet // connecting allows to use "send/write" instead of "sendto", avoiding checking for server address for each packet
// using write without a connect will end in segv // using write without a connect will end in segv
if (connect(udpSockfd[index],udpServerAddrInfo[index]->ai_addr, udpServerAddrInfo[index]->ai_addrlen)==-1) {
LOG(logERROR, ("Could not connect to UDP server at ip:%s, port:%d. (Error code:%d, %s)\n",
udpDestinationIp[index], udpDestinationPort[index], errno, gai_strerror(errno)));
}
LOG(logINFO, ("Udp client socket connected\n", LOG(logINFO, ("Udp client socket connected\n",
udpDestinationPort[index], udpDestinationIp[index])); udpDestinationPort[index], udpDestinationIp[index]));
return OK; return OK;
} }
int sendUDPPacket(int index, const char* buf, int length) { int sendUDPPacket(int index, const char* buf, int length) {
int n = write(udpSockfd[index], buf, length); int n = sendto(udpSockfd[index], buf, length, 0, udpServerAddrInfo[index]->ai_addr, udpServerAddrInfo[index]->ai_addrlen);
// udp sends atomically, no need to handle partial data // udp sends atomically, no need to handle partial data
if (n == -1) { if (n == -1) {
LOG(logERROR, ("Could not send udp packet for socket %d. (Error code:%d, %s)\n", LOG(logERROR, ("Could not send udp packet for socket %d. (Error code:%d, %s)\n",

View File

@ -0,0 +1,120 @@
#ifdef VIRTUAL
#include "communication_virtual.h"
#include "clogger.h"
#include <string.h>
#include <unistd.h> // usleep
#define FILE_STATUS "/tmp/sls_virtual_server_status_"
#define FILE_STOP "/tmp/sls_virtual_server_stop_"
#define FD_STATUS 0
#define FD_STOP 1
#define FILE_NAME_LENGTH 1000
FILE* fd[2] = {NULL, NULL};
char fnameStatus[FILE_NAME_LENGTH];
char fnameStop[FILE_NAME_LENGTH];
int portNumber = 0;
int ComVirtual_createFiles(const int port) {
portNumber = port;
// control server writign status file
memset(fnameStatus, 0, FILE_NAME_LENGTH);
sprintf(fnameStatus, "%s%d", FILE_STATUS, port);
FILE* fd = NULL;
if (NULL == (fd = fopen(fnameStatus, "w"))) {
LOG(logERROR, ("Could not open the file %s for virtual communication\n",
fnameStatus));
return 0;
}
fclose(fd);
LOG(logINFOBLUE, ("Created status file %s\n", fnameStatus));
// stop server writing stop file
memset(fnameStop, 0, FILE_NAME_LENGTH);
sprintf(fnameStop, "%s%d", FILE_STOP, port);
if (NULL == (fd = fopen(fnameStop, "w"))) {
LOG(logERROR, ("Could not open the file %s for virtual communication\n",
fnameStop));
return 0;
}
fclose(fd);
LOG(logINFOBLUE, ("Created stop file %s\n", fnameStop));
return 1;
}
void ComVirtual_setFileNames(const int port) {
portNumber = port;
memset(fnameStatus, 0, FILE_NAME_LENGTH);
memset(fnameStop, 0, FILE_NAME_LENGTH);
sprintf(fnameStatus, "%s%d", FILE_STATUS, port);
sprintf(fnameStop, "%s%d", FILE_STOP, port);
}
void ComVirtual_setStatus(int value) {
while (!ComVirtual_writeToFile(value, fnameStatus, "Control")) {
usleep(100);
}
}
int ComVirtual_getStatus() {
int retval = 0;
while (!ComVirtual_readFromFile(&retval, fnameStatus, "Stop")) {
usleep(100);
}
return retval;
}
void ComVirtual_setStop(int value) {
while (!ComVirtual_writeToFile(value, fnameStop, "Stop")) {
usleep(100);
}
}
int ComVirtual_getStop() {
int retval = 0;
while (!ComVirtual_readFromFile(&retval, fnameStop, "Control")) {
usleep(100);
}
return retval;
}
int ComVirtual_writeToFile(int value, const char* fname, const char* serverName) {
FILE* fd = NULL;
if (NULL == (fd = fopen(fname, "w"))) {
LOG(logERROR, ("Vritual %s Server [%d] could not open "
"the file %s for writing\n",
serverName, portNumber, fname));
return 0;
}
while (fwrite(&value, sizeof(value), 1, fd) < 1) {
LOG(logERROR, ("Vritual %s Server [%d] could not write "
"to file %s\n",
serverName, portNumber, fname));
return 0;
}
fclose(fd);
return 1;
}
int ComVirtual_readFromFile(int* value, const char* fname, const char* serverName) {
FILE* fd = NULL;
if (NULL == (fd = fopen(fname, "r"))) {
LOG(logERROR, ("Vritual %s Server [%d] could not open "
"the file %s for reading\n",
serverName, portNumber, fname));
return 0;
}
while (fread(value, sizeof(int), 1, fd) < 1) {
LOG(logERROR, ("Vritual %s Server [%d] could not read "
"from file %s\n",
serverName, portNumber, fname));
return 0;
}
fclose(fd);
return 1;
}
#endif

View File

@ -7,6 +7,9 @@
#include "slsDetectorServer_funcs.h" #include "slsDetectorServer_funcs.h"
#include "slsDetectorServer_defs.h" #include "slsDetectorServer_defs.h"
#include "versionAPI.h" #include "versionAPI.h"
#ifdef VIRTUAL
#include "communication_virtual.h"
#endif
#include <signal.h> #include <signal.h>
#include <string.h> #include <string.h>
@ -31,7 +34,8 @@ void error(char *msg){
perror(msg); perror(msg);
} }
int main(int argc, char *argv[]){ int main(int argc, char *argv[]) {
// print version // print version
if (argc > 1 && !strcasecmp(argv[1], "-version")) { if (argc > 1 && !strcasecmp(argv[1], "-version")) {
int version = 0; int version = 0;
@ -50,8 +54,9 @@ int main(int argc, char *argv[]){
} }
int portno = DEFAULT_PORTNO; int portno = DEFAULT_PORTNO;
int retval = OK; isControlServer = 1;
int fd = 0; debugflag = 0;
checkModuleFlag = 1;
// if socket crash, ignores SISPIPE, prevents global signal handler // if socket crash, ignores SISPIPE, prevents global signal handler
// subsequent read/write to socket gives error - must handle locally // subsequent read/write to socket gives error - must handle locally
@ -100,16 +105,19 @@ int main(int argc, char *argv[]){
} }
} }
#ifdef STOP_SERVER // control server
char cmd[MAX_STR_LENGTH];
memset(cmd, 0, MAX_STR_LENGTH);
#endif
if (isControlServer) { if (isControlServer) {
LOG(logINFO, ("Opening control server on port %d \n", portno));
#ifdef STOP_SERVER #ifdef STOP_SERVER
// start stop server process
char cmd[MAX_STR_LENGTH];
memset(cmd, 0, MAX_STR_LENGTH);
{ {
int i; int i;
for (i = 0; i < argc; ++i) { for (i = 0; i < argc; ++i) {
if (!strcasecmp(argv[i], "-port")) {
i +=2;
continue;
}
if (i > 0) { if (i > 0) {
strcat(cmd, " "); strcat(cmd, " ");
} }
@ -123,31 +131,42 @@ int main(int argc, char *argv[]){
LOG(logDEBUG1, ("Command to start stop server:%s\n", cmd)); LOG(logDEBUG1, ("Command to start stop server:%s\n", cmd));
system(cmd); system(cmd);
} }
LOG(logINFOBLUE, ("Control Server [%d]\n", portno));
#ifdef VIRTUAL
// creating files for virtual servers to communicate with each other
if (!ComVirtual_createFiles(portno)) {
return -1;
}
#endif
#endif #endif
} else {
LOG(logINFO,("Opening stop server on port %d \n", portno));
} }
// stop server
else {
LOG(logINFOBLUE, ("Stop Server [%d]\n", portno));
#ifdef VIRTUAL
ComVirtual_setFileNames(portno - 1);
#endif
}
init_detector(); init_detector();
// bind socket
{ // bind socket sockfd = bindSocket(portno);
sockfd = bindSocket(portno); if (ret == FAIL)
if (ret == FAIL) return -1;
return -1;
}
// assign function table // assign function table
function_table(); function_table();
if (isControlServer) { if (isControlServer) {
LOG(logINFOBLUE, ("Control Server Ready...\n\n")); LOG(logINFOBLUE, ("Control Server Ready...\n\n"));
} else { } else {
LOG(logINFO, ("Stop Server Ready...\n\n")); LOG(logINFOBLUE, ("Stop Server Ready...\n\n"));
} }
// waits for connection // waits for connection
int retval = OK;
while(retval != GOODBYE && retval != REBOOT) { while(retval != GOODBYE && retval != REBOOT) {
fd = acceptConnection(sockfd); int fd = acceptConnection(sockfd);
if (fd > 0) { if (fd > 0) {
retval = decode_function(fd); retval = decode_function(fd);
closeConnection(fd); closeConnection(fd);

View File

@ -15,9 +15,8 @@ add_library(slsDetectorShared SHARED
${HEADERS} ${HEADERS}
) )
# Do we have link time optimization?
check_ipo_supported(RESULT LTO_AVAILABLE) if(SLS_LTO_AVAILABLE)
if(LTO_AVAILABLE)
set_property(TARGET slsDetectorShared PROPERTY INTERPROCEDURAL_OPTIMIZATION True) set_property(TARGET slsDetectorShared PROPERTY INTERPROCEDURAL_OPTIMIZATION True)
endif() endif()

View File

@ -402,37 +402,45 @@ std::string CmdProxy::Adcphase(int action) {
"resets adcphase and sets it to previous values.\n\t[Gotthard] " "resets adcphase and sets it to previous values.\n\t[Gotthard] "
"Relative phase shift" "Relative phase shift"
<< '\n'; << '\n';
} else if (action == defs::GET_ACTION) {
Result<int> t;
if (args.empty()) {
t = det->getADCPhase({det_id});
os << OutString(t) << '\n';
} else if (args.size() == 1) {
if (args[0] != "deg") {
throw sls::RuntimeError("Unknown adcphase argument " + args[0] +
". Did you mean deg?");
}
t = det->getADCPhaseInDegrees({det_id});
os << OutString(t) << " deg\n";
} else {
WrongNumberOfParameters(0);
}
} else if (action == defs::PUT_ACTION) {
if (args.size() == 1) {
det->setADCPhase(StringTo<int>(args[0]), {det_id});
os << args.front() << '\n';
} else if (args.size() == 2) {
if (args[1] != "deg") {
throw sls::RuntimeError("Unknown adcphase 2nd argument " +
args[1] + ". Did you mean deg?");
}
det->setADCPhaseInDegrees(StringTo<int>(args[0]), {det_id});
os << args[0] << args[1] << '\n';
} else {
WrongNumberOfParameters(1);
}
} else { } else {
throw sls::RuntimeError("Unknown action"); auto det_type = det->getDetectorType().squash(defs::GENERIC);
if (det_type == defs::EIGER ||
det_type == defs::MYTHEN3 ||
det_type == defs::GOTTHARD2) {
throw sls::RuntimeError("adcphase not implemented for this detector");
}
if (action == defs::GET_ACTION) {
Result<int> t;
if (args.empty()) {
t = det->getADCPhase({det_id});
os << OutString(t) << '\n';
} else if (args.size() == 1) {
if (args[0] != "deg") {
throw sls::RuntimeError("Unknown adcphase argument " + args[0] +
". Did you mean deg? ");
}
t = det->getADCPhaseInDegrees({det_id});
os << OutString(t) << " deg\n";
} else {
WrongNumberOfParameters(0);
}
} else if (action == defs::PUT_ACTION) {
if (args.size() == 1) {
det->setADCPhase(StringTo<int>(args[0]), {det_id} );
os << args.front() << '\n';
} else if (args.size() == 2) {
if (args[1] != "deg") {
throw sls::RuntimeError("Unknown adcphase 2nd argument " +
args[1] + ". Did you mean deg?");
}
det->setADCPhaseInDegrees(StringTo<int>(args[0]) , {det_id});
os << args[0] << " " << args[1] << '\n';
} else {
WrongNumberOfParameters(1);
}
} else {
throw sls::RuntimeError("Unknown action");
}
} }
return os.str(); return os.str();
} }
@ -446,37 +454,45 @@ std::string CmdProxy::Dbitphase(int action) {
"shift in degrees. \n\t[Ctb]Changing dbitclk also resets dbitphase and " "shift in degrees. \n\t[Ctb]Changing dbitclk also resets dbitphase and "
"sets to previous values." "sets to previous values."
<< '\n'; << '\n';
} else if (action == defs::GET_ACTION) {
Result<int> t;
if (args.empty()) {
t = det->getDBITPhase({det_id});
os << OutString(t) << '\n';
} else if (args.size() == 1) {
if (args[0] != "deg") {
throw sls::RuntimeError("Unknown dbitphase argument " +
args[0] + ". Did you mean deg?");
}
t = det->getDBITPhaseInDegrees({det_id});
os << OutString(t) << " deg\n";
} else {
WrongNumberOfParameters(0);
}
} else if (action == defs::PUT_ACTION) {
if (args.size() == 1) {
det->setDBITPhase(StringTo<int>(args[0]), {det_id});
os << args.front() << '\n';
} else if (args.size() == 2) {
if (args[1] != "deg") {
throw sls::RuntimeError("Unknown dbitphase 2nd argument " +
args[1] + ". Did you mean deg?");
}
det->setDBITPhaseInDegrees(StringTo<int>(args[0]), {det_id});
os << args[0] << args[1] << '\n';
} else {
WrongNumberOfParameters(1);
}
} else { } else {
throw sls::RuntimeError("Unknown action"); auto det_type = det->getDetectorType().squash(defs::GENERIC);
if (det_type == defs::EIGER ||
det_type == defs::MYTHEN3 ||
det_type == defs::GOTTHARD2) {
throw sls::RuntimeError("dbitphase not implemented for this detector");
}
if (action == defs::GET_ACTION) {
Result<int> t;
if (args.empty()) {
t = det->getDBITPhase({det_id});
os << OutString(t) << '\n';
} else if (args.size() == 1) {
if (args[0] != "deg") {
throw sls::RuntimeError("Unknown dbitphase argument " +
args[0] + ". Did you mean deg? ");
}
t = det->getDBITPhaseInDegrees({det_id});
os << OutString(t) << " deg\n";
} else {
WrongNumberOfParameters(0);
}
} else if (action == defs::PUT_ACTION) {
if (args.size() == 1) {
det->setDBITPhase(StringTo<int>(args[0]), {det_id});
os << args.front() << '\n';
} else if (args.size() == 2) {
if (args[1] != "deg") {
throw sls::RuntimeError("Unknown dbitphase 2nd argument " +
args[1] + ". Did you mean deg? ");
}
det->setDBITPhaseInDegrees(StringTo<int>(args[0]), {det_id} );
os << args[0] << " " << args[1] << '\n';
} else {
WrongNumberOfParameters(1);
}
} else {
throw sls::RuntimeError("Unknown action");
}
} }
return os.str(); return os.str();
} }
@ -538,7 +554,7 @@ std::string CmdProxy::ClockPhase(int action) {
} }
auto t = auto t =
det->getClockPhaseinDegrees(StringTo<int>(args[0]), {det_id}); det->getClockPhaseinDegrees(StringTo<int>(args[0]), {det_id});
os << OutString(t) << '\n'; os << OutString(t) << " deg\n";
} else { } else {
WrongNumberOfParameters(1); WrongNumberOfParameters(1);
} }
@ -554,7 +570,7 @@ std::string CmdProxy::ClockPhase(int action) {
} }
det->setClockPhaseinDegrees(StringTo<int>(args[0]), det->setClockPhaseinDegrees(StringTo<int>(args[0]),
StringTo<int>(args[1]), {det_id}); StringTo<int>(args[1]), {det_id});
os << args[1] << '\n'; os << args[1] << " " << args[2] << '\n';
} else { } else {
WrongNumberOfParameters(1); WrongNumberOfParameters(1);
} }
@ -769,6 +785,47 @@ std::vector<std::string> CmdProxy::DacCommands() {
} }
/* acquisition */ /* acquisition */
std::string CmdProxy::ReceiverStatus(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "running, idle]\n\tReceiver listener status."
<< '\n';
} else if (action == defs::GET_ACTION) {
if (args.size() != 0) {
WrongNumberOfParameters(0);
}
auto t = det->getReceiverStatus({det_id});
os << OutString(t) << '\n';
} else if (action == defs::PUT_ACTION) {
throw sls::RuntimeError("Cannot put. Did you mean to use command 'rx_start' or 'rx_stop'?");
} else {
throw sls::RuntimeError("Unknown action");
}
return os.str();
}
std::string CmdProxy::DetectorStatus(int action) {
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
os << "[running, error, transmitting, finished, waiting, idle]\n\tDetector status."
<< '\n';
} else if (action == defs::GET_ACTION) {
if (args.size() != 0) {
WrongNumberOfParameters(0);
}
auto t = det->getDetectorStatus({det_id});
os << OutString(t) << '\n';
} else if (action == defs::PUT_ACTION) {
throw sls::RuntimeError("Cannot put. Did you mean to use command 'start' or 'stop'?");
} else {
throw sls::RuntimeError("Unknown action");
}
return os.str();
}
/* Network Configuration (Detector<->Receiver) */ /* Network Configuration (Detector<->Receiver) */
std::string CmdProxy::UDPDestinationIP(int action) { std::string CmdProxy::UDPDestinationIP(int action) {

View File

@ -691,8 +691,8 @@ class CmdProxy {
{"rx_stop", &CmdProxy::rx_stop}, {"rx_stop", &CmdProxy::rx_stop},
{"start", &CmdProxy::start}, {"start", &CmdProxy::start},
{"stop", &CmdProxy::stop}, {"stop", &CmdProxy::stop},
{"rx_status", &CmdProxy::rx_status}, {"rx_status", &CmdProxy::ReceiverStatus},
{"status", &CmdProxy::status}, {"status", &CmdProxy::DetectorStatus},
{"rx_framescaught", &CmdProxy::rx_framescaught}, {"rx_framescaught", &CmdProxy::rx_framescaught},
{"rx_missingpackets", &CmdProxy::rx_missingpackets}, {"rx_missingpackets", &CmdProxy::rx_missingpackets},
{"startingfnum", &CmdProxy::startingfnum}, {"startingfnum", &CmdProxy::startingfnum},
@ -934,6 +934,8 @@ class CmdProxy {
std::string DacValues(int action); std::string DacValues(int action);
std::vector<std::string> DacCommands(); std::vector<std::string> DacCommands();
/* acquisition */ /* acquisition */
std::string ReceiverStatus(int action);
std::string DetectorStatus(int action);
/* Network Configuration (Detector<->Receiver) */ /* Network Configuration (Detector<->Receiver) */
std::string UDPDestinationIP(int action); std::string UDPDestinationIP(int action);
std::string UDPDestinationIP2(int action); std::string UDPDestinationIP2(int action);
@ -1363,12 +1365,6 @@ class CmdProxy {
EXECUTE_SET_COMMAND_NOID(stop, stopDetector, EXECUTE_SET_COMMAND_NOID(stop, stopDetector,
"\n\tStops detector state machine."); "\n\tStops detector state machine.");
GET_COMMAND(rx_status, getReceiverStatus,
"running, idle]\n\tReceiver listener status.");
GET_COMMAND(status, getDetectorStatus,
"[running, error, transmitting, finished, waiting, idle]\n\tDetector status.");
GET_COMMAND(rx_framescaught, getFramesCaught, GET_COMMAND(rx_framescaught, getFramesCaught,
"\n\tNumber of frames caught by receiver."); "\n\tNumber of frames caught by receiver.");

View File

@ -234,8 +234,7 @@ Result<ns> Detector::getPeriodLeft(Positions pos) const {
} }
Result<defs::timingMode> Detector::getTimingMode(Positions pos) const { Result<defs::timingMode> Detector::getTimingMode(Positions pos) const {
return pimpl->Parallel(&Module::setTimingMode, pos, return pimpl->Parallel(&Module::getTimingMode, pos);
defs::GET_TIMING_MODE);
} }
void Detector::setTimingMode(defs::timingMode value, Positions pos) { void Detector::setTimingMode(defs::timingMode value, Positions pos) {
@ -923,7 +922,7 @@ void Detector::setClientZmqIp(const IpAddr ip, Positions pos) {
// Eiger Specific // Eiger Specific
Result<int> Detector::getDynamicRange(Positions pos) const { Result<int> Detector::getDynamicRange(Positions pos) const {
return pimpl->Parallel(&Module::setDynamicRange, pos, -1); return pimpl->Parallel(&Module::getDynamicRange, pos);
} }
void Detector::setDynamicRange(int value) { void Detector::setDynamicRange(int value) {

View File

@ -462,6 +462,7 @@ void DetectorImpl::readFrameFromReceiver() {
std::string currentFileName; std::string currentFileName;
uint64_t currentAcquisitionIndex = -1, currentFrameIndex = -1, uint64_t currentAcquisitionIndex = -1, currentFrameIndex = -1,
currentFileIndex = -1; currentFileIndex = -1;
int currentProgress = -1;
uint32_t currentSubFrameIndex = -1, coordX = -1, coordY = -1, uint32_t currentSubFrameIndex = -1, coordX = -1, coordY = -1,
flippedDataX = -1; flippedDataX = -1;
@ -540,6 +541,7 @@ void DetectorImpl::readFrameFromReceiver() {
currentFileName = zHeader.fname; currentFileName = zHeader.fname;
currentAcquisitionIndex = zHeader.acqIndex; currentAcquisitionIndex = zHeader.acqIndex;
currentFrameIndex = zHeader.frameIndex; currentFrameIndex = zHeader.frameIndex;
currentProgress = zHeader.progress;
currentFileIndex = zHeader.fileIndex; currentFileIndex = zHeader.fileIndex;
currentSubFrameIndex = zHeader.expLength; currentSubFrameIndex = zHeader.expLength;
coordY = zHeader.row; coordY = zHeader.row;
@ -559,6 +561,7 @@ void DetectorImpl::readFrameFromReceiver() {
<< "\n\tcurrentFrameIndex: " << currentFrameIndex << "\n\tcurrentFrameIndex: " << currentFrameIndex
<< "\n\tcurrentFileIndex: " << currentFileIndex << "\n\tcurrentFileIndex: " << currentFileIndex
<< "\n\tcurrentSubFrameIndex: " << currentSubFrameIndex << "\n\tcurrentSubFrameIndex: " << currentSubFrameIndex
<< "\n\tcurrentProgress: " << currentProgress
<< "\n\tcoordX: " << coordX << "\n\tcoordY: " << coordY << "\n\tcoordX: " << coordX << "\n\tcoordY: " << coordY
<< "\n\tflippedDataX: " << flippedDataX << "\n\tflippedDataX: " << flippedDataX
<< "\n\tcompleteImage: " << completeImage; << "\n\tcompleteImage: " << completeImage;
@ -613,7 +616,6 @@ void DetectorImpl::readFrameFromReceiver() {
// send data to callback // send data to callback
if (data) { if (data) {
setCurrentProgress(currentFrameIndex + 1);
char* image = multiframe; char* image = multiframe;
int imagesize = multisize; int imagesize = multisize;
@ -630,7 +632,7 @@ void DetectorImpl::readFrameFromReceiver() {
<< "\n\timagesize: " << imagesize << "\n\timagesize: " << imagesize
<< "\n\tdynamicRange: " << dynamicRange; << "\n\tdynamicRange: " << dynamicRange;
thisData = new detectorData(getCurrentProgress(), thisData = new detectorData(currentProgress,
currentFileName, nDetPixelsX, nDetPixelsY, image, currentFileName, nDetPixelsX, nDetPixelsY, image,
imagesize, dynamicRange, currentFileIndex, completeImage); imagesize, dynamicRange, currentFileIndex, completeImage);
@ -1004,38 +1006,6 @@ void DetectorImpl::registerDataCallback(void (*userCallback)(detectorData *,
enableDataStreamingToClient(dataReady == nullptr ? 0 : 1); enableDataStreamingToClient(dataReady == nullptr ? 0 : 1);
} }
double DetectorImpl::setTotalProgress() {
int64_t tot = Parallel(&Module::getTotalNumFramesToReceive, {})
.tsquash("Inconsistent number of total frames (#frames x #triggers(or bursts) x #storage cells)");
if (tot == 0) {
throw RuntimeError("Invalid Total Number of frames (0)");
}
totalProgress = tot;
LOG(logDEBUG1) << "Set total progress " << totalProgress << std::endl;
return totalProgress;
}
double DetectorImpl::getCurrentProgress() {
std::lock_guard<std::mutex> lock(mp);
return 100. * progressIndex / totalProgress;
}
void DetectorImpl::incrementProgress() {
std::lock_guard<std::mutex> lock(mp);
progressIndex += 1;
std::cout << std::fixed << std::setprecision(2) << std::setw(6)
<< 100. * progressIndex / totalProgress << " \%";
std::cout << '\r' << std::flush;
}
void DetectorImpl::setCurrentProgress(int64_t i) {
std::lock_guard<std::mutex> lock(mp);
progressIndex = (double)i;
std::cout << std::fixed << std::setprecision(2) << std::setw(6)
<< 100. * progressIndex / totalProgress << " \%";
std::cout << '\r' << std::flush;
}
int DetectorImpl::acquire() { int DetectorImpl::acquire() {
// ensure acquire isnt started multiple times by same client // ensure acquire isnt started multiple times by same client
if (!isAcquireReady()) { if (!isAcquireReady()) {
@ -1056,7 +1026,7 @@ int DetectorImpl::acquire() {
bool receiver = bool receiver =
Parallel(&Module::getUseReceiverFlag, {}).squash(false); Parallel(&Module::getUseReceiverFlag, {}).squash(false);
progressIndex = 0;
setJoinThreadFlag(false); setJoinThreadFlag(false);
// verify receiver is idle // verify receiver is idle
@ -1066,7 +1036,6 @@ int DetectorImpl::acquire() {
Parallel(&Module::stopReceiver, {}); Parallel(&Module::stopReceiver, {});
} }
} }
setTotalProgress();
startProcessingThread(); startProcessingThread();
@ -1106,12 +1075,10 @@ int DetectorImpl::acquire() {
dataProcessingThread.join(); dataProcessingThread.join();
if (acquisition_finished != nullptr) { if (acquisition_finished != nullptr) {
// same status for all, else error int status = Parallel(&Module::getRunStatus, {}).squash(ERROR);
int status = static_cast<int>(ERROR); auto a = Parallel(&Module::getReceiverProgress, {});
auto t = Parallel(&Module::getRunStatus, {}); int progress = (*std::min_element (a.begin(), a.end()));
if (t.equal()) acquisition_finished((double)progress, status, acqFinished_p);
status = t.front();
acquisition_finished(getCurrentProgress(), status, acqFinished_p);
} }
sem_destroy(&sem_newRTAcquisition); sem_destroy(&sem_newRTAcquisition);
@ -1130,8 +1097,14 @@ int DetectorImpl::acquire() {
return OK; return OK;
} }
void DetectorImpl::printProgress(double progress) {
std::cout << std::fixed << std::setprecision(2) << std::setw(6)
<< progress << " \%";
std::cout << '\r' << std::flush;
}
void DetectorImpl::startProcessingThread() { void DetectorImpl::startProcessingThread() {
setTotalProgress();
dataProcessingThread = std::thread(&DetectorImpl::processData, this); dataProcessingThread = std::thread(&DetectorImpl::processData, this);
} }
@ -1142,7 +1115,9 @@ void DetectorImpl::processData() {
} }
// only update progress // only update progress
else { else {
int64_t caught = -1; double progress = 0;
printProgress(progress);
while (true) { while (true) {
// to exit acquire by typing q // to exit acquire by typing q
if (kbhit() != 0) { if (kbhit() != 0) {
@ -1152,16 +1127,18 @@ void DetectorImpl::processData() {
Parallel(&Module::stopAcquisition, {}); Parallel(&Module::stopAcquisition, {});
} }
} }
// get progress // get and print progress
caught = Parallel(&Module::getFramesCaughtByReceiver, {0}) double temp = (double)Parallel(&Module::getReceiverProgress, {0}).squash();
.squash(); if (temp != progress) {
printProgress(progress);
// updating progress progress = temp;
if (caught != -1) {
setCurrentProgress(caught);
} }
// exiting loop // exiting loop
if (getJoinThreadFlag()) { if (getJoinThreadFlag()) {
// print progress one final time before exiting
progress = (double)Parallel(&Module::getReceiverProgress, {0}).squash();
printProgress(progress);
break; break;
} }
// otherwise error when connecting to the receiver too fast // otherwise error when connecting to the receiver too fast

View File

@ -354,13 +354,7 @@ class DetectorImpl : public virtual slsDetectorDefs {
int InsertGapPixels(char *image, char *&gpImage, bool quadEnable, int dr, int InsertGapPixels(char *image, char *&gpImage, bool quadEnable, int dr,
int &nPixelsx, int &nPixelsy); int &nPixelsx, int &nPixelsy);
double setTotalProgress(); void printProgress(double progress);
double getCurrentProgress();
void incrementProgress();
void setCurrentProgress(int64_t i = 0);
void startProcessingThread(); void startProcessingThread();
@ -405,12 +399,6 @@ class DetectorImpl : public virtual slsDetectorDefs {
* from ext. process) */ * from ext. process) */
sem_t sem_endRTAcquisition; sem_t sem_endRTAcquisition;
/** Total number of frames/images for next acquisition */
double totalProgress{0};
/** Current progress or frames/images processed in current acquisition */
double progressIndex{0};
/** mutex to synchronize main and data processing threads */ /** mutex to synchronize main and data processing threads */
mutable std::mutex mp; mutable std::mutex mp;

View File

@ -137,12 +137,8 @@ int64_t Module::getReceiverSoftwareVersion() const {
void Module::sendToDetector(int fnum, const void *args, size_t args_size, void Module::sendToDetector(int fnum, const void *args, size_t args_size,
void *retval, size_t retval_size) { void *retval, size_t retval_size) {
auto client = DetectorSocket(shm()->hostname, shm()->controlPort); auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
auto ret = client.sendCommandThenRead(fnum, args, args_size, retval, retval_size);
client.sendCommandThenRead(fnum, args, args_size, retval, retval_size);
client.close(); client.close();
if (ret == FORCE_UPDATE) {
updateCachedDetectorVariables();
}
} }
template <typename Arg, typename Ret> template <typename Arg, typename Ret>
@ -363,7 +359,6 @@ void Module::setHostname(const std::string &hostname, const bool initialChecks)
} }
LOG(logINFO) << "Detector connecting - updating!"; LOG(logINFO) << "Detector connecting - updating!";
updateCachedDetectorVariables();
} }
std::string Module::getHostname() const { return shm()->hostname; } std::string Module::getHostname() const { return shm()->hostname; }
@ -396,14 +391,6 @@ void Module::initializeDetectorStructure(detectorType type) {
shm()->controlPort = DEFAULT_PORTNO; shm()->controlPort = DEFAULT_PORTNO;
shm()->stopPort = DEFAULT_PORTNO + 1; shm()->stopPort = DEFAULT_PORTNO + 1;
sls::strcpy_safe(shm()->settingsDir, getenv("HOME")); sls::strcpy_safe(shm()->settingsDir, getenv("HOME"));
shm()->currentSettings = UNINITIALIZED;
shm()->nFrames = 1;
shm()->nTriggers = 1;
shm()->nBursts = 1;
shm()->nAddStorageCells = 0;
shm()->timingMode = AUTO_TIMING;
shm()->burstMode = BURST_INTERNAL;
shm()->deadTime = 0;
sls::strcpy_safe(shm()->rxHostname, "none"); sls::strcpy_safe(shm()->rxHostname, "none");
shm()->rxTCPPort = DEFAULT_PORTNO + 2; shm()->rxTCPPort = DEFAULT_PORTNO + 2;
shm()->useReceiverFlag = false; shm()->useReceiverFlag = false;
@ -420,7 +407,6 @@ void Module::initializeDetectorStructure(detectorType type) {
shm()->nChip.x = parameters.nChipX; shm()->nChip.x = parameters.nChipX;
shm()->nChip.y = parameters.nChipY; shm()->nChip.y = parameters.nChipY;
shm()->nDacs = parameters.nDacs; shm()->nDacs = parameters.nDacs;
shm()->dynamicRange = parameters.dynamicRange;
} }
int Module::sendModule(sls_detector_module *myMod, int Module::sendModule(sls_detector_module *myMod,
@ -540,27 +526,6 @@ Module::getTypeFromDetector(const std::string &hostname, int cport) {
return retval; return retval;
} }
int Module::setDetectorType(detectorType const type) {
int fnum = F_GET_DETECTOR_TYPE;
detectorType retval = GENERIC;
LOG(logDEBUG1) << "Setting detector type to " << type;
// if unspecified, then get from detector
if (type == GET_DETECTOR_TYPE) {
sendToDetector(fnum, nullptr, retval);
shm()->myDetectorType = static_cast<detectorType>(retval);
LOG(logDEBUG1) << "Detector Type: " << retval;
}
if (shm()->useReceiverFlag) {
auto arg = static_cast<int>(shm()->myDetectorType);
retval = GENERIC;
LOG(logDEBUG1) << "Sending detector type to Receiver: " << arg;
sendToReceiver(F_GET_RECEIVER_TYPE, arg, retval);
LOG(logDEBUG1) << "Receiver Type: " << retval;
}
return retval;
}
slsDetectorDefs::detectorType Module::getDetectorType() const { slsDetectorDefs::detectorType Module::getDetectorType() const {
return shm()->myDetectorType; return shm()->myDetectorType;
} }
@ -712,82 +677,6 @@ void Module::execCommand(const std::string &cmd) {
} }
} }
void Module::updateCachedDetectorVariables() {
int fnum = F_UPDATE_CLIENT;
LOG(logDEBUG1) << "Sending update client to detector server";
auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
if (client.sendCommandThenRead(fnum, nullptr, 0, nullptr, 0) ==
FORCE_UPDATE) {
int n = 0, i32 = 0;
int64_t i64 = 0;
sls::IpAddr lastClientIP;
n += client.Receive(&lastClientIP, sizeof(lastClientIP));
LOG(logDEBUG1)
<< "Updating detector last modified by " << lastClientIP;
// dr
n += client.Receive(&i32, sizeof(i32));
shm()->dynamicRange = i32;
// settings
if (shm()->myDetectorType == EIGER || shm()->myDetectorType == JUNGFRAU ||
shm()->myDetectorType == GOTTHARD || shm()->myDetectorType == GOTTHARD2 ||
shm()->myDetectorType == MOENCH) {
n += client.Receive(&i32, sizeof(i32));
shm()->currentSettings = static_cast<detectorSettings>(i32);
}
// frame number
n += client.Receive(&i64, sizeof(i64));
shm()->nFrames = i64;
// storage cell
if (shm()->myDetectorType == JUNGFRAU) {
n += client.Receive(&i64, sizeof(i64));
shm()->nAddStorageCells = i64;
}
// triggers
n += client.Receive(&i64, sizeof(i64));
shm()->nTriggers = i64;
// bursts
if (shm()->myDetectorType == GOTTHARD2) {
n += client.Receive(&i64, sizeof(i64));
shm()->nBursts = i64;
}
// timing mode
n += client.Receive(&i32, sizeof(i32));
shm()->timingMode = static_cast<timingMode>(i32);
// burst mode
if (shm()->myDetectorType == GOTTHARD2) {
n += client.Receive(&i32, sizeof(i32));
shm()->burstMode = static_cast<burstMode>(i32);
}
// number of channels (depends on #samples, adcmask)
if (shm()->myDetectorType == CHIPTESTBOARD ||
shm()->myDetectorType == MOENCH) {
n += client.Receive(&i32, sizeof(i32));
shm()->nChan.x = i32;
n += client.Receive(&i32, sizeof(i32));
shm()->nChan.y = i32;
}
// num udp interfaces
if (shm()->myDetectorType == JUNGFRAU) {
n += client.Receive(&i32, sizeof(i32));
shm()->numUDPInterfaces = i32;
}
if (n == 0) {
LOG(logERROR) << "Could not update detector, received 0 bytes";
}
}
}
std::vector<std::string> Module::getConfigFileCommands() { std::vector<std::string> Module::getConfigFileCommands() {
std::vector<std::string> base{"hostname", "port", "stopport", std::vector<std::string> base{"hostname", "port", "stopport",
"settingsdir", "fpath", "lock", "settingsdir", "fpath", "lock",
@ -863,49 +752,21 @@ std::vector<std::string> Module::getConfigFileCommands() {
} }
slsDetectorDefs::detectorSettings Module::getSettings() { slsDetectorDefs::detectorSettings Module::getSettings() {
return sendSettingsOnly(GET_SETTINGS); int arg = -1;
int retval = -1;
sendToDetector(F_SET_SETTINGS, arg, retval);
LOG(logDEBUG1) << "Settings: " << retval;
return static_cast<detectorSettings>(retval);
} }
slsDetectorDefs::detectorSettings void Module::setSettings(detectorSettings isettings) {
Module::setSettings(detectorSettings isettings) {
LOG(logDEBUG1) << "Module setSettings " << isettings;
if (isettings == -1) {
return getSettings();
}
// eiger: only set shm, setting threshold loads the module data
if (shm()->myDetectorType == EIGER) { if (shm()->myDetectorType == EIGER) {
switch (isettings) { throw RuntimeError("Cannot set settings for Eiger. Use threshold energy.");
case STANDARD:
case HIGHGAIN:
case LOWGAIN:
case VERYHIGHGAIN:
case VERYLOWGAIN:
shm()->currentSettings = isettings;
return shm()->currentSettings;
default:
std::ostringstream ss;
ss << "Unknown settings " << ToString(isettings)
<< " for this detector!";
throw RuntimeError(ss.str());
}
} }
// others: send only the settings, detector server will update dac values
// already in server
return sendSettingsOnly(isettings);
}
slsDetectorDefs::detectorSettings
Module::sendSettingsOnly(detectorSettings isettings) {
int arg = static_cast<int>(isettings); int arg = static_cast<int>(isettings);
int retval = -1; int retval = -1;
LOG(logDEBUG1) << "Setting settings to " << arg; LOG(logDEBUG1) << "Setting settings to " << arg;
sendToDetector(F_SET_SETTINGS, arg, retval); sendToDetector(F_SET_SETTINGS, arg, retval);
LOG(logDEBUG1) << "Settings: " << retval;
shm()->currentSettings = static_cast<detectorSettings>(retval);
return shm()->currentSettings;
} }
int Module::getThresholdEnergy() { int Module::getThresholdEnergy() {
@ -944,8 +805,11 @@ void Module::setThresholdEnergy(int e_eV, detectorSettings isettings,
else if (shm()->myDetectorType == MOENCH) { else if (shm()->myDetectorType == MOENCH) {
setAdditionalJsonParameter("threshold", std::to_string(e_eV)); setAdditionalJsonParameter("threshold", std::to_string(e_eV));
} }
throw RuntimeError(
else {
throw RuntimeError(
"Set threshold energy not implemented for this detector"); "Set threshold energy not implemented for this detector");
}
} }
void Module::setThresholdEnergyAndSettings(int e_eV, void Module::setThresholdEnergyAndSettings(int e_eV,
@ -954,7 +818,7 @@ void Module::setThresholdEnergyAndSettings(int e_eV,
// if settings provided, use that, else use the shared memory variable // if settings provided, use that, else use the shared memory variable
detectorSettings is = detectorSettings is =
((isettings != GET_SETTINGS) ? isettings : shm()->currentSettings); ((isettings != GET_SETTINGS) ? isettings : getSettings());
// verify e_eV exists in trimEneregies[] // verify e_eV exists in trimEneregies[]
if (shm()->trimEnergies.empty() || (e_eV < shm()->trimEnergies.front()) || if (shm()->trimEnergies.empty() || (e_eV < shm()->trimEnergies.front()) ||
@ -999,8 +863,7 @@ void Module::setThresholdEnergyAndSettings(int e_eV,
linearInterpolation(e_eV, trim1, trim2, myMod1.tau, myMod2.tau); linearInterpolation(e_eV, trim1, trim2, myMod1.tau, myMod2.tau);
} }
shm()->currentSettings = is; myMod.reg = is;
myMod.reg = shm()->currentSettings;
myMod.eV = e_eV; myMod.eV = e_eV;
setModule(myMod, tb); setModule(myMod, tb);
if (getSettings() != is) { if (getSettings() != is) {
@ -1161,101 +1024,64 @@ uint64_t Module::getStartingFrameNumber() {
return retval; return retval;
} }
int64_t Module::getTotalNumFramesToReceive() {
int64_t repeats = shm()->nTriggers;
// gotthard2 & auto & burst mode, use nBursts instead of nTriggers
if (shm()->myDetectorType == GOTTHARD2) {
// auto mode (either bursts or no repeats)
if (shm()->timingMode == AUTO_TIMING) {
if (shm()->burstMode != BURST_OFF) {
repeats = shm()->nBursts;
} else {
repeats = 1;
}
}
}
return (shm()->nFrames * repeats * (int64_t)(shm()->nAddStorageCells + 1));
}
void Module::sendTotalNumFramestoReceiver() {
if (shm()->useReceiverFlag) {
int64_t arg = getTotalNumFramesToReceive();
LOG(logDEBUG1) << "Sending total number of frames (#f x #t x #s) to Receiver: " << arg;
sendToReceiver(F_RECEIVER_SET_NUM_FRAMES, arg, nullptr);
}
}
int64_t Module::getNumberOfFrames() { int64_t Module::getNumberOfFrames() {
int64_t retval = -1; int64_t retval = -1;
sendToDetector(F_GET_NUM_FRAMES, nullptr, retval); sendToDetector(F_GET_NUM_FRAMES, nullptr, retval);
LOG(logDEBUG1) << "number of frames :" << retval; LOG(logDEBUG1) << "number of frames :" << retval;
if (shm()->nFrames != retval) { return retval;
shm()->nFrames = retval;
sendTotalNumFramestoReceiver();
}
return shm()->nFrames;
} }
void Module::setNumberOfFrames(int64_t value) { void Module::setNumberOfFrames(int64_t value) {
LOG(logDEBUG1) << "Setting number of frames to " << value; LOG(logDEBUG1) << "Setting number of frames to " << value;
sendToDetector(F_SET_NUM_FRAMES, value, nullptr); sendToDetector(F_SET_NUM_FRAMES, value, nullptr);
shm()->nFrames = value; if (shm()->useReceiverFlag) {
sendTotalNumFramestoReceiver(); LOG(logDEBUG1) << "Sending number of frames to Receiver: " << value;
sendToReceiver(F_RECEIVER_SET_NUM_FRAMES, value, nullptr);
}
} }
int64_t Module::getNumberOfTriggers() { int64_t Module::getNumberOfTriggers() {
int64_t retval = -1; int64_t retval = -1;
sendToDetector(F_GET_NUM_TRIGGERS, nullptr, retval); sendToDetector(F_GET_NUM_TRIGGERS, nullptr, retval);
LOG(logDEBUG1) << "number of triggers :" << retval; LOG(logDEBUG1) << "number of triggers :" << retval;
if (shm()->nTriggers != retval) { return retval;
shm()->nTriggers = retval;
sendTotalNumFramestoReceiver();
}
return shm()->nTriggers;
} }
void Module::setNumberOfTriggers(int64_t value) { void Module::setNumberOfTriggers(int64_t value) {
LOG(logDEBUG1) << "Setting number of triggers to " << value; LOG(logDEBUG1) << "Setting number of triggers to " << value;
sendToDetector(F_SET_NUM_TRIGGERS, value, nullptr); sendToDetector(F_SET_NUM_TRIGGERS, value, nullptr);
shm()->nTriggers = value; if (shm()->useReceiverFlag) {
sendTotalNumFramestoReceiver(); LOG(logDEBUG1) << "Sending number of triggers to Receiver: " << value;
sendToReceiver(F_SET_RECEIVER_NUM_TRIGGERS, value, nullptr);
}
} }
int64_t Module::getNumberOfBursts() { int64_t Module::getNumberOfBursts() {
int64_t retval = -1; int64_t retval = -1;
sendToDetector(F_GET_NUM_BURSTS, nullptr, retval); sendToDetector(F_GET_NUM_BURSTS, nullptr, retval);
LOG(logDEBUG1) << "number of bursts :" << retval; LOG(logDEBUG1) << "number of bursts :" << retval;
if (shm()->nBursts != retval) { return retval;
shm()->nBursts = retval;
sendTotalNumFramestoReceiver();
}
return shm()->nBursts;
} }
void Module::setNumberOfBursts(int64_t value) { void Module::setNumberOfBursts(int64_t value) {
LOG(logDEBUG1) << "Setting number of bursts to " << value; LOG(logDEBUG1) << "Setting number of bursts to " << value;
sendToDetector(F_SET_NUM_BURSTS, value, nullptr); sendToDetector(F_SET_NUM_BURSTS, value, nullptr);
shm()->nBursts = value; if (shm()->useReceiverFlag) {
sendTotalNumFramestoReceiver(); LOG(logDEBUG1) << "Sending number of bursts to Receiver: " << value;
sendToReceiver(F_SET_RECEIVER_NUM_BURSTS, value, nullptr);
}
} }
int Module::getNumberOfAdditionalStorageCells() { int Module::getNumberOfAdditionalStorageCells() {
int prevVal = shm()->nAddStorageCells;
int retval = -1; int retval = -1;
sendToDetector(F_GET_NUM_ADDITIONAL_STORAGE_CELLS, nullptr, retval); sendToDetector(F_GET_NUM_ADDITIONAL_STORAGE_CELLS, nullptr, retval);
LOG(logDEBUG1) << "number of storage cells :" << retval; LOG(logDEBUG1) << "number of storage cells :" << retval;
shm()->nAddStorageCells = retval; return retval;
if (prevVal != retval) {
sendTotalNumFramestoReceiver();
}
return shm()->nAddStorageCells;
} }
void Module::setNumberOfAdditionalStorageCells(int value) { void Module::setNumberOfAdditionalStorageCells(int value) {
LOG(logDEBUG1) << "Setting number of storage cells to " << value; LOG(logDEBUG1) << "Setting number of storage cells to " << value;
sendToDetector(F_SET_NUM_ADDITIONAL_STORAGE_CELLS, value, nullptr); sendToDetector(F_SET_NUM_ADDITIONAL_STORAGE_CELLS, value, nullptr);
shm()->nAddStorageCells = value;
sendTotalNumFramestoReceiver();
} }
int Module::getNumberOfAnalogSamples() { int Module::getNumberOfAnalogSamples() {
@ -1305,16 +1131,13 @@ void Module::setExptime(int64_t value) {
} }
LOG(logDEBUG1) << "Setting exptime to " << value << "ns"; LOG(logDEBUG1) << "Setting exptime to " << value << "ns";
sendToDetector(F_SET_EXPTIME, value, nullptr); sendToDetector(F_SET_EXPTIME, value, nullptr);
if (shm()->myDetectorType == EIGER && prevVal != value && shm()->dynamicRange == 16) {
int r = getRateCorrection();
if (r != 0) {
setRateCorrection(r);
}
}
if (shm()->useReceiverFlag) { if (shm()->useReceiverFlag) {
LOG(logDEBUG1) << "Sending exptime to Receiver: " << value; LOG(logDEBUG1) << "Sending exptime to Receiver: " << value;
sendToReceiver(F_RECEIVER_SET_EXPTIME, value, nullptr); sendToReceiver(F_RECEIVER_SET_EXPTIME, value, nullptr);
} }
if (prevVal != value) {
updateRateCorrection();
}
} }
int64_t Module::getPeriod() { int64_t Module::getPeriod() {
@ -1359,16 +1182,13 @@ void Module::setSubExptime(int64_t value) {
} }
LOG(logDEBUG1) << "Setting sub exptime to " << value << "ns"; LOG(logDEBUG1) << "Setting sub exptime to " << value << "ns";
sendToDetector(F_SET_SUB_EXPTIME, value, nullptr); sendToDetector(F_SET_SUB_EXPTIME, value, nullptr);
if (shm()->myDetectorType == EIGER && prevVal != value && shm()->dynamicRange == 32) {
int r = getRateCorrection();
if (r != 0) {
setRateCorrection(r);
}
}
if (shm()->useReceiverFlag) { if (shm()->useReceiverFlag) {
LOG(logDEBUG1) << "Sending sub exptime to Receiver: " << value; LOG(logDEBUG1) << "Sending sub exptime to Receiver: " << value;
sendToReceiver(F_RECEIVER_SET_SUB_EXPTIME, value, nullptr); sendToReceiver(F_RECEIVER_SET_SUB_EXPTIME, value, nullptr);
} }
if (prevVal != value) {
updateRateCorrection();
}
} }
int64_t Module::getSubDeadTime() { int64_t Module::getSubDeadTime() {
@ -1466,48 +1286,63 @@ int64_t Module::getMeasurementTime() const {
return retval; return retval;
} }
slsDetectorDefs::timingMode Module::setTimingMode(timingMode value) { slsDetectorDefs::timingMode Module::getTimingMode() {
int fnum = F_SET_TIMING_MODE; int arg = -1;
//auto arg = static_cast<int>(pol);
timingMode retval = GET_TIMING_MODE; timingMode retval = GET_TIMING_MODE;
LOG(logDEBUG1) << "Setting communication to mode " << value; sendToDetector(F_SET_TIMING_MODE, arg, retval);
sendToDetector(fnum, static_cast<int>(value), retval);
LOG(logDEBUG1) << "Timing Mode: " << retval; LOG(logDEBUG1) << "Timing Mode: " << retval;
shm()->timingMode = retval;
return retval; return retval;
} }
int Module::setDynamicRange(int n) { void Module::setTimingMode(timingMode value) {
// TODO! Properly handle fail timingMode retval = GET_TIMING_MODE;
int prevDr = shm()->dynamicRange; LOG(logDEBUG1) << "Setting timing mode to " << value;
sendToDetector(F_SET_TIMING_MODE, static_cast<int>(value), retval);
if (shm()->useReceiverFlag) {
LOG(logDEBUG1) << "Sending timing mode to Receiver: " << value;
sendToReceiver(F_SET_RECEIVER_TIMING_MODE, value, nullptr);
}
}
int Module::getDynamicRange() {
int arg = -1;
int retval = -1;
sendToDetector(F_SET_DYNAMIC_RANGE, arg, retval);
LOG(logDEBUG1) << "Dynamic Range: " << retval;
return retval;
}
void Module::setDynamicRange(int n) {
int prev_val = n;
if (shm()->myDetectorType == EIGER) {
prev_val = getDynamicRange();
}
int retval = -1; int retval = -1;
LOG(logDEBUG1) << "Setting dynamic range to " << n; LOG(logDEBUG1) << "Setting dynamic range to " << n;
sendToDetector(F_SET_DYNAMIC_RANGE, n, retval); sendToDetector(F_SET_DYNAMIC_RANGE, n, retval);
LOG(logDEBUG1) << "Dynamic Range: " << retval; LOG(logDEBUG1) << "Dynamic Range: " << retval;
shm()->dynamicRange = retval;
if (shm()->useReceiverFlag) { if (shm()->useReceiverFlag) {
n = shm()->dynamicRange; int arg = retval;
retval = -1; retval = -1;
LOG(logDEBUG1) << "Sending dynamic range to receiver: " << n; LOG(logDEBUG1) << "Sending dynamic range to receiver: " << arg;
sendToReceiver(F_SET_RECEIVER_DYNAMIC_RANGE, n, retval); sendToReceiver(F_SET_RECEIVER_DYNAMIC_RANGE, arg, retval);
LOG(logDEBUG1) << "Receiver Dynamic range: " << retval; LOG(logDEBUG1) << "Receiver Dynamic range: " << retval;
} }
// changes in dr // changes in dr
int dr = shm()->dynamicRange; if (n != prev_val) {
if (prevDr != dr && shm()->myDetectorType == EIGER) {
updateRateCorrection();
// update speed for usability // update speed for usability
if (dr == 32) { if (n == 32) {
LOG(logINFO) << "Setting Clock to Quarter Speed to cope with Dynamic Range of 32"; setClockDivider(RUN_CLOCK, 2); LOG(logINFO) << "Setting Clock to Quarter Speed to cope with Dynamic Range of 32";
} else { setClockDivider(RUN_CLOCK, 2);
LOG(logINFO) << "Setting Clock to Full Speed to cope with Dynamic Range of " << dr; setClockDivider(RUN_CLOCK, 0); } else if (prev_val == 32) {
LOG(logINFO) << "Setting Clock to Full Speed for Dynamic Range of " << n;
setClockDivider(RUN_CLOCK, 0);
} }
updateRateCorrection();
} }
return shm()->dynamicRange;
} }
int Module::setDAC(int val, dacIndex index, int mV) { int Module::setDAC(int val, dacIndex index, int mV) {
@ -1654,14 +1489,13 @@ uint32_t Module::clearBit(uint32_t addr, int n) {
} }
} }
std::string Module::setReceiverHostname(const std::string &receiverIP) { void Module::setReceiverHostname(const std::string &receiverIP) {
LOG(logDEBUG1) << "Setting up Receiver with " << receiverIP; LOG(logDEBUG1) << "Setting up Receiver with " << receiverIP;
// recieverIP is none // recieverIP is none
if (receiverIP == "none") { if (receiverIP == "none") {
memset(shm()->rxHostname, 0, MAX_STR_LENGTH); memset(shm()->rxHostname, 0, MAX_STR_LENGTH);
sls::strcpy_safe(shm()->rxHostname, "none"); sls::strcpy_safe(shm()->rxHostname, "none");
shm()->useReceiverFlag = false; shm()->useReceiverFlag = false;
return std::string(shm()->rxHostname);
} }
// stop acquisition if running // stop acquisition if running
@ -1669,8 +1503,6 @@ std::string Module::setReceiverHostname(const std::string &receiverIP) {
LOG(logWARNING) << "Acquisition already running, Stopping it."; LOG(logWARNING) << "Acquisition already running, Stopping it.";
stopAcquisition(); stopAcquisition();
} }
// update detector before receiver
updateCachedDetectorVariables();
// start updating // start updating
std::string host = receiverIP; std::string host = receiverIP;
@ -1683,74 +1515,78 @@ std::string Module::setReceiverHostname(const std::string &receiverIP) {
shm()->useReceiverFlag = true; shm()->useReceiverFlag = true;
checkReceiverVersionCompatibility(); checkReceiverVersionCompatibility();
if (setDetectorType(shm()->myDetectorType) != GENERIC) { // populate parameters from detector
sendMultiDetectorSize(); rxParameters retval;
setDetectorId(); sendToDetector(F_GET_RECEIVER_PARAMETERS, nullptr, retval);
setDetectorHostname();
// setup udp // populate from shared memory
updateRxDestinationUDPIP(); retval.detType = shm()->myDetectorType;
setDestinationUDPPort(getDestinationUDPPort()); retval.multiSize.x = shm()->multiSize.x;
if (shm()->myDetectorType == JUNGFRAU || shm()->myDetectorType == EIGER ) { retval.multiSize.y = shm()->multiSize.y;
setDestinationUDPPort2(getDestinationUDPPort2()); retval.detId = detId;
} memset(retval.hostname, 0, sizeof(retval.hostname));
if (shm()->myDetectorType == JUNGFRAU) { strcpy_safe(retval.hostname, shm()->hostname);
updateRxDestinationUDPIP2();
setNumberofUDPInterfaces(getNumberofUDPInterfaces());
}
LOG(logDEBUG1) << printReceiverConfiguration();
setReceiverUDPSocketBufferSize(0); LOG(logDEBUG1)
sendTotalNumFramestoReceiver(); << "detType:" << retval.detType << std::endl
setExptime(getExptime()); << "multiSize.x:" << retval.multiSize.x << std::endl
setPeriod(getPeriod()); << "multiSize.y:" << retval.multiSize.y << std::endl
<< "detId:" << retval.detId << std::endl
<< "hostname:" << retval.hostname << std::endl
<< "udpInterfaces:" << retval.udpInterfaces << std::endl
<< "udp_dstport:" << retval.udp_dstport << std::endl
<< "udp_dstip:" << sls::IpAddr(retval.udp_dstip) << std::endl
<< "udp_dstmac:" << sls::MacAddr(retval.udp_dstmac) << std::endl
<< "udp_dstport2:" << retval.udp_dstport2 << std::endl
<< "udp_dstip2:" << sls::IpAddr(retval.udp_dstip2) << std::endl
<< "udp_dstmac2:" << sls::MacAddr(retval.udp_dstmac2) << std::endl
<< "frames:" << retval.frames << std::endl
<< "triggers:" << retval.triggers << std::endl
<< "bursts:" << retval.bursts << std::endl
<< "analogSamples:" << retval.analogSamples << std::endl
<< "digitalSamples:" << retval.digitalSamples << std::endl
<< "expTimeNs:" << retval.expTimeNs << std::endl
<< "periodNs:" << retval.periodNs << std::endl
<< "subExpTimeNs:" << retval.subExpTimeNs << std::endl
<< "subDeadTimeNs:" << retval.subDeadTimeNs << std::endl
<< "activate:" << retval.activate << std::endl
<< "quad:" << retval.quad << std::endl
<< "dynamicRange:" << retval.dynamicRange << std::endl
<< "timMode:" << retval.timMode << std::endl
<< "tenGiga:" << retval.tenGiga << std::endl
<< "roMode:" << retval.roMode << std::endl
<< "adcMask:" << retval.adcMask << std::endl
<< "adc10gMask:" << retval.adc10gMask << std::endl
<< "roi.xmin:" << retval.roi.xmin << std::endl
<< "roi.xmax:" << retval.roi.xmax << std::endl
<< "countermask:" << retval.countermask << std::endl
<< "burstType:" << retval.burstType << std::endl;
// detector specific
switch (shm()->myDetectorType) {
case EIGER: sls::MacAddr retvals[2];
setSubExptime(getSubExptime()); sendToReceiver(F_SETUP_RECEIVER, retval, retvals);
setSubDeadTime(getSubDeadTime()); // update detectors with dest mac
setDynamicRange(shm()->dynamicRange); if (retval.udp_dstmac == 0 && retvals[0] != 0) {
activate(-1); LOG(logINFO) << "Setting destination udp mac of "
enableTenGigabitEthernet(-1); "detector " << detId << " to " << retvals[0];
setQuad(getQuad()); sendToDetector(F_SET_DEST_UDP_MAC, retvals[0], nullptr);
break; }
if (retval.udp_dstmac2 == 0 && retvals[1] != 0) {
case CHIPTESTBOARD: LOG(logINFO) << "Setting destination udp mac2 of "
setNumberOfAnalogSamples(getNumberOfAnalogSamples()); "detector " << detId << " to " << retvals[1];
setNumberOfDigitalSamples(getNumberOfDigitalSamples()); sendToDetector(F_SET_DEST_UDP_MAC2, retvals[1], nullptr);
enableTenGigabitEthernet(-1);
setReadoutMode(getReadoutMode());
setADCEnableMask(getADCEnableMask());
setTenGigaADCEnableMask(getTenGigaADCEnableMask());
break;
case MOENCH:
setNumberOfAnalogSamples(getNumberOfAnalogSamples());
enableTenGigabitEthernet(-1);
setADCEnableMask(getADCEnableMask());
setTenGigaADCEnableMask(getTenGigaADCEnableMask());
break;
case GOTTHARD:
setROI(getROI());
break;
case MYTHEN3:
sendNumberofCounterstoReceiver(getCounterMask());
setDynamicRange(shm()->dynamicRange);
break;
default:
break;
}
// to use rx_hostname if empty and also update client zmqip
updateReceiverStreamingIP();
} }
return std::string(shm()->rxHostname); // update numinterfaces if different
shm()->numUDPInterfaces = retval.udpInterfaces;
if (shm()->myDetectorType == MOENCH) {
setAdditionalJsonParameter("adcmask_1g", std::to_string(retval.adcMask));
setAdditionalJsonParameter("adcmask_10g", std::to_string(retval.adc10gMask));
}
// to use rx_hostname if empty and also update client zmqip
updateReceiverStreamingIP();
} }
std::string Module::getReceiverHostname() const { std::string Module::getReceiverHostname() const {
@ -1845,13 +1681,6 @@ sls::IpAddr Module::getDestinationUDPIP() {
return retval; return retval;
} }
void Module::updateRxDestinationUDPIP() {
auto ip = getDestinationUDPIP();
if (ip != 0) {
setDestinationUDPIP(ip);
}
}
void Module::setDestinationUDPIP2(const IpAddr ip) { void Module::setDestinationUDPIP2(const IpAddr ip) {
LOG(logDEBUG1) << "Setting destination udp ip2 to " << ip; LOG(logDEBUG1) << "Setting destination udp ip2 to " << ip;
if (ip == 0) { if (ip == 0) {
@ -1875,13 +1704,6 @@ sls::IpAddr Module::getDestinationUDPIP2() {
return retval; return retval;
} }
void Module::updateRxDestinationUDPIP2() {
auto ip = getDestinationUDPIP2();
if (ip != 0) {
setDestinationUDPIP2(ip);
}
}
void Module::setDestinationUDPMAC(const MacAddr mac) { void Module::setDestinationUDPMAC(const MacAddr mac) {
LOG(logDEBUG1) << "Setting destination udp mac to " << mac; LOG(logDEBUG1) << "Setting destination udp mac to " << mac;
if (mac == 0) { if (mac == 0) {
@ -2268,9 +2090,6 @@ std::vector<int> Module::getVetoPhoton(const int chipIndex) {
client.Receive(adus, sizeof(adus)); client.Receive(adus, sizeof(adus));
std::vector<int> retvals(adus, adus + nch); std::vector<int> retvals(adus, adus + nch);
LOG(logDEBUG1) << "Getting veto photon [" << chipIndex << "]: " << nch << " channels\n"; LOG(logDEBUG1) << "Getting veto photon [" << chipIndex << "]: " << nch << " channels\n";
if (ret == FORCE_UPDATE) {
updateCachedDetectorVariables();
}
return retvals; return retvals;
} }
} }
@ -2357,10 +2176,6 @@ void Module::setVetoPhoton(const int chipIndex, const int numPhotons, const int
client.Receive(mess, MAX_STR_LENGTH); client.Receive(mess, MAX_STR_LENGTH);
throw RuntimeError("Detector " + std::to_string(detId) + throw RuntimeError("Detector " + std::to_string(detId) +
" returned error: " + std::string(mess)); " returned error: " + std::string(mess));
} else {
if (ret == FORCE_UPDATE) {
updateCachedDetectorVariables();
}
} }
} }
@ -2374,15 +2189,17 @@ slsDetectorDefs::burstMode Module::getBurstMode() {
int retval = -1; int retval = -1;
sendToDetector(F_GET_BURST_MODE, nullptr, retval); sendToDetector(F_GET_BURST_MODE, nullptr, retval);
LOG(logDEBUG1) << "Burst mode:" << retval; LOG(logDEBUG1) << "Burst mode:" << retval;
shm()->burstMode = static_cast<slsDetectorDefs::burstMode>(retval); return static_cast<slsDetectorDefs::burstMode>(retval);
return shm()->burstMode;
} }
void Module::setBurstMode(slsDetectorDefs::burstMode value) { void Module::setBurstMode(slsDetectorDefs::burstMode value) {
int arg = static_cast<int>(value); int arg = static_cast<int>(value);
LOG(logDEBUG1) << "Setting burst mode to " << arg; LOG(logDEBUG1) << "Setting burst mode to " << arg;
sendToDetector(F_SET_BURST_MODE, arg, nullptr); sendToDetector(F_SET_BURST_MODE, arg, nullptr);
shm()->burstMode = value; if (shm()->useReceiverFlag) {
LOG(logDEBUG1) << "Sending burst mode to Receiver: " << value;
sendToReceiver(F_SET_RECEIVER_BURST_MODE, value, nullptr);
}
} }
bool Module::getCurrentSource() { bool Module::getCurrentSource() {
@ -2927,22 +2744,15 @@ void Module::setModule(sls_detector_module &module, int tb) {
} }
client.Receive(&retval, sizeof(retval)); client.Receive(&retval, sizeof(retval));
LOG(logDEBUG1) << "Set Module returned: " << retval; LOG(logDEBUG1) << "Set Module returned: " << retval;
if (ret == FORCE_UPDATE) {
updateCachedDetectorVariables();
}
} }
sls_detector_module Module::getModule() { sls_detector_module Module::getModule() {
int fnum = F_GET_MODULE; int fnum = F_GET_MODULE;
int ret = FAIL;
LOG(logDEBUG1) << "Getting module"; LOG(logDEBUG1) << "Getting module";
sls_detector_module myMod{shm()->myDetectorType}; sls_detector_module myMod{shm()->myDetectorType};
auto client = DetectorSocket(shm()->hostname, shm()->controlPort); auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
ret = client.sendCommandThenRead(fnum, nullptr, 0, nullptr, 0); client.sendCommandThenRead(fnum, nullptr, 0, nullptr, 0);
receiveModule(&myMod, client); receiveModule(&myMod, client);
if (ret == FORCE_UPDATE) {
updateCachedDetectorVariables();
}
return myMod; return myMod;
} }
@ -2950,37 +2760,23 @@ void Module::setDefaultRateCorrection() {
LOG(logDEBUG1) << "Setting Default Rate Correction"; LOG(logDEBUG1) << "Setting Default Rate Correction";
int64_t arg = -1; int64_t arg = -1;
sendToDetector(F_SET_RATE_CORRECT, arg, nullptr); sendToDetector(F_SET_RATE_CORRECT, arg, nullptr);
shm()->deadTime = -1;
} }
void Module::setRateCorrection(int64_t t) { void Module::setRateCorrection(int64_t t) {
LOG(logDEBUG1) << "Setting Rate Correction to " << t; LOG(logDEBUG1) << "Setting Rate Correction to " << t;
sendToDetector(F_SET_RATE_CORRECT, t, nullptr); sendToDetector(F_SET_RATE_CORRECT, t, nullptr);
shm()->deadTime = t;
} }
int64_t Module::getRateCorrection() { int64_t Module::getRateCorrection() {
int64_t retval = -1; int64_t retval = -1;
LOG(logDEBUG1) << "Getting rate correction";
sendToDetector(F_GET_RATE_CORRECT, nullptr, retval); sendToDetector(F_GET_RATE_CORRECT, nullptr, retval);
shm()->deadTime = retval;
LOG(logDEBUG1) << "Rate correction: " << retval; LOG(logDEBUG1) << "Rate correction: " << retval;
return retval; return retval;
} }
void Module::updateRateCorrection() { void Module::updateRateCorrection() {
if (shm()->deadTime != 0) { LOG(logDEBUG1) << "Updating rate correction";
switch (shm()->dynamicRange) { sendToDetector(F_UPDATE_RATE_CORRECTION);
case 16:
case 32:
setRateCorrection(shm()->deadTime);
break;
default:
setRateCorrection(0);
throw sls::RuntimeError(
"Rate correction Deactivated, must be in 32 or 16 bit mode");
}
}
} }
std::string Module::printReceiverConfiguration() { std::string Module::printReceiverConfiguration() {
@ -3052,38 +2848,6 @@ void Module::execReceiverCommand(const std::string &cmd) {
} }
} }
void Module::sendMultiDetectorSize() {
int args[]{shm()->multiSize.x, shm()->multiSize.y};
int retval = -1;
LOG(logDEBUG1) << "Sending multi detector size to receiver: ("
<< shm()->multiSize.x << "," << shm()->multiSize.y
<< ")";
if (shm()->useReceiverFlag) {
sendToReceiver(F_SEND_RECEIVER_MULTIDETSIZE, args, retval);
LOG(logDEBUG1) << "Receiver multi size returned: " << retval;
}
}
void Module::setDetectorId() {
LOG(logDEBUG1) << "Sending detector pos id to receiver: " << detId;
if (shm()->useReceiverFlag) {
int retval = -1;
sendToReceiver(F_SEND_RECEIVER_DETPOSID, detId, retval);
LOG(logDEBUG1) << "Receiver Position Id returned: " << retval;
}
}
void Module::setDetectorHostname() {
char args[MAX_STR_LENGTH]{};
char retvals[MAX_STR_LENGTH]{};
sls::strcpy_safe(args, shm()->hostname);
LOG(logDEBUG1) << "Sending detector hostname to receiver: " << args;
if (shm()->useReceiverFlag) {
sendToReceiver(F_SEND_RECEIVER_DETHOSTNAME, args, retvals);
LOG(logDEBUG1) << "Receiver set detector hostname: " << retvals;
}
}
std::string Module::getFilePath() { std::string Module::getFilePath() {
if (!shm()->useReceiverFlag) { if (!shm()->useReceiverFlag) {
throw RuntimeError("Set rx_hostname first to use receiver parameters (file path)"); throw RuntimeError("Set rx_hostname first to use receiver parameters (file path)");
@ -3281,6 +3045,15 @@ uint64_t Module::getReceiverCurrentFrameIndex() const {
return retval; return retval;
} }
int Module::getReceiverProgress() const {
int retval = -1;
if (shm()->useReceiverFlag) {
sendToReceiver(F_GET_RECEIVER_PROGRESS, nullptr, retval);
LOG(logDEBUG1) << "Current Progress of Receiver: " << retval;
}
return retval;
}
void Module::setFileWrite(bool value) { void Module::setFileWrite(bool value) {
if (!shm()->useReceiverFlag) { if (!shm()->useReceiverFlag) {
throw RuntimeError("Set rx_hostname first to use receiver parameters (file write enable)"); throw RuntimeError("Set rx_hostname first to use receiver parameters (file write enable)");
@ -3372,6 +3145,10 @@ bool Module::enableTenGigabitEthernet(int value) {
int retval = -1; int retval = -1;
LOG(logDEBUG1) << "Enabling / Disabling 10Gbe: " << value; LOG(logDEBUG1) << "Enabling / Disabling 10Gbe: " << value;
sendToDetector(F_ENABLE_TEN_GIGA, value, retval); sendToDetector(F_ENABLE_TEN_GIGA, value, retval);
if (value != -1) {
int stopRetval = -1;
sendToDetectorStop(F_ENABLE_TEN_GIGA, value, stopRetval);
}
LOG(logDEBUG1) << "10Gbe: " << retval; LOG(logDEBUG1) << "10Gbe: " << retval;
value = retval; value = retval;
if (shm()->useReceiverFlag && value != -1) { if (shm()->useReceiverFlag && value != -1) {
@ -3615,10 +3392,6 @@ void Module::setPipeline(int clkIndex, int value) {
void Module::setCounterMask(uint32_t countermask) { void Module::setCounterMask(uint32_t countermask) {
LOG(logDEBUG1) << "Setting Counter mask to " << countermask; LOG(logDEBUG1) << "Setting Counter mask to " << countermask;
sendToDetector(F_SET_COUNTER_MASK, countermask, nullptr); sendToDetector(F_SET_COUNTER_MASK, countermask, nullptr);
sendNumberofCounterstoReceiver(countermask);
}
void Module::sendNumberofCounterstoReceiver(uint32_t countermask) {
if (shm()->useReceiverFlag) { if (shm()->useReceiverFlag) {
int ncounters = __builtin_popcount(countermask); int ncounters = __builtin_popcount(countermask);
LOG(logDEBUG1) << "Sending Reciver #counters: " << ncounters; LOG(logDEBUG1) << "Sending Reciver #counters: " << ncounters;

View File

@ -14,7 +14,7 @@
class ServerInterface; class ServerInterface;
#define SLS_SHMAPIVERSION 0x190726 #define SLS_SHMAPIVERSION 0x190726
#define SLS_SHMVERSION 0x200324 #define SLS_SHMVERSION 0x200402
namespace sls{ namespace sls{
@ -62,33 +62,6 @@ struct sharedSlsDetector {
/** number of dacs per module*/ /** number of dacs per module*/
int nDacs; int nDacs;
/** dynamic range of the detector data */
int dynamicRange;
/** detector settings (standard, fast, etc.) */
slsDetectorDefs::detectorSettings currentSettings;
/** number of frames */
int64_t nFrames;
/** number of triggers */
int64_t nTriggers;
/** number of bursts */
int64_t nBursts;
/** number of additional storage cells */
int nAddStorageCells;
/** timing mode */
slsDetectorDefs::timingMode timingMode;
/** burst mode */
slsDetectorDefs::burstMode burstMode;
/** rate correction in ns (needed for default -1) */
int64_t deadTime;
/** ip address/hostname of the receiver for client control via TCP */ /** ip address/hostname of the receiver for client control via TCP */
char rxHostname[MAX_STR_LENGTH]; char rxHostname[MAX_STR_LENGTH];
@ -203,13 +176,6 @@ class Module : public virtual slsDetectorDefs {
*/ */
detectorType getDetectorType() const; detectorType getDetectorType() const;
/**
* Gets detector type from detector and set it in receiver
* @param type the detector type
* @returns detector type in receiver
*/
int setDetectorType(detectorType type = GET_DETECTOR_TYPE);
/** /**
* Update total number of channels (chiptestboard or moench) * Update total number of channels (chiptestboard or moench)
* from the detector server * from the detector server
@ -298,21 +264,12 @@ class Module : public virtual slsDetectorDefs {
*/ */
void execCommand(const std::string &cmd); void execCommand(const std::string &cmd);
/**
* Updates some of the shared memory receiving the data from the detector
*/
void updateCachedDetectorVariables();
/** /**
* Get detector specific commands to write into config file * Get detector specific commands to write into config file
* @returns vector of strings with commands * @returns vector of strings with commands
*/ */
std::vector<std::string> getConfigFileCommands(); std::vector<std::string> getConfigFileCommands();
/**
* Get detector settings
* @returns current settings
*/
detectorSettings getSettings(); detectorSettings getSettings();
/** [Jungfrau] Options:DYNAMICGAIN, DYNAMICHG0, FIXGAIN1, FIXGAIN2, FORCESWITCHG1, FORCESWITCHG2 /** [Jungfrau] Options:DYNAMICGAIN, DYNAMICHG0, FIXGAIN1, FIXGAIN2, FORCESWITCHG1, FORCESWITCHG2
@ -320,18 +277,8 @@ class Module : public virtual slsDetectorDefs {
* [Gotthard2] Options: DYNAMICGAIN, FIXGAIN1, FIXGAIN2 * [Gotthard2] Options: DYNAMICGAIN, FIXGAIN1, FIXGAIN2
* [Moench] Options: G1_HIGHGAIN, G1_LOWGAIN, G2_HIGHCAP_HIGHGAIN, G2_HIGHCAP_LOWGAIN, * [Moench] Options: G1_HIGHGAIN, G1_LOWGAIN, G2_HIGHCAP_HIGHGAIN, G2_HIGHCAP_LOWGAIN,
* G2_LOWCAP_HIGHGAIN, G2_LOWCAP_LOWGAIN, G4_HIGHGAIN, G4_LOWGAIN * G2_LOWCAP_HIGHGAIN, G2_LOWCAP_LOWGAIN, G4_HIGHGAIN, G4_LOWGAIN
* [Eiger] Only stores them locally in shm Options: STANDARD, HIGHGAIN, LOWGAIN, VERYHIGHGAIN, VERYLOWGAIN
*/ */
detectorSettings setSettings(detectorSettings isettings); void setSettings(detectorSettings isettings);
/**
* Send detector settings only (set only for Jungfrau, Gotthard, Moench, get
* for all) Only the settings enum is sent to the detector, where it will
* initialize al the dacs already hard coded in the detector server
* @param isettings settings
* @returns current settings
*/
detectorSettings sendSettingsOnly(detectorSettings isettings);
/** /**
* Get threshold energy (Mythen and Eiger) * Get threshold energy (Mythen and Eiger)
@ -445,10 +392,6 @@ class Module : public virtual slsDetectorDefs {
*/ */
uint64_t getStartingFrameNumber(); uint64_t getStartingFrameNumber();
int64_t getTotalNumFramesToReceive();
void sendTotalNumFramestoReceiver();
int64_t getNumberOfFrames(); int64_t getNumberOfFrames();
void setNumberOfFrames(int64_t value); void setNumberOfFrames(int64_t value);
@ -556,22 +499,17 @@ class Module : public virtual slsDetectorDefs {
* [Gotthard2] only in continuous mode */ * [Gotthard2] only in continuous mode */
int64_t getMeasurementTime() const; int64_t getMeasurementTime() const;
/**
* Set/get timing mode
* @param value timing mode (-1 gets)
* @returns current timing mode
*/
timingMode setTimingMode(timingMode value = GET_TIMING_MODE);
timingMode getTimingMode();
void setTimingMode(timingMode value);
int getDynamicRange();
/** /**
* Set/get dynamic range * Set/get dynamic range
* (Eiger: If i is 32, also sets clkdivider to 2, if 16, sets clkdivider to * (Eiger: If i is 32, also sets clkdivider to 2, if 16, sets clkdivider to
* 1) * 1)
* @param i dynamic range (-1 get)
* @returns current dynamic range
* \sa sharedSlsDetector
*/ */
int setDynamicRange(int n = -1); void setDynamicRange(int n);
/** /**
* Set/get dacs value * Set/get dacs value
@ -702,10 +640,10 @@ class Module : public virtual slsDetectorDefs {
* significant for the receiver Also configures the detector to the receiver * significant for the receiver Also configures the detector to the receiver
* as UDP destination * as UDP destination
* @param receiver receiver hostname or IP address * @param receiver receiver hostname or IP address
* @returns the receiver IP address from shared memory
*/ */
std::string setReceiverHostname(const std::string &receiver); void setReceiverHostname(const std::string &receiver);
void test();
/** /**
* Returns the receiver IP address\sa sharedSlsDetector * Returns the receiver IP address\sa sharedSlsDetector
* @returns the receiver IP address * @returns the receiver IP address
@ -776,13 +714,6 @@ class Module : public virtual slsDetectorDefs {
*/ */
sls::IpAddr getDestinationUDPIP(); sls::IpAddr getDestinationUDPIP();
/**
* Gets destination udp ip from detector,
* if 0, it converts rx_hostname to ip and
* updates both detector and receiver
*/
void updateRxDestinationUDPIP();
/** /**
* Validates the format of the receiver UDP IP address (bottom half) and * Validates the format of the receiver UDP IP address (bottom half) and
* sets it(Jungfrau only) * sets it(Jungfrau only)
@ -798,13 +729,6 @@ class Module : public virtual slsDetectorDefs {
*/ */
sls::IpAddr getDestinationUDPIP2(); sls::IpAddr getDestinationUDPIP2();
/**
* Gets destination udp ip2 from detector,
* if 0, it converts rx_hostname to ip and
* updates both detector and receiver
*/
void updateRxDestinationUDPIP2();
/** /**
* Validates the format of the receiver UDP MAC address and sets it * Validates the format of the receiver UDP MAC address and sets it
* @param mac receiver UDP MAC address * @param mac receiver UDP MAC address
@ -1399,26 +1323,6 @@ class Module : public virtual slsDetectorDefs {
*/ */
void execReceiverCommand(const std::string &cmd); void execReceiverCommand(const std::string &cmd);
/**
* Send the multi detector size to the detector
* @param detx number of detectors in x dir
* @param dety number of detectors in y dir
*/
void sendMultiDetectorSize();
/**
* Send the detector pos id to the receiver
* for various file naming conventions for multi detectors in receiver
*/
void setDetectorId();
/**
* Send the detector host name to the receiver
* for various handshaking required with the detector
*/
void setDetectorHostname();
std::string getFilePath(); std::string getFilePath();
void setFilePath(const std::string &path); void setFilePath(const std::string &path);
std::string getFileName(); std::string getFileName();
@ -1467,6 +1371,7 @@ class Module : public virtual slsDetectorDefs {
* @returns current frame index of receiver * @returns current frame index of receiver
*/ */
uint64_t getReceiverCurrentFrameIndex() const; uint64_t getReceiverCurrentFrameIndex() const;
int getReceiverProgress() const;
void setFileWrite(bool value); void setFileWrite(bool value);
@ -1660,9 +1565,6 @@ class Module : public virtual slsDetectorDefs {
/** [Mythen3] */ /** [Mythen3] */
void setCounterMask(uint32_t countermask); void setCounterMask(uint32_t countermask);
/** [Mythen3] */
void sendNumberofCounterstoReceiver(uint32_t countermask);
/** [Mythen3] */ /** [Mythen3] */
uint32_t getCounterMask(); uint32_t getCounterMask();

View File

@ -15,7 +15,9 @@ using sls::Detector;
using test::GET; using test::GET;
using test::PUT; using test::PUT;
TEST_CASE("Setting and reading back Chip test board dacs", "[.cmd][.dacs]") { /* dacs */
TEST_CASE("Setting and reading back Chip test board dacs", "[.cmd][.dacs][.new]") {
// dac 0 to dac 17 // dac 0 to dac 17
Detector det; Detector det;
@ -23,12 +25,12 @@ TEST_CASE("Setting and reading back Chip test board dacs", "[.cmd][.dacs]") {
auto det_type = det.getDetectorType().squash(); auto det_type = det.getDetectorType().squash();
if (det_type == defs::CHIPTESTBOARD) { if (det_type == defs::CHIPTESTBOARD) {
for (int i = 0; i < 18; ++i) { for (int i = 0; i < 18; ++i) {
SECTION("dac " + std::to_string(i)) { test_dac(static_cast<defs::dacIndex>(i), "dac " + std::to_string(i), 0); } SECTION("dac " + std::to_string(i)) { test_dac(static_cast<defs::dacIndex>(i), "dac", 0); }
} }
// eiger // eiger
REQUIRE_THROWS(proxy.Call("vthreshold", {}, -1, GET)); //REQUIRE_THROWS(proxy.Call("vthreshold", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vsvp", {}, -1, GET)); //REQUIRE_THROWS(proxy.Call("vsvp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vsvn", {}, -1, GET)); //REQUIRE_THROWS(proxy.Call("vsvn", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vtr", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vtr", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vrf", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vrf", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vrs", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vrs", {}, -1, GET));
@ -51,30 +53,30 @@ TEST_CASE("Setting and reading back Chip test board dacs", "[.cmd][.dacs]") {
REQUIRE_THROWS(proxy.Call("vref_prech", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vref_prech", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_pixbuf", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vb_pixbuf", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_ds", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vb_ds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET)); //REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET)); //REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET));
// gotthard // gotthard
REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET)); //REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcascn_pb", {}, -1, GET)); //REQUIRE_THROWS(proxy.Call("vcascn_pb", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcascp_pb", {}, -1, GET)); //REQUIRE_THROWS(proxy.Call("vcascp_pb", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vout_cm", {}, -1, GET)); //REQUIRE_THROWS(proxy.Call("vout_cm", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcasc_out", {}, -1, GET)); //REQUIRE_THROWS(proxy.Call("vcasc_out", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vin_cm", {}, -1, GET)); //REQUIRE_THROWS(proxy.Call("vin_cm", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET)); //REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("ib_test_c", {}, -1, GET)); //REQUIRE_THROWS(proxy.Call("ib_test_c", {}, -1, GET));
// mythen3 // mythen3
REQUIRE_THROWS(proxy.Call("vpreamp", {}, -1, GET)); //REQUIRE_THROWS(proxy.Call("vpreamp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vshaper", {}, -1, GET)); //REQUIRE_THROWS(proxy.Call("vshaper", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vshaperneg", {}, -1, GET)); //REQUIRE_THROWS(proxy.Call("vshaperneg", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vipre", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vipre", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("viinsh", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("viinsh", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vdcsh", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vdcsh", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vth1", {}, -1, GET)); //REQUIRE_THROWS(proxy.Call("vth1", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vth2", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vth2", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vth3", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vth3", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vpl", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vpl", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vph", {}, -1, GET)); //REQUIRE_THROWS(proxy.Call("vph", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vtrim", {}, -1, GET)); //REQUIRE_THROWS(proxy.Call("vtrim", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcassh", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vcassh", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcas", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vcas", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vicin", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vicin", {}, -1, GET));

View File

@ -13,6 +13,245 @@ using sls::CmdProxy;
using sls::Detector; using sls::Detector;
using test::GET; using test::GET;
using test::PUT; using test::PUT;
/** temperature */
TEST_CASE("temp_fpgaext", "[.cmd][.new]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
REQUIRE_NOTHROW(proxy.Call("temp_fpgaext", {}, -1, GET));
std::ostringstream oss;
REQUIRE_NOTHROW(proxy.Call("temp_fpgaext", {}, 0, GET, oss));
std::string s = (oss.str()).erase (0, strlen("temp_fpgaext "));
REQUIRE(std::stoi(s) != -1);
} else {
REQUIRE_THROWS(proxy.Call("temp_fpgaext", {}, -1, GET));
}
}
TEST_CASE("temp_10ge", "[.cmd][.new]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
REQUIRE_NOTHROW(proxy.Call("temp_10ge", {}, -1, GET));
std::ostringstream oss;
REQUIRE_NOTHROW(proxy.Call("temp_10ge", {}, 0, GET, oss));
std::string s = (oss.str()).erase (0, strlen("temp_10ge "));
REQUIRE(std::stoi(s) != -1);
} else {
REQUIRE_THROWS(proxy.Call("temp_10ge", {}, -1, GET));
}
}
TEST_CASE("temp_dcdc", "[.cmd][.new]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
REQUIRE_NOTHROW(proxy.Call("temp_dcdc", {}, -1, GET));
std::ostringstream oss;
REQUIRE_NOTHROW(proxy.Call("temp_dcdc", {}, 0, GET, oss));
std::string s = (oss.str()).erase (0, strlen("temp_dcdc "));
REQUIRE(std::stoi(s) != -1);
} else {
REQUIRE_THROWS(proxy.Call("temp_dcdc", {}, -1, GET));
}
}
TEST_CASE("temp_sodl", "[.cmd][.new]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
REQUIRE_NOTHROW(proxy.Call("temp_sodl", {}, -1, GET));
std::ostringstream oss;
REQUIRE_NOTHROW(proxy.Call("temp_sodl", {}, 0, GET, oss));
std::string s = (oss.str()).erase (0, strlen("temp_sodl "));
REQUIRE(std::stoi(s) != -1);
} else {
REQUIRE_THROWS(proxy.Call("temp_sodl", {}, -1, GET));
}
}
TEST_CASE("temp_sodr", "[.cmd][.new]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
REQUIRE_NOTHROW(proxy.Call("temp_sodr", {}, -1, GET));
std::ostringstream oss;
REQUIRE_NOTHROW(proxy.Call("temp_sodr", {}, 0, GET, oss));
std::string s = (oss.str()).erase (0, strlen("temp_sodr "));
REQUIRE(std::stoi(s) != -1);
} else {
REQUIRE_THROWS(proxy.Call("temp_sodr", {}, -1, GET));
}
}
TEST_CASE("temp_fpgafl", "[.cmd][.new]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
REQUIRE_NOTHROW(proxy.Call("temp_fpgafl", {}, -1, GET));
std::ostringstream oss;
REQUIRE_NOTHROW(proxy.Call("temp_fpgafl", {}, 0, GET, oss));
std::string s = (oss.str()).erase (0, strlen("temp_fpgafl "));
REQUIRE(std::stoi(s) != -1);
} else {
REQUIRE_THROWS(proxy.Call("temp_fpgafl", {}, -1, GET));
}
}
TEST_CASE("temp_fpgafr", "[.cmd][.new]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
REQUIRE_NOTHROW(proxy.Call("temp_fpgafr", {}, -1, GET));
std::ostringstream oss;
REQUIRE_NOTHROW(proxy.Call("temp_fpgafr", {}, 0, GET, oss));
std::string s = (oss.str()).erase (0, strlen("temp_fpgafr "));
REQUIRE(std::stoi(s) != -1);
} else {
REQUIRE_THROWS(proxy.Call("temp_fpgafr", {}, -1, GET));
}
}
/* dacs */
TEST_CASE("Setting and reading back EIGER dacs", "[.cmd][.dacs][.new]") {
// vsvp, vtr, vrf, vrs, vsvn, vtgstv, vcmp_ll, vcmp_lr, vcal, vcmp_rl,
// rxb_rb, rxb_lb, vcmp_rr, vcp, vcn, vis, vthreshold
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
SECTION("vsvp") { test_dac(defs::SVP, "vsvp", 5); }
SECTION("vtr") { test_dac(defs::VRF, "vtr", 1200); }
SECTION("vrf") { test_dac(defs::VRF, "vrf", 1500); }
SECTION("vrs") { test_dac(defs::VRF, "vrs", 1510); }
SECTION("vsvn") { test_dac(defs::SVN, "vsvn", 3800); }
SECTION("vtgstv") { test_dac(defs::VTGSTV, "vtgstv", 2550); }
SECTION("vcmp_ll") { test_dac(defs::VCMP_LL, "vcmp_ll", 1400); }
SECTION("vcmp_lr") { test_dac(defs::VCMP_LR, "vcmp_lr", 1400); }
SECTION("vcal") { test_dac(defs::CAL, "vcal", 1400); }
SECTION("vcmp_rl") { test_dac(defs::VCMP_RL, "vcmp_rl", 1400); }
SECTION("rxb_rb") { test_dac(defs::RXB_RB, "rxb_rb", 1400); }
SECTION("rxb_lb") { test_dac(defs::RXB_LB, "rxb_lb", 1400); }
SECTION("vcmp_rr") { test_dac(defs::VCMP_RR, "vcmp_rr", 1400); }
SECTION("vcp") { test_dac(defs::VCP, "vcp", 1400); }
SECTION("vcn") { test_dac(defs::VCN, "vcn", 1400); }
SECTION("vis") { test_dac(defs::VIS, "vis", 1400); }
SECTION("iodelay") { test_dac(defs::IO_DELAY, "iodelay", 1400); }
SECTION("vthreshold") {
// Read out individual vcmp to be able to reset after
// the test is done
auto vcmp_ll = det.getDAC(defs::VCMP_LL, false);
auto vcmp_lr = det.getDAC(defs::VCMP_LR, false);
auto vcmp_rl = det.getDAC(defs::VCMP_RL, false);
auto vcmp_rr = det.getDAC(defs::VCMP_RR, false);
auto vcp = det.getDAC(defs::VCP, false);
{
std::ostringstream oss;
proxy.Call("vthreshold", {"1234"}, -1, PUT, oss);
REQUIRE(oss.str() == "vthreshold 1234\n");
}
{
std::ostringstream oss;
proxy.Call("vthreshold", {}, -1, GET, oss);
REQUIRE(oss.str() == "vthreshold 1234\n");
}
// Reset dacs after test
for (int i = 0; i != det.size(); ++i) {
det.setDAC(defs::VCMP_LL, vcmp_ll[i], false, {i});
det.setDAC(defs::VCMP_LR, vcmp_ll[i], false, {i});
det.setDAC(defs::VCMP_RL, vcmp_ll[i], false, {i});
det.setDAC(defs::VCMP_RR, vcmp_ll[i], false, {i});
det.setDAC(defs::VCP, vcp[i], false, {i});
}
}
// gotthard
REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcascn_pb", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcascp_pb", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vout_cm", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcasc_out", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vin_cm", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("ib_test_c", {}, -1, GET));
// mythen3
REQUIRE_THROWS(proxy.Call("vpreamp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vshaper", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vshaperneg", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vipre", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("viinsh", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vdcsh", {}, -1, GET));
// REQUIRE_THROWS(proxy.Call("vth1", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vth2", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vth3", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vpl", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vph", {}, -1, GET));
// REQUIRE_THROWS(proxy.Call("vtrim", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcassh", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcas", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vicin", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vipre_out", {}, -1, GET));
// gotthard2
REQUIRE_THROWS(proxy.Call("vref_h_adc", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_comp_fe", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_comp_adc", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcom_cds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_rstore", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_opa_1st", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_comp_fe", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcom_adc1", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_l_adc", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_cds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_cs", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_opa_fd", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcom_adc2", {}, -1, GET));
// jungfrau
REQUIRE_THROWS(proxy.Call("vb_comp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vdd_prot", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vin_com", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_prech", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_pixbuf", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_ds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET));
}
}
TEST_CASE("Eiger transmission delay", "[.cmd]") { TEST_CASE("Eiger transmission delay", "[.cmd]") {
Detector det; Detector det;
@ -280,110 +519,7 @@ TEST_CASE("quad", "[.cmd]") {
} }
} }
TEST_CASE("Setting and reading back EIGER dacs", "[.cmd][.dacs]") {
// vsvp, vtr, vrf, vrs, vsvn, vtgstv, vcmp_ll, vcmp_lr, vcal, vcmp_rl,
// rxb_rb, rxb_lb, vcmp_rr, vcp, vcn, vis, vthreshold
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
SECTION("vsvp") { test_dac(defs::SVP, "vsvp", 5); }
SECTION("vtr") { test_dac(defs::VRF, "vtr", 1200); }
SECTION("vrf") { test_dac(defs::VRF, "vrf", 1500); }
SECTION("vrs") { test_dac(defs::VRF, "vrs", 1510); }
SECTION("vsvn") { test_dac(defs::SVN, "vsvn", 3800); }
SECTION("vtgstv") { test_dac(defs::VTGSTV, "vtgstv", 2550); }
SECTION("vcmp_ll") { test_dac(defs::VCMP_LL, "vcmp_ll", 1400); }
SECTION("vcmp_lr") { test_dac(defs::VCMP_LR, "vcmp_lr", 1400); }
SECTION("vcal") { test_dac(defs::CAL, "vcal", 1400); }
SECTION("vcmp_rl") { test_dac(defs::VCMP_RL, "vcmp_rl", 1400); }
SECTION("rxb_rb") { test_dac(defs::RXB_RB, "rxb_rb", 1400); }
SECTION("rxb_lb") { test_dac(defs::RXB_LB, "rxb_lb", 1400); }
SECTION("vcmp_rr") { test_dac(defs::VCMP_RR, "vcmp_rr", 1400); }
SECTION("vcp") { test_dac(defs::VCP, "vcp", 1400); }
SECTION("vcn") { test_dac(defs::VCN, "vcn", 1400); }
SECTION("vis") { test_dac(defs::VIS, "vis", 1400); }
SECTION("iodelay") { test_dac(defs::IO_DELAY, "iodelay", 1400); }
SECTION("vthreshold") {
// Read out individual vcmp to be able to reset after
// the test is done
auto vcmp_ll = det.getDAC(defs::VCMP_LL, false);
auto vcmp_lr = det.getDAC(defs::VCMP_LR, false);
auto vcmp_rl = det.getDAC(defs::VCMP_RL, false);
auto vcmp_rr = det.getDAC(defs::VCMP_RR, false);
auto vcp = det.getDAC(defs::VCP, false);
{
std::ostringstream oss;
proxy.Call("vthreshold", {"1234"}, -1, PUT, oss);
REQUIRE(oss.str() == "vthreshold 1234\n");
}
{
std::ostringstream oss;
proxy.Call("vthreshold", {}, -1, GET, oss);
REQUIRE(oss.str() == "vthreshold 1234\n");
}
// Reset dacs after test
for (int i = 0; i != det.size(); ++i) {
det.setDAC(defs::VCMP_LL, vcmp_ll[i], false, {i});
det.setDAC(defs::VCMP_LR, vcmp_ll[i], false, {i});
det.setDAC(defs::VCMP_RL, vcmp_ll[i], false, {i});
det.setDAC(defs::VCMP_RR, vcmp_ll[i], false, {i});
det.setDAC(defs::VCP, vcp[i], false, {i});
}
}
// gotthard
REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcascn_pb", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcascp_pb", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vout_cm", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcasc_out", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vin_cm", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("ib_test_c", {}, -1, GET));
// mythen3
REQUIRE_THROWS(proxy.Call("vpreamp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vshaper", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vshaperneg", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vipre", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("viinsh", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vdcsh", {}, -1, GET));
// REQUIRE_THROWS(proxy.Call("vth1", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vth2", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vth3", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vpl", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vph", {}, -1, GET));
// REQUIRE_THROWS(proxy.Call("vtrim", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcassh", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcas", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vicin", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vipre_out", {}, -1, GET));
// gotthard2
REQUIRE_THROWS(proxy.Call("vref_h_adc", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_comp_fe", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_comp_adc", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcom_cds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_rstore", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_opa_1st", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_comp_fe", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcom_adc1", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_l_adc", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_cds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_cs", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_opa_fd", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcom_adc2", {}, -1, GET));
// jungfrau
REQUIRE_THROWS(proxy.Call("vb_comp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vdd_prot", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vin_com", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_prech", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_pixbuf", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_ds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET));
}
}
// TEST_CASE("trigger", "[.cmd]") { // TEST_CASE("trigger", "[.cmd]") {
// Detector det; // Detector det;

View File

@ -16,12 +16,46 @@ void test_dac(defs::dacIndex index, const std::string &dacname, int dacvalue) {
std::ostringstream oss_set, oss_get; std::ostringstream oss_set, oss_get;
auto dacstr = std::to_string(dacvalue); auto dacstr = std::to_string(dacvalue);
auto previous = det.getDAC(index, false); auto previous = det.getDAC(index, false);
proxy.Call(dacname, {dacstr}, -1, PUT, oss_set); // chip test board
REQUIRE(oss_set.str() == dacname + " " + dacstr + "\n"); if (dacname == "dac") {
proxy.Call(dacname, {}, -1, GET, oss_get); auto dacIndexstr = std::to_string(static_cast<int>(index));
REQUIRE(oss_get.str() == dacname + " " + dacstr + "\n"); proxy.Call(dacname, {dacIndexstr, dacstr}, -1, PUT, oss_set);
REQUIRE(oss_set.str() == dacname + " " + dacIndexstr + " " + dacstr + "\n");
proxy.Call(dacname, {dacIndexstr}, -1, GET, oss_get);
REQUIRE(oss_get.str() == dacname + " " + dacIndexstr + " " + dacstr + "\n");
}
// other detectors
else {
proxy.Call(dacname, {dacstr}, -1, PUT, oss_set);
REQUIRE(oss_set.str() == dacname + " " + dacstr + "\n");
proxy.Call(dacname, {}, -1, GET, oss_get);
REQUIRE(oss_get.str() == dacname + " " + dacstr + "\n");
}
// Reset all dacs to previous value // Reset all dacs to previous value
for (int i = 0; i != det.size(); ++i) { for (int i = 0; i != det.size(); ++i) {
det.setDAC(index, previous[i], false, {i}); det.setDAC(index, previous[i], false, {i});
} }
} }
void test_onchip_dac(defs::dacIndex index, const std::string &dacname, int dacvalue) {
Detector det;
CmdProxy proxy(&det);
REQUIRE_THROWS(proxy.Call(dacname, {}, -1, GET));
REQUIRE_THROWS(proxy.Call(dacname, {"10", "0x0"}, -1, PUT)); // chip index (-1 to 9)
REQUIRE_THROWS(proxy.Call(dacname, {"-1", "0x400"}, -1, PUT)); // max val is 0x3ff
int chipIndex = -1; // for now, it is -1 only
auto prev_val = det.getOnChipDAC(index, chipIndex);
auto dacValueStr = sls::ToStringHex(dacvalue);
auto chipIndexStr = std::to_string(chipIndex);
std::ostringstream oss_set, oss_get;
proxy.Call(dacname, {chipIndexStr, dacValueStr}, -1, PUT, oss_set);
REQUIRE(oss_set.str() == dacname + " " + chipIndexStr + " " + dacValueStr + "\n");
proxy.Call(dacname, {chipIndexStr}, -1, GET, oss_get);
REQUIRE(oss_get.str() == dacname + " " + chipIndexStr + " " + dacValueStr + "\n");
// Reset all dacs to previous value
for (int i = 0; i != det.size(); ++i) {
det.setOnChipDAC(index, chipIndex, prev_val[i], {i});
}
}

View File

@ -2,3 +2,4 @@
#include "sls_detector_defs.h" #include "sls_detector_defs.h"
void test_dac(slsDetectorDefs::dacIndex index, const std::string &dacname, int dacvalue); void test_dac(slsDetectorDefs::dacIndex index, const std::string &dacname, int dacvalue);
void test_onchip_dac(slsDetectorDefs::dacIndex index, const std::string &dacname, int dacvalue);

View File

@ -15,7 +15,9 @@ using sls::Detector;
using test::GET; using test::GET;
using test::PUT; using test::PUT;
TEST_CASE("Setting and reading back GOTTHARD dacs", "[.cmd][.dacs]") { /* dacs */
TEST_CASE("Setting and reading back GOTTHARD dacs", "[.cmd][.dacs][.new]") {
// vref_ds, vcascn_pb, vcascp_pb, vout_cm, vcasc_out, vin_cm, vref_comp, ib_test_c // vref_ds, vcascn_pb, vcascp_pb, vout_cm, vcasc_out, vin_cm, vref_comp, ib_test_c
Detector det; Detector det;

View File

@ -88,17 +88,9 @@ TEST_CASE("bursts", "[.cmd][.new]") {
} }
} }
/* dacs */
TEST_CASE("Setting and reading back GOTTHARD2 dacs", "[.cmd][.dacs][.new]") {
TEST_CASE("Setting and reading back GOTTHARD2 dacs", "[.cmd][.dacs]") {
// vref_h_adc, vb_comp_fe, vb_comp_adc, vcom_cds, // vref_h_adc, vb_comp_fe, vb_comp_adc, vcom_cds,
// vref_restore, vb_opa_1st, vref_comp_fe, vcom_adc1, // vref_restore, vb_opa_1st, vref_comp_fe, vcom_adc1,
// vref_prech, vref_l_adc, vref_cds, vb_cs, // vref_prech, vref_l_adc, vref_cds, vb_cs,
@ -179,46 +171,90 @@ TEST_CASE("Setting and reading back GOTTHARD2 dacs", "[.cmd][.dacs]") {
} }
} }
TEST_CASE("vchip", "[.cmd][.onchipdacs]") { /* on chip dacs */
TEST_CASE("vchip_comp_fe", "[.cmd][.onchipdacs][.new]") {
Detector det; Detector det;
CmdProxy proxy(&det); CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash(); auto det_type = det.getDetectorType().squash();
if (det_type == defs::GOTTHARD2) { if (det_type == defs::GOTTHARD2) {
std::vector<std::string> on_chip_dac_names = {"vchip_comp_fe", "vchip_opa_1st", "vchip_opa_fd", "vchip_comp_adc", "vchip_ref_comp_fe", "vchip_cs"}; SECTION("vchip_comp_fe") { test_onchip_dac(defs::VB_COMP_FE, "vchip_comp_fe", 0x137); }
std::vector<defs::dacIndex> on_chip_dac_indices = {defs::VB_COMP_FE, defs::VB_OPA_1ST, defs::VB_OPA_FD, defs::VB_COMP_ADC, defs::VREF_COMP_FE, defs::VB_CS};
std::vector<int> values = {0x137, 0x000, 0x134, 0x3FF, 0x100, 0x0D0};
for (size_t i = 0; i < on_chip_dac_names.size(); ++i) {
REQUIRE_THROWS(proxy.Call(on_chip_dac_names[i], {}, -1, GET));
REQUIRE_THROWS(proxy.Call(on_chip_dac_names[i], {"10", "0x0"}, -1, GET)); // chip index (-1 to 9)
REQUIRE_THROWS(proxy.Call(on_chip_dac_names[i], {"-1", "0x400"}, -1, GET)); // max val is 0x3ff
auto previous = det.getOnChipDAC(on_chip_dac_indices[i], -1);
auto dacstr = sls::ToStringHex(values[i]);
int chip_index = -1;
auto chip_index_str = std::to_string(chip_index);
std::ostringstream oss_set, oss_get;
proxy.Call(on_chip_dac_names[i], {chip_index_str, dacstr}, -1, PUT, oss_set);
REQUIRE(oss_set.str() == on_chip_dac_names[i] + " " + chip_index_str + " " + dacstr + "\n");
proxy.Call(on_chip_dac_names[i], {chip_index_str}, -1, GET, oss_get);
REQUIRE(oss_get.str() == on_chip_dac_names[i] + " " + chip_index_str + " " + dacstr + "\n");
// Reset all dacs to previous value
for (int i = 0; i != det.size(); ++i) {
det.setOnChipDAC(on_chip_dac_indices[i], chip_index, previous[i], {i});
}
}
} else { } else {
REQUIRE_THROWS(proxy.Call("vchip_comp_fe", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vchip_comp_fe", {}, -1, GET));
}
}
TEST_CASE("vchip_opa_1st", "[.cmd][.onchipdacs][.new]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::GOTTHARD2) {
SECTION("vchip_opa_1st") { test_onchip_dac(defs::VB_OPA_1ST, "vchip_opa_1st", 0x000); }
} else {
REQUIRE_THROWS(proxy.Call("vchip_opa_1st", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vchip_opa_1st", {}, -1, GET));
}
}
TEST_CASE("vchip_opa_fd", "[.cmd][.onchipdacs][.new]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::GOTTHARD2) {
SECTION("vchip_opa_fd") { test_onchip_dac(defs::VB_OPA_FD, "vchip_opa_fd", 0x134); }
} else {
REQUIRE_THROWS(proxy.Call("vchip_opa_fd", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vchip_opa_fd", {}, -1, GET));
}
}
TEST_CASE("vchip_comp_adc", "[.cmd][.onchipdacs][.new]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::GOTTHARD2) {
SECTION("vchip_comp_adc") { test_onchip_dac(defs::VB_COMP_ADC, "vchip_comp_adc", 0x3FF); }
} else {
REQUIRE_THROWS(proxy.Call("vchip_comp_adc", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vchip_comp_adc", {}, -1, GET));
}
}
TEST_CASE("vchip_ref_comp_fe", "[.cmd][.onchipdacs][.new]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::GOTTHARD2) {
SECTION("vchip_ref_comp_fe") { test_onchip_dac(defs::VREF_COMP_FE, "vchip_ref_comp_fe", 0x100); }
} else {
REQUIRE_THROWS(proxy.Call("vchip_ref_comp_fe", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vchip_ref_comp_fe", {}, -1, GET));
}
}
TEST_CASE("vchip_cs", "[.cmd][.onchipdacs][.new]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::GOTTHARD2) {
SECTION("vchip_cs") { test_onchip_dac(defs::VB_CS, "vchip_cs", 0x0D0); }
} else {
REQUIRE_THROWS(proxy.Call("vchip_cs", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vchip_cs", {}, -1, GET));
} }
} }
TEST_CASE("burstmode", "[.cmd]") { TEST_CASE("burstmode", "[.cmd]") {
Detector det; Detector det;
CmdProxy proxy(&det); CmdProxy proxy(&det);

View File

@ -13,38 +13,116 @@ using sls::Detector;
using test::GET; using test::GET;
using test::PUT; using test::PUT;
TEST_CASE("powerchip", "[.cmd][!mayfail]") { /* dacs */
// TODO! this test currently fails with the
// virtual detecto server TEST_CASE("Setting and reading back Jungfrau dacs", "[.cmd][.dacs][.new]") {
// vb_comp, vdd_prot, vin_com, vref_prech, vb_pixbuf, vb_ds, vref_ds, vref_comp
Detector det; Detector det;
CmdProxy proxy(&det); CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash(); auto det_type = det.getDetectorType().squash();
if (det_type == defs::JUNGFRAU) { if (det_type == defs::JUNGFRAU) {
auto pc = det.getPowerChip(); SECTION("vb_comp") { test_dac(defs::VB_COMP, "vb_comp", 1220); }
{ SECTION("vdd_prot") { test_dac(defs::VDD_PROT, "vdd_prot", 3000); }
std::ostringstream oss; SECTION("vin_com") { test_dac(defs::VIN_COM, "vin_com", 1053); }
proxy.Call("powerchip", {"1"}, -1, PUT, oss); SECTION("vref_prech") { test_dac(defs::VREF_PRECH, "vref_prech", 1450); }
REQUIRE(oss.str() == "powerchip 1\n"); SECTION("vb_pixbuf") { test_dac(defs::VB_PIXBUF, "vb_pixbuf", 750); }
} SECTION("vb_ds") { test_dac(defs::VB_DS, "vb_ds", 1000); }
{ SECTION("vref_ds") { test_dac(defs::VREF_DS, "vref_ds", 480); }
std::ostringstream oss; SECTION("vref_comp") { test_dac(defs::VREF_COMP, "vref_comp", 420); }
proxy.Call("powerchip", {"0"}, -1, PUT, oss); // eiger
REQUIRE(oss.str() == "powerchip 0\n"); REQUIRE_THROWS(proxy.Call("vthreshold", {}, -1, GET));
} REQUIRE_THROWS(proxy.Call("vsvp", {}, -1, GET));
{ REQUIRE_THROWS(proxy.Call("vsvn", {}, -1, GET));
std::ostringstream oss; REQUIRE_THROWS(proxy.Call("vtr", {}, -1, GET));
proxy.Call("powerchip", {}, -1, GET, oss); REQUIRE_THROWS(proxy.Call("vrf", {}, -1, GET));
REQUIRE(oss.str() == "powerchip 0\n"); REQUIRE_THROWS(proxy.Call("vrs", {}, -1, GET));
} REQUIRE_THROWS(proxy.Call("vtgstv", {}, -1, GET));
for (int i = 0; i != det.size(); ++i) { REQUIRE_THROWS(proxy.Call("vcmp_ll", {}, -1, GET));
det.setPowerChip(pc[i], {i}); REQUIRE_THROWS(proxy.Call("vcmp_lr", {}, -1, GET));
} REQUIRE_THROWS(proxy.Call("vcal", {}, -1, GET));
} else { REQUIRE_THROWS(proxy.Call("vcmp_rl", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("powerchip", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("vcmp_rr", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("rxb_rb", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("rxb_lb", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcn", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vis", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("iodelay", {}, -1, GET));
// gotthard
// REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcascn_pb", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcascp_pb", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vout_cm", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcasc_out", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vin_cm", {}, -1, GET));
// REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("ib_test_c", {}, -1, GET));
// mythen3
REQUIRE_THROWS(proxy.Call("vpreamp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vshaper", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vshaperneg", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vipre", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("viinsh", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vdcsh", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vth1", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vth2", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vth3", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vpl", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vph", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vtrim", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcassh", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcas", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vicin", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vipre_out", {}, -1, GET));
// gotthard2
REQUIRE_THROWS(proxy.Call("vref_h_adc", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_comp_fe", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_comp_adc", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcom_cds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_rstore", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_opa_1st", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_comp_fe", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcom_adc1", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_l_adc", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_cds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_cs", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_opa_fd", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcom_adc2", {}, -1, GET));
} }
} }
TEST_CASE("nframes", "[.cmd]") { TEST_CASE("nframes", "[.cmd]") {
Detector det; Detector det;
CmdProxy proxy(&det); CmdProxy proxy(&det);
@ -158,78 +236,3 @@ TEST_CASE("resetfpga", "[.cmd]") {
} }
TEST_CASE("Setting and reading back Jungfrau dacs", "[.cmd]") {
// vb_comp, vdd_prot, vin_com, vref_prech, vb_pixbuf, vb_ds, vref_ds, vref_comp
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::JUNGFRAU) {
SECTION("vb_comp") { test_dac(defs::VB_COMP, "vb_comp", 1220); }
SECTION("vdd_prot") { test_dac(defs::VDD_PROT, "vdd_prot", 3000); }
SECTION("vin_com") { test_dac(defs::VIN_COM, "vin_com", 1053); }
SECTION("vref_prech") { test_dac(defs::VREF_PRECH, "vref_prech", 1450); }
SECTION("vb_pixbuf") { test_dac(defs::VB_PIXBUF, "vb_pixbuf", 750); }
SECTION("vb_ds") { test_dac(defs::VB_DS, "vb_ds", 1000); }
SECTION("vref_ds") { test_dac(defs::VREF_DS, "vref_ds", 480); }
SECTION("vref_comp") { test_dac(defs::VREF_COMP, "vref_comp", 420); }
// eiger
REQUIRE_THROWS(proxy.Call("vthreshold", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vsvp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vsvn", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vtr", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vrf", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vrs", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vtgstv", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcmp_ll", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcmp_lr", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcal", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcmp_rl", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcmp_rr", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("rxb_rb", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("rxb_lb", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcn", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vis", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("iodelay", {}, -1, GET));
// gotthard
// REQUIRE_THROWS(proxy.Call("vref_ds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcascn_pb", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcascp_pb", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vout_cm", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcasc_out", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vin_cm", {}, -1, GET));
// REQUIRE_THROWS(proxy.Call("vref_comp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("ib_test_c", {}, -1, GET));
// mythen3
REQUIRE_THROWS(proxy.Call("vpreamp", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vshaper", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vshaperneg", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vipre", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("viinsh", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vdcsh", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vth1", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vth2", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vth3", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vpl", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vph", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vtrim", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcassh", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcas", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vicin", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vipre_out", {}, -1, GET));
// gotthard2
REQUIRE_THROWS(proxy.Call("vref_h_adc", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_comp_fe", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_comp_adc", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcom_cds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_rstore", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_opa_1st", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_comp_fe", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcom_adc1", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_l_adc", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vref_cds", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_cs", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vb_opa_fd", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vcom_adc2", {}, -1, GET));
}
}

View File

@ -15,7 +15,9 @@ using sls::Detector;
using test::GET; using test::GET;
using test::PUT; using test::PUT;
TEST_CASE("Setting and reading back MOENCH dacs", "[.cmd][.dacs]") { /* dacs */
TEST_CASE("Setting and reading back MOENCH dacs", "[.cmd][.dacs][.new]") {
// vbp_colbuf, vipre, vin_cm", vb_sda, vcasc_sfp, vout_cm, vipre_cds, ibias_sfp // vbp_colbuf, vipre, vin_cm", vb_sda, vcasc_sfp, vout_cm, vipre_cds, ibias_sfp
Detector det; Detector det;

View File

@ -15,7 +15,9 @@ using sls::Detector;
using test::GET; using test::GET;
using test::PUT; using test::PUT;
TEST_CASE("Setting and reading back MYTHEN3 dacs", "[.cmd][.dacs]") { /* dacs */
TEST_CASE("Setting and reading back MYTHEN3 dacs", "[.cmd][.dacs][.new]") {
// vcassh, vth2, vshaper, vshaperneg, vipre_out, vth3, vth1, // vcassh, vth2, vshaper, vshaperneg, vipre_out, vth3, vth1,
// vicin, vcas, vpreamp, vpl, vipre, viinsh, vph, vtrim, vdcsh, // vicin, vcas, vpreamp, vpl, vipre, viinsh, vph, vtrim, vdcsh,
@ -87,88 +89,21 @@ TEST_CASE("Setting and reading back MYTHEN3 dacs", "[.cmd][.dacs]") {
} }
} }
TEST_CASE("clkfreq", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::MYTHEN3 || det_type == defs::GOTTHARD2) {
REQUIRE_THROWS(proxy.Call("clkfreq", {"0", "2"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("clkfreq", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("clkfreq", {"7"}, -1, GET));
auto value = det.getClockFrequency(0).squash(-1);
std::ostringstream oss_set, oss_get;
proxy.Call("clkfreq", {"0"}, -1, GET, oss_get);
REQUIRE(oss_get.str() == "clkfreq " + std::to_string(value) + "\n");
} else {
REQUIRE_THROWS(proxy.Call("clkfreq", {"0"}, -1, GET));
}
}
TEST_CASE("clkphase", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::MYTHEN3 || det_type == defs::GOTTHARD2) {
REQUIRE_THROWS(proxy.Call("clkphase", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("clkphase", {"7"}, -1, GET));
REQUIRE_THROWS(proxy.Call("clkphase", {"4"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("clkphase", {"7", "4"}, -1, PUT));
auto previous = det.getClockFrequency(0).squash(-1);
auto previous_string = std::to_string(previous);
std::ostringstream oss_set, oss_get, oss_get2;
proxy.Call("clkfreq", {"0", previous_string}, -1, PUT, oss_set);
REQUIRE(oss_set.str() == "clkfreq" + previous_string + "\n");
proxy.Call("clkfreq", {"0"}, -1, GET, oss_get);
REQUIRE(oss_get.str() == "clkfreq " + previous_string + "\n");
REQUIRE_NOTHROW(proxy.Call("clkphase", {"0", "deg"}, -1, GET));
} else {
REQUIRE_THROWS(proxy.Call("clkphase", {"0"}, -1, GET));
}
}
TEST_CASE("clkdiv", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::MYTHEN3 || det_type == defs::GOTTHARD2) {
REQUIRE_THROWS(proxy.Call("clkdiv", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("clkdiv", {"7"}, -1, GET));
REQUIRE_THROWS(proxy.Call("clkdiv", {"7", "4"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("clkdiv", {"7", "4"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("clkdiv", {"0", "1"}, -1, PUT));
auto previous = det.getClockDivider(0).squash(-1);
auto previous_string = std::to_string(previous);
std::ostringstream oss_set, oss_get;
proxy.Call("clkdiv", {"0", previous_string}, -1, PUT, oss_set);
REQUIRE(oss_set.str() == "clkdiv" + previous_string + "\n");
proxy.Call("clkdiv", {"0"}, -1, GET, oss_get);
REQUIRE(oss_get.str() == "clkdiv " + previous_string + "\n");
} else {
REQUIRE_THROWS(proxy.Call("clkdiv", {"0"}, -1, GET));
}
}
TEST_CASE("maxclkphaseshift", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::MYTHEN3 || det_type == defs::GOTTHARD2) {
REQUIRE_THROWS(proxy.Call("maxclkphaseshift", {"0", "2"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("maxclkphaseshift", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("maxclkphaseshift", {"7"}, -1, GET));
auto value = det.getMaxClockPhaseShift(0).squash(-1);
std::ostringstream oss_set, oss_get;
proxy.Call("maxclkphaseshift", {"0"}, -1, GET, oss_get);
REQUIRE(oss_get.str() ==
"maxclkphaseshift " + std::to_string(value) + "\n");
} else {
REQUIRE_THROWS(proxy.Call("maxclkphaseshift", {"0"}, -1, GET));
}
}
TEST_CASE("counters", "[.cmd]") { TEST_CASE("counters", "[.cmd]") {
Detector det; Detector det;

File diff suppressed because it is too large Load Diff

View File

@ -29,8 +29,8 @@ add_library(slsReceiverShared SHARED
${HEADERS} ${HEADERS}
) )
check_ipo_supported(RESULT result)
if(result) if(SLS_LTO_AVAILABLE)
set_property(TARGET slsReceiverShared PROPERTY INTERPROCEDURAL_OPTIMIZATION True) set_property(TARGET slsReceiverShared PROPERTY INTERPROCEDURAL_OPTIMIZATION True)
endif() endif()

View File

@ -24,19 +24,16 @@ using Interface = sls::ServerInterface;
ClientInterface::~ClientInterface() { ClientInterface::~ClientInterface() {
killTcpThread = true; killTcpThread = true;
// shut down tcp sockets LOG(logINFO) << "Shutting down TCP Socket on port " << portNumber;
if (server.get() != nullptr) { server.shutdown();
LOG(logINFO) << "Shutting down TCP Socket on port " << portNumber; LOG(logDEBUG) << "TCP Socket closed on port " << portNumber;
server->shutDownSocket();
LOG(logDEBUG) << "TCP Socket closed on port " << portNumber;
}
// shut down tcp thread
tcpThread->join(); tcpThread->join();
} }
ClientInterface::ClientInterface(int portNumber) ClientInterface::ClientInterface(int portNumber)
: myDetectorType(GOTTHARD), : myDetectorType(GOTTHARD),
portNumber(portNumber > 0 ? portNumber : DEFAULT_PORTNO + 2) { portNumber(portNumber > 0 ? portNumber : DEFAULT_PORTNO + 2),
server(portNumber) {
functionTable(); functionTable();
// start up tcp thread // start up tcp thread
tcpThread = sls::make_unique<std::thread>(&ClientInterface::startTCPServer, this); tcpThread = sls::make_unique<std::thread>(&ClientInterface::startTCPServer, this);
@ -73,11 +70,11 @@ void ClientInterface::startTCPServer() {
LOG(logINFOBLUE) << "Created [ TCP server Tid: " << syscall(SYS_gettid) << "]"; LOG(logINFOBLUE) << "Created [ TCP server Tid: " << syscall(SYS_gettid) << "]";
LOG(logINFO) << "SLS Receiver starting TCP Server on port " LOG(logINFO) << "SLS Receiver starting TCP Server on port "
<< portNumber << '\n'; << portNumber << '\n';
server = sls::make_unique<sls::ServerSocket>(portNumber); // server = sls::make_unique<sls::ServerSocket>(portNumber);
while (true) { while (!killTcpThread) {
LOG(logDEBUG1) << "Start accept loop"; LOG(logDEBUG1) << "Start accept loop";
try { try {
auto socket = server->accept(); auto socket = server.accept();
try { try {
verifyLock(); verifyLock();
ret = decodeFunction(socket); ret = decodeFunction(socket);
@ -95,10 +92,6 @@ void ClientInterface::startTCPServer() {
} catch (const RuntimeError &e) { } catch (const RuntimeError &e) {
LOG(logERROR) << "Accept failed"; LOG(logERROR) << "Accept failed";
} }
// destructor to kill this thread
if (killTcpThread) {
break;
}
} }
if (receiver) { if (receiver) {
@ -115,10 +108,14 @@ int ClientInterface::functionTable(){
flist[F_GET_LAST_RECEIVER_CLIENT_IP] = &ClientInterface::get_last_client_ip; flist[F_GET_LAST_RECEIVER_CLIENT_IP] = &ClientInterface::get_last_client_ip;
flist[F_SET_RECEIVER_PORT] = &ClientInterface::set_port; flist[F_SET_RECEIVER_PORT] = &ClientInterface::set_port;
flist[F_GET_RECEIVER_VERSION] = &ClientInterface::get_version; flist[F_GET_RECEIVER_VERSION] = &ClientInterface::get_version;
flist[F_GET_RECEIVER_TYPE] = &ClientInterface::set_detector_type; flist[F_SETUP_RECEIVER] = &ClientInterface::setup_receiver;
flist[F_SEND_RECEIVER_DETHOSTNAME] = &ClientInterface::set_detector_hostname;
flist[F_RECEIVER_SET_ROI] = &ClientInterface::set_roi; flist[F_RECEIVER_SET_ROI] = &ClientInterface::set_roi;
flist[F_RECEIVER_SET_NUM_FRAMES] = &ClientInterface::set_num_frames; flist[F_RECEIVER_SET_NUM_FRAMES] = &ClientInterface::set_num_frames;
flist[F_SET_RECEIVER_NUM_TRIGGERS] = &ClientInterface::set_num_triggers;
flist[F_SET_RECEIVER_NUM_BURSTS] = &ClientInterface::set_num_bursts;
flist[F_SET_RECEIVER_NUM_ADD_STORAGE_CELLS] = &ClientInterface::set_num_add_storage_cells;
flist[F_SET_RECEIVER_TIMING_MODE] = &ClientInterface::set_timing_mode;
flist[F_SET_RECEIVER_BURST_MODE] = &ClientInterface::set_burst_mode;
flist[F_RECEIVER_SET_NUM_ANALOG_SAMPLES]= &ClientInterface::set_num_analog_samples; flist[F_RECEIVER_SET_NUM_ANALOG_SAMPLES]= &ClientInterface::set_num_analog_samples;
flist[F_RECEIVER_SET_NUM_DIGITAL_SAMPLES]= &ClientInterface::set_num_digital_samples; flist[F_RECEIVER_SET_NUM_DIGITAL_SAMPLES]= &ClientInterface::set_num_digital_samples;
flist[F_RECEIVER_SET_EXPTIME] = &ClientInterface::set_exptime; flist[F_RECEIVER_SET_EXPTIME] = &ClientInterface::set_exptime;
@ -155,8 +152,6 @@ int ClientInterface::functionTable(){
flist[F_SET_FLIPPED_DATA_RECEIVER] = &ClientInterface::set_flipped_data; flist[F_SET_FLIPPED_DATA_RECEIVER] = &ClientInterface::set_flipped_data;
flist[F_SET_RECEIVER_FILE_FORMAT] = &ClientInterface::set_file_format; flist[F_SET_RECEIVER_FILE_FORMAT] = &ClientInterface::set_file_format;
flist[F_GET_RECEIVER_FILE_FORMAT] = &ClientInterface::get_file_format; flist[F_GET_RECEIVER_FILE_FORMAT] = &ClientInterface::get_file_format;
flist[F_SEND_RECEIVER_DETPOSID] = &ClientInterface::set_detector_posid;
flist[F_SEND_RECEIVER_MULTIDETSIZE] = &ClientInterface::set_multi_detector_size;
flist[F_SET_RECEIVER_STREAMING_PORT] = &ClientInterface::set_streaming_port; flist[F_SET_RECEIVER_STREAMING_PORT] = &ClientInterface::set_streaming_port;
flist[F_GET_RECEIVER_STREAMING_PORT] = &ClientInterface::get_streaming_port; flist[F_GET_RECEIVER_STREAMING_PORT] = &ClientInterface::get_streaming_port;
flist[F_SET_RECEIVER_STREAMING_SRC_IP] = &ClientInterface::set_streaming_source_ip; flist[F_SET_RECEIVER_STREAMING_SRC_IP] = &ClientInterface::set_streaming_source_ip;
@ -195,6 +190,7 @@ int ClientInterface::functionTable(){
flist[F_INCREMENT_FILE_INDEX] = &ClientInterface::increment_file_index; flist[F_INCREMENT_FILE_INDEX] = &ClientInterface::increment_file_index;
flist[F_SET_ADDITIONAL_JSON_PARAMETER] = &ClientInterface::set_additional_json_parameter; flist[F_SET_ADDITIONAL_JSON_PARAMETER] = &ClientInterface::set_additional_json_parameter;
flist[F_GET_ADDITIONAL_JSON_PARAMETER] = &ClientInterface::get_additional_json_parameter; flist[F_GET_ADDITIONAL_JSON_PARAMETER] = &ClientInterface::get_additional_json_parameter;
flist[F_GET_RECEIVER_PROGRESS] = &ClientInterface::get_progress;
for (int i = NUM_DET_FUNCTIONS + 1; i < NUM_REC_FUNCTIONS ; i++) { for (int i = NUM_DET_FUNCTIONS + 1; i < NUM_REC_FUNCTIONS ; i++) {
LOG(logDEBUG1) << "function fnum: " << i << " (" << LOG(logDEBUG1) << "function fnum: " << i << " (" <<
@ -250,7 +246,7 @@ void ClientInterface::validate(T arg, T retval, const std::string& modename,
} }
void ClientInterface::verifyLock() { void ClientInterface::verifyLock() {
if (lockedByClient && server->getThisClient() != server->getLockedBy()) { if (lockedByClient && server.getThisClient() != server.getLockedBy()) {
throw sls::SocketError("Receiver locked\n"); throw sls::SocketError("Receiver locked\n");
} }
} }
@ -296,10 +292,10 @@ int ClientInterface::lock_receiver(Interface &socket) {
auto lock = socket.Receive<int>(); auto lock = socket.Receive<int>();
LOG(logDEBUG1) << "Locking Server to " << lock; LOG(logDEBUG1) << "Locking Server to " << lock;
if (lock >= 0) { if (lock >= 0) {
if (!lockedByClient || (server->getLockedBy() == server->getThisClient())) { if (!lockedByClient || (server.getLockedBy() == server.getThisClient())) {
lockedByClient = lock; lockedByClient = lock;
lock ? server->setLockedBy(server->getThisClient()) lock ? server.setLockedBy(server.getThisClient())
: server->setLockedBy(sls::IpAddr{}); : server.setLockedBy(sls::IpAddr{});
} else { } else {
throw RuntimeError("Receiver locked\n"); throw RuntimeError("Receiver locked\n");
} }
@ -308,7 +304,7 @@ int ClientInterface::lock_receiver(Interface &socket) {
} }
int ClientInterface::get_last_client_ip(Interface &socket) { int ClientInterface::get_last_client_ip(Interface &socket) {
return socket.sendResult(server->getLastClient()); return socket.sendResult(server.getLastClient());
} }
int ClientInterface::set_port(Interface &socket) { int ClientInterface::set_port(Interface &socket) {
@ -318,9 +314,9 @@ int ClientInterface::set_port(Interface &socket) {
" is too low (<1024)"); " is too low (<1024)");
LOG(logINFO) << "TCP port set to " << p_number << std::endl; LOG(logINFO) << "TCP port set to " << p_number << std::endl;
auto new_server = sls::make_unique<sls::ServerSocket>(p_number); sls::ServerSocket new_server(p_number);
new_server->setLockedBy(server->getLockedBy()); new_server.setLockedBy(server.getLockedBy());
new_server->setLastClient(server->getThisClient()); new_server.setLastClient(server.getThisClient());
server = std::move(new_server); server = std::move(new_server);
socket.sendResult(p_number); socket.sendResult(p_number);
return OK; return OK;
@ -330,69 +326,210 @@ int ClientInterface::get_version(Interface &socket) {
return socket.sendResult(getReceiverVersion()); return socket.sendResult(getReceiverVersion());
} }
int ClientInterface::set_detector_type(Interface &socket) { int ClientInterface::setup_receiver(Interface &socket) {
auto arg = socket.Receive<detectorType>(); auto arg = socket.Receive<rxParameters>();
// set LOG(logDEBUG1)
if (arg >= 0) { << "detType:" << arg.detType << std::endl
// if object exists, verify unlocked and idle, else only verify lock << "multiSize.x:" << arg.multiSize.x << std::endl
// (connecting first time) << "multiSize.y:" << arg.multiSize.y << std::endl
if (receiver != nullptr) { << "detId:" << arg.detId << std::endl
verifyIdle(socket); << "hostname:" << arg.hostname << std::endl
} << "udpInterfaces:" << arg.udpInterfaces << std::endl
switch (arg) { << "udp_dstport:" << arg.udp_dstport << std::endl
case GOTTHARD: << "udp_dstip:" << sls::IpAddr(arg.udp_dstip) << std::endl
case EIGER: << "udp_dstmac:" << sls::MacAddr(arg.udp_dstmac) << std::endl
case CHIPTESTBOARD: << "udp_dstport2:" << arg.udp_dstport2 << std::endl
case MOENCH: << "udp_dstip2:" << sls::IpAddr(arg.udp_dstip2) << std::endl
case JUNGFRAU: << "udp_dstmac2:" << sls::MacAddr(arg.udp_dstmac2) << std::endl
case MYTHEN3: << "frames:" << arg.frames << std::endl
case GOTTHARD2: << "triggers:" << arg.triggers << std::endl
break; << "bursts:" << arg.bursts << std::endl
default: << "analogSamples:" << arg.analogSamples << std::endl
throw RuntimeError("Unknown detector type: " + std::to_string(arg)); << "digitalSamples:" << arg.digitalSamples << std::endl
break; << "expTimeNs:" << arg.expTimeNs << std::endl
} << "periodNs:" << arg.periodNs << std::endl
<< "subExpTimeNs:" << arg.subExpTimeNs << std::endl
<< "subDeadTimeNs:" << arg.subDeadTimeNs << std::endl
<< "activate:" << arg.activate << std::endl
<< "quad:" << arg.quad << std::endl
<< "dynamicRange:" << arg.dynamicRange << std::endl
<< "timMode:" << arg.timMode << std::endl
<< "tenGiga:" << arg.tenGiga << std::endl
<< "roMode:" << arg.roMode << std::endl
<< "adcMask:" << arg.adcMask << std::endl
<< "adc10gMask:" << arg.adc10gMask << std::endl
<< "roi.xmin:" << arg.roi.xmin << std::endl
<< "roi.xmax:" << arg.roi.xmax << std::endl
<< "countermask:" << arg.countermask << std::endl
<< "burstType:" << arg.burstType << std::endl;
try {
myDetectorType = GENERIC;
receiver = sls::make_unique<Implementation>(arg);
myDetectorType = arg;
} catch (...) {
throw RuntimeError("Could not set detector type");
}
// callbacks after (in setdetectortype, the object is reinitialized) // if object exists, verify unlocked and idle, else only verify lock
if (startAcquisitionCallBack != nullptr) // (connecting first time)
impl()->registerCallBackStartAcquisition(startAcquisitionCallBack, if (receiver != nullptr) {
pStartAcquisition); verifyIdle(socket);
if (acquisitionFinishedCallBack != nullptr)
impl()->registerCallBackAcquisitionFinished(
acquisitionFinishedCallBack, pAcquisitionFinished);
if (rawDataReadyCallBack != nullptr)
impl()->registerCallBackRawDataReady(rawDataReadyCallBack,
pRawDataReady);
if (rawDataModifyReadyCallBack != nullptr)
impl()->registerCallBackRawDataModifyReady(
rawDataModifyReadyCallBack, pRawDataReady);
} }
return socket.sendResult(myDetectorType);
// basic setup
setDetectorType(arg.detType);
{
int msize[2] = {arg.multiSize.x, arg.multiSize.y};
impl()->setMultiDetectorSize(msize);
}
impl()->setDetectorPositionId(arg.detId);
impl()->setDetectorHostname(arg.hostname);
// udp setup
sls::MacAddr retvals[2];
if (arg.udp_dstmac == 0 && arg.udp_dstip != 0) {
retvals[0] = setUdpIp(sls::IpAddr(arg.udp_dstip));
}
if (arg.udp_dstmac2 == 0 && arg.udp_dstip2 != 0) {
retvals[1] = setUdpIp2(sls::IpAddr(arg.udp_dstip2));
}
impl()->setUDPPortNumber(arg.udp_dstport);
impl()->setUDPPortNumber2(arg.udp_dstport2);
if (myDetectorType == JUNGFRAU) {
try {
impl()->setNumberofUDPInterfaces(arg.udpInterfaces);
} catch(const RuntimeError &e) {
throw RuntimeError("Failed to set number of interfaces to " +
std::to_string(arg.udpInterfaces));
}
}
impl()->setUDPSocketBufferSize(0);
// acquisition parameters
impl()->setNumberOfFrames(arg.frames);
impl()->setNumberOfTriggers(arg.triggers);
if (myDetectorType == GOTTHARD) {
impl()->setNumberOfBursts(arg.bursts);
}
if (myDetectorType == MOENCH || myDetectorType == CHIPTESTBOARD) {
try {
impl()->setNumberofAnalogSamples(arg.analogSamples);
} catch(const RuntimeError &e) {
throw RuntimeError("Could not set num analog samples to " +
std::to_string(arg.analogSamples) +
" due to fifo structure memory allocation.");
}
}
if (myDetectorType == CHIPTESTBOARD) {
try {
impl()->setNumberofDigitalSamples(arg.digitalSamples);
} catch(const RuntimeError &e) {
throw RuntimeError("Could not set num digital samples to "
+ std::to_string(arg.analogSamples) +
" due to fifo structure memory allocation.");
}
}
impl()->setAcquisitionTime(arg.expTimeNs);
impl()->setAcquisitionPeriod(arg.periodNs);
if (myDetectorType == EIGER) {
impl()->setSubExpTime(arg.subExpTimeNs);
impl()->setSubPeriod(arg.subExpTimeNs + arg.subDeadTimeNs);
impl()->setActivate(static_cast<bool>(arg.activate));
try {
impl()->setQuad(arg.quad == 0 ? false : true);
} catch(const RuntimeError &e) {
throw RuntimeError("Could not set quad to " +
std::to_string(arg.quad) +
" due to fifo strucutre memory allocation");
}
}
if (myDetectorType == EIGER || myDetectorType == MYTHEN3) {
try {
impl()->setDynamicRange(arg.dynamicRange);
} catch(const RuntimeError &e) {
throw RuntimeError("Could not set dynamic range. Could not allocate "
"memory for fifo or could not start listening/writing threads");
}
}
impl()->setTimingMode(arg.timMode);
if (myDetectorType == EIGER || myDetectorType == MOENCH ||
myDetectorType == CHIPTESTBOARD) {
try {
impl()->setTenGigaEnable(arg.tenGiga);
} catch(const RuntimeError &e) {
throw RuntimeError("Could not set 10GbE.");
}
}
if (myDetectorType == CHIPTESTBOARD) {
try {
impl()->setReadoutMode(arg.roMode);
} catch(const RuntimeError &e) {
throw RuntimeError("Could not set read out mode "
"due to fifo memory allocation.");
}
}
if (myDetectorType == CHIPTESTBOARD || myDetectorType == MOENCH) {
try {
impl()->setADCEnableMask(arg.adcMask);
} catch(const RuntimeError &e) {
throw RuntimeError("Could not set adc enable mask "
"due to fifo memory allcoation");
}
try {
impl()->setTenGigaADCEnableMask(arg.adc10gMask);
} catch(const RuntimeError &e) {
throw RuntimeError("Could not set 10Gb adc enable mask "
"due to fifo memory allcoation");
}
}
if (myDetectorType == GOTTHARD) {
try {
impl()->setROI(arg.roi);
} catch(const RuntimeError &e) {
throw RuntimeError("Could not set ROI");
}
}
if (myDetectorType == MYTHEN3) {
int ncounters = __builtin_popcount(arg.countermask);
impl()->setNumberofCounters(ncounters);
}
if (myDetectorType == GOTTHARD) {
impl()->setBurstMode(arg.burstType);
}
return socket.sendResult(retvals);
} }
int ClientInterface::set_detector_hostname(Interface &socket) { void ClientInterface::setDetectorType(detectorType arg) {
char hostname[MAX_STR_LENGTH]{}; switch (arg) {
char retval[MAX_STR_LENGTH]{}; case GOTTHARD:
socket.Receive(hostname); case EIGER:
case CHIPTESTBOARD:
case MOENCH:
case JUNGFRAU:
case MYTHEN3:
case GOTTHARD2:
break;
default:
throw RuntimeError("Unknown detector type: " + std::to_string(arg));
break;
}
if (strlen(hostname) != 0) { try {
verifyIdle(socket); myDetectorType = GENERIC;
impl()->setDetectorHostname(hostname); receiver = sls::make_unique<Implementation>(arg);
myDetectorType = arg;
} catch (...) {
throw RuntimeError("Could not set detector type");
} }
auto s = impl()->getDetectorHostname();
sls::strcpy_safe(retval, s.c_str()); // callbacks after (in setdetectortype, the object is reinitialized)
if (s.empty()) { if (startAcquisitionCallBack != nullptr)
throw RuntimeError("Hostname not set"); impl()->registerCallBackStartAcquisition(startAcquisitionCallBack,
} pStartAcquisition);
return socket.sendResult(retval); if (acquisitionFinishedCallBack != nullptr)
impl()->registerCallBackAcquisitionFinished(
acquisitionFinishedCallBack, pAcquisitionFinished);
if (rawDataReadyCallBack != nullptr)
impl()->registerCallBackRawDataReady(rawDataReadyCallBack,
pRawDataReady);
if (rawDataModifyReadyCallBack != nullptr)
impl()->registerCallBackRawDataModifyReady(
rawDataModifyReadyCallBack, pRawDataReady);
} }
int ClientInterface::set_roi(Interface &socket) { int ClientInterface::set_roi(Interface &socket) {
@ -415,8 +552,85 @@ int ClientInterface::set_roi(Interface &socket) {
int ClientInterface::set_num_frames(Interface &socket) { int ClientInterface::set_num_frames(Interface &socket) {
auto value = socket.Receive<int64_t>(); auto value = socket.Receive<int64_t>();
if (value <= 0) {
throw RuntimeError("Invalid number of frames " +
std::to_string(value));
}
verifyIdle(socket);
LOG(logDEBUG1) << "Setting num frames to " << value; LOG(logDEBUG1) << "Setting num frames to " << value;
impl()->setNumberOfFrames(value); impl()->setNumberOfFrames(value);
int64_t retval = impl()->getNumberOfFrames();
validate(value, retval, "set number of frames", DEC);
return socket.Send(OK);
}
int ClientInterface::set_num_triggers(Interface &socket) {
auto value = socket.Receive<int64_t>();
if (value <= 0) {
throw RuntimeError("Invalid number of triggers " +
std::to_string(value));
}
verifyIdle(socket);
LOG(logDEBUG1) << "Setting num triggers to " << value;
impl()->setNumberOfTriggers(value);
int64_t retval = impl()->getNumberOfTriggers();
validate(value, retval, "set number of triggers", DEC);
return socket.Send(OK);
}
int ClientInterface::set_num_bursts(Interface &socket) {
auto value = socket.Receive<int64_t>();
if (value <= 0) {
throw RuntimeError("Invalid number of bursts " +
std::to_string(value));
}
verifyIdle(socket);
LOG(logDEBUG1) << "Setting num bursts to " << value;
impl()->setNumberOfBursts(value);
int64_t retval = impl()->getNumberOfBursts();
validate(value, retval, "set number of bursts", DEC);
return socket.Send(OK);
}
int ClientInterface::set_num_add_storage_cells(Interface &socket) {
auto value = socket.Receive<int>();
if (value < 0) {
throw RuntimeError("Invalid number of additional storage cells " +
std::to_string(value));
}
verifyIdle(socket);
LOG(logDEBUG1) << "Setting num additional storage cells to " << value;
impl()->setNumberOfAdditionalStorageCells(value);
int retval = impl()->getNumberOfAdditionalStorageCells();
validate(value, retval, "set number of additional storage cells", DEC);
return socket.Send(OK);
}
int ClientInterface::set_timing_mode(Interface &socket) {
auto value = socket.Receive<int>();
if (value < 0 || value >= NUM_TIMING_MODES) {
throw RuntimeError("Invalid timing mode " +
std::to_string(value));
}
verifyIdle(socket);
LOG(logDEBUG1) << "Setting timing mode to " << value;
impl()->setTimingMode(static_cast<timingMode>(value));
int retval = impl()->getTimingMode();
validate(value, retval, "set timing mode", DEC);
return socket.Send(OK);
}
int ClientInterface::set_burst_mode(Interface &socket) {
auto value = socket.Receive<int>();
if (value < 0 || value >= NUM_BURST_MODES) {
throw RuntimeError("Invalid burst mode " +
std::to_string(value));
}
verifyIdle(socket);
LOG(logDEBUG1) << "Setting burst mode to " << value;
impl()->setBurstMode(static_cast<burstMode>(value));
int retval = impl()->getBurstMode();
validate(value, retval, "set burst mode", DEC);
return socket.Send(OK); return socket.Send(OK);
} }
@ -431,7 +645,6 @@ int ClientInterface::set_num_analog_samples(Interface &socket) {
} catch(const RuntimeError &e) { } catch(const RuntimeError &e) {
throw RuntimeError("Could not set num analog samples to " + std::to_string(value) + " due to fifo structure memory allocation."); throw RuntimeError("Could not set num analog samples to " + std::to_string(value) + " due to fifo structure memory allocation.");
} }
return socket.Send(OK); return socket.Send(OK);
} }
@ -748,7 +961,7 @@ int ClientInterface::enable_tengiga(Interface &socket) {
try { try {
impl()->setTenGigaEnable(val); impl()->setTenGigaEnable(val);
} catch(const RuntimeError &e) { } catch(const RuntimeError &e) {
throw RuntimeError("Could not set 10GbE."); throw RuntimeError("Could not set 10GbE." );
} }
} }
int retval = impl()->getTenGigaEnable(); int retval = impl()->getTenGigaEnable();
@ -869,34 +1082,6 @@ int ClientInterface::get_file_format(Interface &socket) {
return socket.sendResult(retval); return socket.sendResult(retval);
} }
int ClientInterface::set_detector_posid(Interface &socket) {
auto arg = socket.Receive<int>();
if (arg >= 0) {
verifyIdle(socket);
LOG(logDEBUG1) << "Setting detector position id:" << arg;
impl()->setDetectorPositionId(arg);
}
auto retval = impl()->getDetectorPositionId();
validate(arg, retval, "set detector position id", DEC);
LOG(logDEBUG1) << "Position Id:" << retval;
return socket.sendResult(retval);
}
int ClientInterface::set_multi_detector_size(Interface &socket) {
int arg[]{-1, -1};
socket.Receive(arg);
if ((arg[0] > 0) && (arg[1] > 0)) {
verifyIdle(socket);
LOG(logDEBUG1)
<< "Setting multi detector size:" << arg[0] << "," << arg[1];
impl()->setMultiDetectorSize(arg);
}
int *temp = impl()->getMultiDetectorSize(); // TODO! return by value!
int retval = temp[0] * temp[1];
LOG(logDEBUG1) << "Multi Detector Size:" << retval;
return socket.sendResult(retval);
}
int ClientInterface::set_streaming_port(Interface &socket) { int ClientInterface::set_streaming_port(Interface &socket) {
auto port = socket.Receive<int>(); auto port = socket.Receive<int>();
if (port < 0) { if (port < 0) {
@ -1280,11 +1465,7 @@ int ClientInterface::set_read_n_lines(Interface &socket) {
return socket.Send(OK); return socket.Send(OK);
} }
sls::MacAddr ClientInterface::setUdpIp(sls::IpAddr arg) {
int ClientInterface::set_udp_ip(Interface &socket) {
auto arg = socket.Receive<sls::IpAddr>();
verifyIdle(socket);
LOG(logINFO) << "Received UDP IP: " << arg;
// getting eth // getting eth
std::string eth = sls::IpToInterfaceName(arg.str()); std::string eth = sls::IpToInterfaceName(arg.str());
if (eth == "none") { if (eth == "none") {
@ -1303,18 +1484,19 @@ int ClientInterface::set_udp_ip(Interface &socket) {
if (retval == 0) { if (retval == 0) {
throw RuntimeError("Failed to get udp mac adddress to listen to (eth:" + eth + ", ip:" + arg.str() + ")\n"); throw RuntimeError("Failed to get udp mac adddress to listen to (eth:" + eth + ", ip:" + arg.str() + ")\n");
} }
return retval;
}
int ClientInterface::set_udp_ip(Interface &socket) {
auto arg = socket.Receive<sls::IpAddr>();
verifyIdle(socket);
LOG(logINFO) << "Received UDP IP: " << arg;
auto retval = setUdpIp(arg);
LOG(logINFO) << "Receiver MAC Address: " << retval; LOG(logINFO) << "Receiver MAC Address: " << retval;
return socket.sendResult(retval); return socket.sendResult(retval);
} }
sls::MacAddr ClientInterface::setUdpIp2(sls::IpAddr arg) {
int ClientInterface::set_udp_ip2(Interface &socket) {
auto arg = socket.Receive<sls::IpAddr>();
verifyIdle(socket);
if (myDetectorType != JUNGFRAU) {
throw RuntimeError("UDP Destination IP2 not implemented for this detector");
}
LOG(logINFO) << "Received UDP IP2: " << arg;
// getting eth // getting eth
std::string eth = sls::IpToInterfaceName(arg.str()); std::string eth = sls::IpToInterfaceName(arg.str());
if (eth == "none") { if (eth == "none") {
@ -1331,6 +1513,17 @@ int ClientInterface::set_udp_ip2(Interface &socket) {
if (retval == 0) { if (retval == 0) {
throw RuntimeError("Failed to get udp mac adddress2 to listen to (eth:" + eth + ", ip:" + arg.str() + ")\n"); throw RuntimeError("Failed to get udp mac adddress2 to listen to (eth:" + eth + ", ip:" + arg.str() + ")\n");
} }
return retval;
}
int ClientInterface::set_udp_ip2(Interface &socket) {
auto arg = socket.Receive<sls::IpAddr>();
verifyIdle(socket);
if (myDetectorType != JUNGFRAU) {
throw RuntimeError("UDP Destination IP2 not implemented for this detector");
}
LOG(logINFO) << "Received UDP IP2: " << arg;
auto retval = setUdpIp2(arg);
LOG(logINFO) << "Receiver MAC Address2: " << retval; LOG(logINFO) << "Receiver MAC Address2: " << retval;
return socket.sendResult(retval); return socket.sendResult(retval);
} }
@ -1425,3 +1618,9 @@ int ClientInterface::get_additional_json_parameter(Interface &socket) {
LOG(logDEBUG1) << "additional json parameter (" << arg << "):" << retval; LOG(logDEBUG1) << "additional json parameter (" << arg << "):" << retval;
return socket.sendResult(retval); return socket.sendResult(retval);
} }
int ClientInterface::get_progress(Interface &socket) {
int retval = impl()->getProgress();
LOG(logDEBUG1) << "progress retval: " << retval;
return socket.sendResult(retval);
}

View File

@ -10,8 +10,18 @@ class ServerInterface;
#include <future> #include <future>
class ClientInterface : private virtual slsDetectorDefs { class ClientInterface : private virtual slsDetectorDefs {
private:
enum numberMode { DEC, HEX }; enum numberMode { DEC, HEX };
detectorType myDetectorType;
int portNumber{0};
sls::ServerSocket server;
std::unique_ptr<Implementation> receiver;
std::unique_ptr<std::thread> tcpThread;
int ret{OK};
int fnum{-1};
int lockedByClient{0};
std::atomic<bool> killTcpThread{false};
public: public:
virtual ~ClientInterface(); virtual ~ClientInterface();
@ -49,17 +59,21 @@ class ClientInterface : private virtual slsDetectorDefs {
void verifyLock(); void verifyLock();
void verifyIdle(sls::ServerInterface &socket); void verifyIdle(sls::ServerInterface &socket);
int exec_command(sls::ServerInterface &socket); int exec_command(sls::ServerInterface &socket);
int exit_server(sls::ServerInterface &socket); int exit_server(sls::ServerInterface &socket);
int lock_receiver(sls::ServerInterface &socket); int lock_receiver(sls::ServerInterface &socket);
int get_last_client_ip(sls::ServerInterface &socket); int get_last_client_ip(sls::ServerInterface &socket);
int set_port(sls::ServerInterface &socket); int set_port(sls::ServerInterface &socket);
int get_version(sls::ServerInterface &socket); int get_version(sls::ServerInterface &socket);
int set_detector_type(sls::ServerInterface &socket); int setup_receiver(sls::ServerInterface &socket);
int set_detector_hostname(sls::ServerInterface &socket); void setDetectorType(detectorType arg);
int set_roi(sls::ServerInterface &socket); int set_roi(sls::ServerInterface &socket);
int set_num_frames(sls::ServerInterface &socket); int set_num_frames(sls::ServerInterface &socket);
int set_num_triggers(sls::ServerInterface &socket);
int set_num_bursts(sls::ServerInterface &socket);
int set_num_add_storage_cells(sls::ServerInterface &socket);
int set_timing_mode(sls::ServerInterface &socket);
int set_burst_mode(sls::ServerInterface &socket);
int set_num_analog_samples(sls::ServerInterface &socket); int set_num_analog_samples(sls::ServerInterface &socket);
int set_num_digital_samples(sls::ServerInterface &socket); int set_num_digital_samples(sls::ServerInterface &socket);
int set_exptime(sls::ServerInterface &socket); int set_exptime(sls::ServerInterface &socket);
@ -97,8 +111,6 @@ class ClientInterface : private virtual slsDetectorDefs {
int set_flipped_data(sls::ServerInterface &socket); int set_flipped_data(sls::ServerInterface &socket);
int set_file_format(sls::ServerInterface &socket); int set_file_format(sls::ServerInterface &socket);
int get_file_format(sls::ServerInterface &socket); int get_file_format(sls::ServerInterface &socket);
int set_detector_posid(sls::ServerInterface &socket);
int set_multi_detector_size(sls::ServerInterface &socket);
int set_streaming_port(sls::ServerInterface &socket); int set_streaming_port(sls::ServerInterface &socket);
int get_streaming_port(sls::ServerInterface &socket); int get_streaming_port(sls::ServerInterface &socket);
int set_streaming_source_ip(sls::ServerInterface &socket); int set_streaming_source_ip(sls::ServerInterface &socket);
@ -127,7 +139,9 @@ class ClientInterface : private virtual slsDetectorDefs {
int get_dbit_offset(sls::ServerInterface &socket); int get_dbit_offset(sls::ServerInterface &socket);
int set_quad_type(sls::ServerInterface &socket); int set_quad_type(sls::ServerInterface &socket);
int set_read_n_lines(sls::ServerInterface &socket); int set_read_n_lines(sls::ServerInterface &socket);
sls::MacAddr setUdpIp(sls::IpAddr arg);
int set_udp_ip(sls::ServerInterface &socket); int set_udp_ip(sls::ServerInterface &socket);
sls::MacAddr setUdpIp2(sls::IpAddr arg);
int set_udp_ip2(sls::ServerInterface &socket); int set_udp_ip2(sls::ServerInterface &socket);
int set_udp_port(sls::ServerInterface &socket); int set_udp_port(sls::ServerInterface &socket);
int set_udp_port2(sls::ServerInterface &socket); int set_udp_port2(sls::ServerInterface &socket);
@ -137,6 +151,7 @@ class ClientInterface : private virtual slsDetectorDefs {
int increment_file_index(sls::ServerInterface &socket); int increment_file_index(sls::ServerInterface &socket);
int set_additional_json_parameter(sls::ServerInterface &socket); int set_additional_json_parameter(sls::ServerInterface &socket);
int get_additional_json_parameter(sls::ServerInterface &socket); int get_additional_json_parameter(sls::ServerInterface &socket);
int get_progress(sls::ServerInterface &socket);
Implementation *impl() { Implementation *impl() {
if (receiver != nullptr) { if (receiver != nullptr) {
@ -147,18 +162,8 @@ class ClientInterface : private virtual slsDetectorDefs {
} }
} }
detectorType myDetectorType;
std::unique_ptr<Implementation> receiver{nullptr};
int (ClientInterface::*flist[NUM_REC_FUNCTIONS])( int (ClientInterface::*flist[NUM_REC_FUNCTIONS])(
sls::ServerInterface &socket); sls::ServerInterface &socket);
int ret{OK};
int fnum{-1};
int lockedByClient{0};
int portNumber{0};
std::atomic<bool> killTcpThread{false};
std::unique_ptr<std::thread> tcpThread;
//***callback parameters*** //***callback parameters***
@ -172,6 +177,6 @@ class ClientInterface : private virtual slsDetectorDefs {
void *) = nullptr; void *) = nullptr;
void *pRawDataReady{nullptr}; void *pRawDataReady{nullptr};
protected:
std::unique_ptr<sls::ServerSocket> server{nullptr};
}; };

View File

@ -29,13 +29,9 @@ DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo* f,
uint32_t* freq, uint32_t* timer, uint32_t* freq, uint32_t* timer,
bool* fp, bool* act, bool* depaden, bool* sm, bool* qe, bool* fp, bool* act, bool* depaden, bool* sm, bool* qe,
std::vector <int> * cdl, int* cdo, int* cad) : std::vector <int> * cdl, int* cdo, int* cad) :
ThreadObject(ind, TypeName), ThreadObject(ind, TypeName),
runningFlag(false),
generalData(nullptr),
fifo(f), fifo(f),
myDetectorType(dtype), myDetectorType(dtype),
file(nullptr),
dataStreamEnable(dsEnable), dataStreamEnable(dsEnable),
fileFormatType(ftype), fileFormatType(ftype),
fileWriteEnable(fwenable), fileWriteEnable(fwenable),
@ -43,7 +39,6 @@ DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo* f,
dynamicRange(dr), dynamicRange(dr),
streamingFrequency(freq), streamingFrequency(freq),
streamingTimerInMs(timer), streamingTimerInMs(timer),
currentFreqCount(0),
activated(act), activated(act),
deactivatedPaddingEnable(depaden), deactivatedPaddingEnable(depaden),
silentMode(sm), silentMode(sm),
@ -51,14 +46,7 @@ DataProcessor::DataProcessor(int ind, detectorType dtype, Fifo* f,
framePadding(fp), framePadding(fp),
ctbDbitList(cdl), ctbDbitList(cdl),
ctbDbitOffset(cdo), ctbDbitOffset(cdo),
ctbAnalogDataBytes(cad), ctbAnalogDataBytes(cad)
startedFlag(false),
firstIndex(0),
numFramesCaught(0),
currentFrameIndex(0),
rawDataReadyCallBack(nullptr),
rawDataModifyReadyCallBack(nullptr),
pRawDataReady(nullptr)
{ {
LOG(logDEBUG) << "DataProcessor " << ind << " created"; LOG(logDEBUG) << "DataProcessor " << ind << " created";
memset((void*)&timerBegin, 0, sizeof(timespec)); memset((void*)&timerBegin, 0, sizeof(timespec));
@ -71,10 +59,6 @@ DataProcessor::~DataProcessor() {
/** getters */ /** getters */
bool DataProcessor::IsRunning() {
return runningFlag;
}
bool DataProcessor::GetStartedFlag(){ bool DataProcessor::GetStartedFlag(){
return startedFlag; return startedFlag;
} }
@ -91,24 +75,12 @@ uint64_t DataProcessor::GetProcessedIndex() {
return currentFrameIndex - firstIndex; return currentFrameIndex - firstIndex;
} }
/** setters */
void DataProcessor::StartRunning() {
runningFlag = true;
}
void DataProcessor::StopRunning() {
runningFlag = false;
}
void DataProcessor::SetFifo(Fifo* f) { void DataProcessor::SetFifo(Fifo* f) {
fifo = f; fifo = f;
} }
void DataProcessor::ResetParametersforNewAcquisition(){ void DataProcessor::ResetParametersforNewAcquisition(){
runningFlag = false; StopRunning();
startedFlag = false; startedFlag = false;
numFramesCaught = 0; numFramesCaught = 0;
firstIndex = 0; firstIndex = 0;

View File

@ -59,11 +59,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
//*** getters *** //*** getters ***
/**
* Returns if the thread is currently running
* @returns true if thread is running, else false
*/
bool IsRunning() override;
/** /**
* Get acquisition started flag * Get acquisition started flag
@ -89,17 +84,6 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
*/ */
uint64_t GetProcessedIndex(); uint64_t GetProcessedIndex();
//*** setters ***
/**
* Set bit in RunningMask to allow thread to run
*/
void StartRunning();
/**
* Reset bit in RunningMask to prevent thread from running
*/
void StopRunning();
/** /**
* Set Fifo pointer to the one given * Set Fifo pointer to the one given
* @param f address of Fifo pointer * @param f address of Fifo pointer
@ -254,11 +238,8 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
/** type of thread */ /** type of thread */
static const std::string TypeName; static const std::string TypeName;
/** Object running status */
std::atomic<bool> runningFlag;
/** GeneralData (Detector Data) object */ /** GeneralData (Detector Data) object */
const GeneralData* generalData; const GeneralData* generalData{nullptr};
/** Fifo structure */ /** Fifo structure */
Fifo* fifo; Fifo* fifo;
@ -269,7 +250,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
detectorType myDetectorType; detectorType myDetectorType;
/** File writer implemented as binary or hdf5 File */ /** File writer implemented as binary or hdf5 File */
File* file; File* file{nullptr};
/** Data Stream Enable */ /** Data Stream Enable */
bool* dataStreamEnable; bool* dataStreamEnable;
@ -293,7 +274,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
uint32_t* streamingTimerInMs; uint32_t* streamingTimerInMs;
/** Current frequency count */ /** Current frequency count */
uint32_t currentFreqCount; uint32_t currentFreqCount{0};
/** timer beginning stamp for random streaming */ /** timer beginning stamp for random streaming */
struct timespec timerBegin; struct timespec timerBegin;
@ -324,21 +305,18 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
//acquisition start //acquisition start
/** Aquisition Started flag */ /** Aquisition Started flag */
bool startedFlag; std::atomic<bool> startedFlag{false};
/** Frame Number of First Frame */ /** Frame Number of First Frame */
uint64_t firstIndex; std::atomic<uint64_t> firstIndex{0};
//for statistics //for statistics
/** Number of complete frames caught */ /** Number of complete frames caught */
uint64_t numFramesCaught; uint64_t numFramesCaught{0};
/** Frame Number of latest processed frame number */ /** Frame Number of latest processed frame number */
uint64_t currentFrameIndex; std::atomic<uint64_t> currentFrameIndex{0};
//call back //call back
/** /**
@ -349,7 +327,7 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
* dataSize in bytes is the size of the data in bytes. * dataSize in bytes is the size of the data in bytes.
*/ */
void (*rawDataReadyCallBack)(char*, void (*rawDataReadyCallBack)(char*,
char*, uint32_t, void*); char*, uint32_t, void*) = nullptr;
/** /**
* Call back for raw data (modified) * Call back for raw data (modified)
@ -359,9 +337,9 @@ class DataProcessor : private virtual slsDetectorDefs, public ThreadObject {
* revDatasize is the reference of data size in bytes. Can be modified to the new size to be written/streamed. (only smaller value). * revDatasize is the reference of data size in bytes. Can be modified to the new size to be written/streamed. (only smaller value).
*/ */
void (*rawDataModifyReadyCallBack)(char*, void (*rawDataModifyReadyCallBack)(char*,
char*, uint32_t &, void*); char*, uint32_t &, void*) = nullptr;
void *pRawDataReady; void *pRawDataReady{nullptr};

View File

@ -17,21 +17,15 @@ const std::string DataStreamer::TypeName = "DataStreamer";
DataStreamer::DataStreamer(int ind, Fifo* f, uint32_t* dr, ROI* r, DataStreamer::DataStreamer(int ind, Fifo* f, uint32_t* dr, ROI* r,
uint64_t* fi, int fd, int* nd, bool* qe) : uint64_t* fi, int fd, int* nd, bool* qe, uint64_t* tot) :
ThreadObject(ind, TypeName), ThreadObject(ind, TypeName),
runningFlag(0),
generalData(nullptr),
fifo(f), fifo(f),
zmqSocket(nullptr),
dynamicRange(dr), dynamicRange(dr),
roi(r), roi(r),
adcConfigured(-1),
fileIndex(fi), fileIndex(fi),
flippedDataX(fd), flippedDataX(fd),
startedFlag(false), quadEnable(qe),
firstIndex(0), totalNumFrames(tot)
completeBuffer(nullptr),
quadEnable(qe)
{ {
numDet[0] = nd[0]; numDet[0] = nd[0];
numDet[1] = nd[1]; numDet[1] = nd[1];
@ -45,29 +39,12 @@ DataStreamer::~DataStreamer() {
delete [] completeBuffer; delete [] completeBuffer;
} }
/** getters */
bool DataStreamer::IsRunning() {
return runningFlag;
}
/** setters */
void DataStreamer::StartRunning() {
runningFlag = true;
}
void DataStreamer::StopRunning() {
runningFlag = false;
}
void DataStreamer::SetFifo(Fifo* f) { void DataStreamer::SetFifo(Fifo* f) {
fifo = f; fifo = f;
} }
void DataStreamer::ResetParametersforNewAcquisition(const std::string& fname){ void DataStreamer::ResetParametersforNewAcquisition(const std::string& fname){
runningFlag = false; StopRunning();
startedFlag = false; startedFlag = false;
firstIndex = 0; firstIndex = 0;
@ -241,6 +218,7 @@ int DataStreamer::SendHeader(sls_receiver_header* rheader, uint32_t size, uint32
zHeader.imageSize = size; zHeader.imageSize = size;
zHeader.acqIndex = acquisitionIndex; zHeader.acqIndex = acquisitionIndex;
zHeader.frameIndex = frameIndex; zHeader.frameIndex = frameIndex;
zHeader.progress = 100 * ((double)(frameIndex + 1) / (double)(*totalNumFrames));
zHeader.fname = fileNametoStream; zHeader.fname = fileNametoStream;
zHeader.frameNumber = header.frameNumber; zHeader.frameNumber = header.frameNumber;
zHeader.expLength = header.expLength; zHeader.expLength = header.expLength;

View File

@ -31,9 +31,10 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
* @param fd flipped data enable for x dimension * @param fd flipped data enable for x dimension
* @param nd pointer to number of detectors in each dimension * @param nd pointer to number of detectors in each dimension
* @param qe pointer to quad Enable * @param qe pointer to quad Enable
* @param tot pointer to total number of frames
*/ */
DataStreamer(int ind, Fifo* f, uint32_t* dr, ROI* r, DataStreamer(int ind, Fifo* f, uint32_t* dr, ROI* r,
uint64_t* fi, int fd, int* nd, bool* qe); uint64_t* fi, int fd, int* nd, bool* qe, uint64_t* tot);
/** /**
* Destructor * Destructor
@ -41,25 +42,6 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
*/ */
~DataStreamer(); ~DataStreamer();
//*** getters ***
/**
* Returns if the thread is currently running
* @returns true if thread is running, else false
*/
bool IsRunning();
//*** setters ***
/**
* Set bit in RunningMask to allow thread to run
*/
void StartRunning();
/**
* Reset bit in RunningMask to prevent thread from running
*/
void StopRunning();
/** /**
* Set Fifo pointer to the one given * Set Fifo pointer to the one given
* @param f address of Fifo pointer * @param f address of Fifo pointer
@ -157,19 +139,14 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
/** type of thread */ /** type of thread */
static const std::string TypeName; static const std::string TypeName;
/** Object running status */
bool runningFlag;
/** GeneralData (Detector Data) object */ /** GeneralData (Detector Data) object */
const GeneralData* generalData; const GeneralData* generalData{nullptr};
/** Fifo structure */ /** Fifo structure */
Fifo* fifo; Fifo* fifo;
/** ZMQ Socket - Receiver to Client */ /** ZMQ Socket - Receiver to Client */
ZmqSocket* zmqSocket; ZmqSocket* zmqSocket{nullptr};
/** Pointer to dynamic range */ /** Pointer to dynamic range */
uint32_t* dynamicRange; uint32_t* dynamicRange;
@ -178,7 +155,7 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
ROI* roi; ROI* roi;
/** adc Configured */ /** adc Configured */
int adcConfigured; int adcConfigured{-1};
/** Pointer to file index */ /** Pointer to file index */
uint64_t* fileIndex; uint64_t* fileIndex;
@ -190,16 +167,16 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
std::map<std::string, std::string> additionJsonHeader; std::map<std::string, std::string> additionJsonHeader;
/** Aquisition Started flag */ /** Aquisition Started flag */
bool startedFlag; bool startedFlag{nullptr};
/** Frame Number of First Frame */ /** Frame Number of First Frame */
uint64_t firstIndex; uint64_t firstIndex{0};
/* File name to stream */ /* File name to stream */
std::string fileNametoStream; std::string fileNametoStream;
/** Complete buffer used for roi, eg. shortGotthard */ /** Complete buffer used for roi, eg. shortGotthard */
char* completeBuffer; char* completeBuffer{nullptr};
/** Number of Detectors in X and Y dimension */ /** Number of Detectors in X and Y dimension */
int numDet[2]; int numDet[2];
@ -207,5 +184,8 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
/** Quad Enable */ /** Quad Enable */
bool* quadEnable; bool* quadEnable;
/** Total number of frames */
uint64_t* totalNumFrames;
}; };

View File

@ -414,7 +414,7 @@ class EigerData : public GeneralData {
imageSize = dataSize*packetsPerFrame; imageSize = dataSize*packetsPerFrame;
maxFramesPerFile = EIGER_MAX_FRAMES_PER_FILE; maxFramesPerFile = EIGER_MAX_FRAMES_PER_FILE;
fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header); fifoBufferHeaderSize= FIFO_HEADER_NUMBYTES + sizeof(slsDetectorDefs::sls_receiver_header);
defaultFifoDepth = 100; defaultFifoDepth = 1000;
threadsPerReceiver = 2; threadsPerReceiver = 2;
headerPacketSize = 40; headerPacketSize = 40;
standardheader = true; standardheader = true;
@ -428,6 +428,7 @@ class EigerData : public GeneralData {
void SetDynamicRange(int dr, bool tgEnable) { void SetDynamicRange(int dr, bool tgEnable) {
packetsPerFrame = (tgEnable ? 4 : 16) * dr; packetsPerFrame = (tgEnable ? 4 : 16) * dr;
imageSize = dataSize*packetsPerFrame; imageSize = dataSize*packetsPerFrame;
defaultFifoDepth = (dr == 32 ? 100 : 1000);
} }
/** /**

View File

@ -95,7 +95,13 @@ void Implementation::InitializeMembers() {
streamingSrcIP = sls::IpAddr{}; streamingSrcIP = sls::IpAddr{};
// detector parameters // detector parameters
numberOfFrames = 0; numberOfTotalFrames = 0;
numberOfFrames = 1;
numberOfTriggers = 1;
numberOfBursts = 1;
numberOfAdditionalStorageCells = 0;
timingMode = AUTO_TIMING;
burstMode = BURST_OFF;
acquisitionPeriod = SAMPLE_TIME_IN_NS; acquisitionPeriod = SAMPLE_TIME_IN_NS;
acquisitionTime = 0; acquisitionTime = 0;
subExpTime = 0; subExpTime = 0;
@ -181,7 +187,9 @@ void Implementation::SetupFifoStructure() {
fifoDepth)); fifoDepth));
} catch (...) { } catch (...) {
fifo.clear(); fifo.clear();
throw sls::RuntimeError("Could not allocate memory for fifo structure " + std::to_string(i)); fifoDepth = 0;
throw sls::RuntimeError("Could not allocate memory for fifo structure " +
std::to_string(i) + ". FifoDepth is now 0.");
} }
// set the listener & dataprocessor threads to point to the right fifo // set the listener & dataprocessor threads to point to the right fifo
if (listener.size()) if (listener.size())
@ -267,7 +275,7 @@ void Implementation::setDetectorType(const detectorType d) {
auto fifo_ptr = fifo[i].get(); auto fifo_ptr = fifo[i].get();
listener.push_back(sls::make_unique<Listener>( listener.push_back(sls::make_unique<Listener>(
i, myDetectorType, fifo_ptr, &status, &udpPortNum[i], &eth[i], i, myDetectorType, fifo_ptr, &status, &udpPortNum[i], &eth[i],
&numberOfFrames, &dynamicRange, &udpSocketBufferSize, &numberOfTotalFrames, &dynamicRange, &udpSocketBufferSize,
&actualUDPSocketBufferSize, &framesPerFile, &frameDiscardMode, &actualUDPSocketBufferSize, &framesPerFile, &frameDiscardMode,
&activated, &deactivatedPaddingEnable, &silentMode)); &activated, &deactivatedPaddingEnable, &silentMode));
dataProcessor.push_back(sls::make_unique<DataProcessor>( dataProcessor.push_back(sls::make_unique<DataProcessor>(
@ -347,7 +355,7 @@ void Implementation::setDetectorPositionId(const int id) {
for (unsigned int i = 0; i < dataProcessor.size(); ++i) { for (unsigned int i = 0; i < dataProcessor.size(); ++i) {
dataProcessor[i]->SetupFileWriter( dataProcessor[i]->SetupFileWriter(
fileWriteEnable, (int *)numDet, &framesPerFile, &fileName, &filePath, fileWriteEnable, (int *)numDet, &framesPerFile, &fileName, &filePath,
&fileIndex, &overwriteEnable, &detID, &numThreads, &numberOfFrames, &fileIndex, &overwriteEnable, &detID, &numThreads, &numberOfTotalFrames,
&dynamicRange, &udpPortNum[i], generalData); &dynamicRange, &udpPortNum[i], generalData);
} }
assert(numDet[1] != 0); assert(numDet[1] != 0);
@ -508,7 +516,7 @@ void Implementation::setFileWriteEnable(const bool b) {
dataProcessor[i]->SetupFileWriter( dataProcessor[i]->SetupFileWriter(
fileWriteEnable, (int *)numDet, &framesPerFile, &fileName, fileWriteEnable, (int *)numDet, &framesPerFile, &fileName,
&filePath, &fileIndex, &overwriteEnable, &detID, &numThreads, &filePath, &fileIndex, &overwriteEnable, &detID, &numThreads,
&numberOfFrames, &dynamicRange, &udpPortNum[i], generalData); &numberOfTotalFrames, &dynamicRange, &udpPortNum[i], generalData);
} }
} }
@ -594,6 +602,24 @@ uint64_t Implementation::getAcquisitionIndex() const {
return min; return min;
} }
int Implementation::getProgress() const {
// get minimum of processed frame indices
uint64_t currentFrameIndex = -1;
uint32_t flagsum = 0;
for (const auto &it : dataProcessor) {
flagsum += it->GetStartedFlag();
uint64_t curr = it->GetProcessedIndex();
currentFrameIndex = curr < currentFrameIndex ? curr : currentFrameIndex;
}
// no data processed
if (flagsum != dataProcessor.size()) {
currentFrameIndex = -1;
}
return (100.00 * ((double)(currentFrameIndex + 1) / (double)numberOfTotalFrames));
}
std::vector<uint64_t> Implementation::getNumMissingPackets() const { std::vector<uint64_t> Implementation::getNumMissingPackets() const {
std::vector<uint64_t> mp(numThreads); std::vector<uint64_t> mp(numThreads);
for (int i = 0; i < numThreads; i++) { for (int i = 0; i < numThreads; i++) {
@ -603,7 +629,7 @@ std::vector<uint64_t> Implementation::getNumMissingPackets() const {
if (numLinesReadout != MAX_EIGER_ROWS_PER_READOUT) { if (numLinesReadout != MAX_EIGER_ROWS_PER_READOUT) {
totnp = ((numLinesReadout * np) / MAX_EIGER_ROWS_PER_READOUT); totnp = ((numLinesReadout * np) / MAX_EIGER_ROWS_PER_READOUT);
} }
totnp *= numberOfFrames; totnp *= numberOfTotalFrames;
mp[i] = listener[i]->GetNumMissingPacket(stoppedFlag, totnp); mp[i] = listener[i]->GetNumMissingPacket(stoppedFlag, totnp);
} }
return mp; return mp;
@ -745,7 +771,7 @@ void Implementation::startReadout() {
// wait for all packets // wait for all packets
const int numPacketsToReceive = const int numPacketsToReceive =
numberOfFrames * generalData->packetsPerFrame * listener.size(); numberOfTotalFrames * generalData->packetsPerFrame * listener.size();
if (totalPacketsReceived != numPacketsToReceive) { if (totalPacketsReceived != numPacketsToReceive) {
while (totalPacketsReceived != previousValue) { while (totalPacketsReceived != previousValue) {
LOG(logDEBUG3) LOG(logDEBUG3)
@ -842,7 +868,7 @@ void Implementation::SetupWriter() {
attr.nPixelsX = generalData->nPixelsX; attr.nPixelsX = generalData->nPixelsX;
attr.nPixelsY = generalData->nPixelsY; attr.nPixelsY = generalData->nPixelsY;
attr.maxFramesPerFile = framesPerFile; attr.maxFramesPerFile = framesPerFile;
attr.totalFrames = numberOfFrames; attr.totalFrames = numberOfTotalFrames;
attr.exptimeNs = acquisitionTime; attr.exptimeNs = acquisitionTime;
attr.subExptimeNs = subExpTime; attr.subExptimeNs = subExpTime;
attr.subPeriodNs = subPeriod; attr.subPeriodNs = subPeriod;
@ -932,7 +958,7 @@ void Implementation::setNumberofUDPInterfaces(const int n) {
auto fifo_ptr = fifo[i].get(); auto fifo_ptr = fifo[i].get();
listener.push_back(sls::make_unique<Listener>( listener.push_back(sls::make_unique<Listener>(
i, myDetectorType, fifo_ptr, &status, &udpPortNum[i], i, myDetectorType, fifo_ptr, &status, &udpPortNum[i],
&eth[i], &numberOfFrames, &dynamicRange, &eth[i], &numberOfTotalFrames, &dynamicRange,
&udpSocketBufferSize, &actualUDPSocketBufferSize, &udpSocketBufferSize, &actualUDPSocketBufferSize,
&framesPerFile, &frameDiscardMode, &activated, &framesPerFile, &frameDiscardMode, &activated,
&deactivatedPaddingEnable, &silentMode)); &deactivatedPaddingEnable, &silentMode));
@ -963,7 +989,7 @@ void Implementation::setNumberofUDPInterfaces(const int n) {
} }
dataStreamer.push_back(sls::make_unique<DataStreamer>( dataStreamer.push_back(sls::make_unique<DataStreamer>(
i, fifo[i].get(), &dynamicRange, &roi, &fileIndex, i, fifo[i].get(), &dynamicRange, &roi, &fileIndex,
fd, (int*)nd, &quadEnable)); fd, (int*)nd, &quadEnable, &numberOfTotalFrames));
dataStreamer[i]->SetGeneralData(generalData); dataStreamer[i]->SetGeneralData(generalData);
dataStreamer[i]->CreateZmqSockets( dataStreamer[i]->CreateZmqSockets(
&numThreads, streamingPort, streamingSrcIP); &numThreads, streamingPort, streamingSrcIP);
@ -1107,7 +1133,7 @@ void Implementation::setDataStreamEnable(const bool enable) {
} }
dataStreamer.push_back(sls::make_unique<DataStreamer>( dataStreamer.push_back(sls::make_unique<DataStreamer>(
i, fifo[i].get(), &dynamicRange, &roi, &fileIndex, i, fifo[i].get(), &dynamicRange, &roi, &fileIndex,
fd, (int*)nd, &quadEnable)); fd, (int*)nd, &quadEnable, &numberOfTotalFrames));
dataStreamer[i]->SetGeneralData(generalData); dataStreamer[i]->SetGeneralData(generalData);
dataStreamer[i]->CreateZmqSockets( dataStreamer[i]->CreateZmqSockets(
&numThreads, streamingPort, streamingSrcIP); &numThreads, streamingPort, streamingSrcIP);
@ -1225,6 +1251,26 @@ void Implementation::setAdditionalJsonParameter(const std::string &key, const st
* Detector Parameters * * Detector Parameters *
* * * *
* ************************************************/ * ************************************************/
void Implementation::updateTotalNumberOfFrames() {
int64_t repeats = numberOfTriggers;
// gotthard2: auto mode
// burst mode: (bursts instead of triggers)
// non burst mode: no bursts or triggers
if (myDetectorType == GOTTHARD2 &&timingMode == AUTO_TIMING) {
if (burstMode == BURST_OFF) {
repeats = numberOfBursts;
} else {
repeats = 1;
}
}
numberOfTotalFrames = numberOfFrames * repeats *
(int64_t)(numberOfAdditionalStorageCells + 1);
if (numberOfTotalFrames == 0) {
throw sls::RuntimeError("Invalid total number of frames to receive: 0");
}
LOG(logINFO) << "Total Number of Frames: " << numberOfTotalFrames;
}
uint64_t Implementation::getNumberOfFrames() const { uint64_t Implementation::getNumberOfFrames() const {
LOG(logDEBUG3) << __SHORT_AT__ << " called"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
return numberOfFrames; return numberOfFrames;
@ -1232,9 +1278,69 @@ uint64_t Implementation::getNumberOfFrames() const {
void Implementation::setNumberOfFrames(const uint64_t i) { void Implementation::setNumberOfFrames(const uint64_t i) {
LOG(logDEBUG3) << __SHORT_AT__ << " called"; LOG(logDEBUG3) << __SHORT_AT__ << " called";
numberOfFrames = i; numberOfFrames = i;
LOG(logINFO) << "Number of Frames: " << numberOfFrames; LOG(logINFO) << "Number of Frames: " << numberOfFrames;
updateTotalNumberOfFrames();
}
uint64_t Implementation::getNumberOfTriggers() const {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
return numberOfTriggers;
}
void Implementation::setNumberOfTriggers(const uint64_t i) {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
numberOfTriggers = i;
LOG(logINFO) << "Number of Triggers: " << numberOfTriggers;
updateTotalNumberOfFrames();
}
uint64_t Implementation::getNumberOfBursts() const {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
return numberOfBursts;
}
void Implementation::setNumberOfBursts(const uint64_t i) {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
numberOfBursts = i;
LOG(logINFO) << "Number of Bursts: " << numberOfBursts;
updateTotalNumberOfFrames();
}
int Implementation::getNumberOfAdditionalStorageCells() const {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
return numberOfAdditionalStorageCells;
}
void Implementation::setNumberOfAdditionalStorageCells(const int i) {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
numberOfAdditionalStorageCells = i;
LOG(logINFO) << "Number of Additional Storage Cells: " << numberOfAdditionalStorageCells;
updateTotalNumberOfFrames();
}
slsDetectorDefs::timingMode Implementation::getTimingMode() const {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
return timingMode;
}
void Implementation::setTimingMode(const slsDetectorDefs::timingMode i) {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
timingMode = i;
LOG(logINFO) << "Timing Mode: " << timingMode;
updateTotalNumberOfFrames();
}
slsDetectorDefs::burstMode Implementation::getBurstMode() const {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
return burstMode;
}
void Implementation::setBurstMode(const slsDetectorDefs::burstMode i) {
LOG(logDEBUG3) << __SHORT_AT__ << " called";
burstMode = i;
LOG(logINFO) << "Burst Mode: " << burstMode;
updateTotalNumberOfFrames();
} }
uint64_t Implementation::getAcquisitionPeriod() const { uint64_t Implementation::getAcquisitionPeriod() const {
@ -1371,6 +1477,7 @@ void Implementation::setDynamicRange(const uint32_t i) {
// to update npixelsx, npixelsy in file writer // to update npixelsx, npixelsy in file writer
for (const auto &it : dataProcessor) for (const auto &it : dataProcessor)
it->SetPixelDimension(); it->SetPixelDimension();
fifoDepth = generalData->defaultFifoDepth;
SetupFifoStructure(); SetupFifoStructure();
} }
} }

View File

@ -75,6 +75,7 @@ class Implementation : private virtual slsDetectorDefs {
runStatus getStatus() const; runStatus getStatus() const;
uint64_t getFramesCaught() const; uint64_t getFramesCaught() const;
uint64_t getAcquisitionIndex() const; uint64_t getAcquisitionIndex() const;
int getProgress() const;
std::vector<uint64_t> getNumMissingPackets() const; std::vector<uint64_t> getNumMissingPackets() const;
void startReceiver(); void startReceiver();
void setStoppedFlag(bool stopped); void setStoppedFlag(bool stopped);
@ -134,8 +135,19 @@ class Implementation : private virtual slsDetectorDefs {
* Detector Parameters * * Detector Parameters *
* * * *
* ************************************************/ * ************************************************/
void updateTotalNumberOfFrames();
uint64_t getNumberOfFrames() const; uint64_t getNumberOfFrames() const;
void setNumberOfFrames(const uint64_t i); void setNumberOfFrames(const uint64_t i);
uint64_t getNumberOfTriggers() const;
void setNumberOfTriggers(const uint64_t i);
uint64_t getNumberOfBursts() const;
void setNumberOfBursts(const uint64_t i);
int getNumberOfAdditionalStorageCells() const;
void setNumberOfAdditionalStorageCells(const int i);
timingMode getTimingMode() const;
void setTimingMode(const timingMode i);
burstMode getBurstMode() const;
void setBurstMode(const burstMode i);
uint64_t getAcquisitionTime() const; uint64_t getAcquisitionTime() const;
void setAcquisitionTime(const uint64_t i); void setAcquisitionTime(const uint64_t i);
uint64_t getAcquisitionPeriod() const; uint64_t getAcquisitionPeriod() const;
@ -266,7 +278,13 @@ class Implementation : private virtual slsDetectorDefs {
std::map<std::string, std::string> additionalJsonHeader; std::map<std::string, std::string> additionalJsonHeader;
// detector parameters // detector parameters
uint64_t numberOfTotalFrames;
uint64_t numberOfFrames; uint64_t numberOfFrames;
uint64_t numberOfTriggers;
uint64_t numberOfBursts;
int numberOfAdditionalStorageCells;
timingMode timingMode;
burstMode burstMode;
uint64_t acquisitionPeriod; uint64_t acquisitionPeriod;
uint64_t acquisitionTime; uint64_t acquisitionTime;
uint64_t subExpTime; uint64_t subExpTime;

View File

@ -12,6 +12,7 @@
#include "container_utils.h" // For sls::make_unique<> #include "container_utils.h" // For sls::make_unique<>
#include "sls_detector_exceptions.h" #include "sls_detector_exceptions.h"
#include "UdpRxSocket.h" #include "UdpRxSocket.h"
#include "network_utils.h"
#include <cerrno> #include <cerrno>
#include <cstring> #include <cstring>
@ -25,12 +26,9 @@ Listener::Listener(int ind, detectorType dtype, Fifo* f, std::atomic<runStatus>*
int64_t* us, int64_t* as, uint32_t* fpf, int64_t* us, int64_t* as, uint32_t* fpf,
frameDiscardPolicy* fdp, bool* act, bool* depaden, bool* sm) : frameDiscardPolicy* fdp, bool* act, bool* depaden, bool* sm) :
ThreadObject(ind, TypeName), ThreadObject(ind, TypeName),
runningFlag(0),
generalData(nullptr),
fifo(f), fifo(f),
myDetectorType(dtype), myDetectorType(dtype),
status(s), status(s),
udpSocket(nullptr),
udpPortNumber(portno), udpPortNumber(portno),
eth(e), eth(e),
numImages(nf), numImages(nf),
@ -41,45 +39,22 @@ Listener::Listener(int ind, detectorType dtype, Fifo* f, std::atomic<runStatus>*
frameDiscardMode(fdp), frameDiscardMode(fdp),
activated(act), activated(act),
deactivatedPaddingEnable(depaden), deactivatedPaddingEnable(depaden),
silentMode(sm), silentMode(sm)
row(0),
column(0),
startedFlag(false),
firstIndex(0),
numPacketsCaught(0),
lastCaughtFrameIndex(0),
currentFrameIndex(0),
carryOverFlag(0),
udpSocketAlive(0),
numPacketsStatistic(0),
numFramesStatistic(0),
oddStartingPacket(true)
{ {
LOG(logDEBUG) << "Listener " << ind << " created"; LOG(logDEBUG) << "Listener " << ind << " created";
} }
Listener::~Listener() = default;
Listener::~Listener() { uint64_t Listener::GetPacketsCaught() const {
if (udpSocket){
sem_post(&semaphore_socket);
sem_destroy(&semaphore_socket);
}
}
/** getters */
bool Listener::IsRunning() {
return runningFlag;
}
uint64_t Listener::GetPacketsCaught() {
return numPacketsCaught; return numPacketsCaught;
} }
uint64_t Listener::GetLastFrameIndexCaught() { uint64_t Listener::GetLastFrameIndexCaught() const {
return lastCaughtFrameIndex; return lastCaughtFrameIndex;
} }
uint64_t Listener::GetNumMissingPacket(bool stoppedFlag, uint64_t numPackets) { uint64_t Listener::GetNumMissingPacket(bool stoppedFlag, uint64_t numPackets) const {
if (!stoppedFlag) { if (!stoppedFlag) {
return (numPackets - numPacketsCaught); return (numPackets - numPacketsCaught);
} }
@ -89,24 +64,12 @@ uint64_t Listener::GetNumMissingPacket(bool stoppedFlag, uint64_t numPackets) {
return (lastCaughtFrameIndex - firstIndex + 1) * generalData->packetsPerFrame - numPacketsCaught; return (lastCaughtFrameIndex - firstIndex + 1) * generalData->packetsPerFrame - numPacketsCaught;
} }
/** setters */
void Listener::StartRunning() {
runningFlag = true;
}
void Listener::StopRunning() {
runningFlag = false;
}
void Listener::SetFifo(Fifo* f) { void Listener::SetFifo(Fifo* f) {
fifo = f; fifo = f;
} }
void Listener::ResetParametersforNewAcquisition() { void Listener::ResetParametersforNewAcquisition() {
runningFlag = false; StopRunning();
startedFlag = false; startedFlag = false;
numPacketsCaught = 0; numPacketsCaught = 0;
firstIndex = 0; firstIndex = 0;
@ -174,10 +137,9 @@ void Listener::CreateUDPSockets() {
} }
udpSocketAlive = true; udpSocketAlive = true;
sem_init(&semaphore_socket,1,0);
// doubled due to kernel bookkeeping (could also be less due to permissions) // doubled due to kernel bookkeeping (could also be less due to permissions)
*actualUDPSocketBufferSize = udpSocket->getActualUDPSocketBufferSize(); *actualUDPSocketBufferSize = udpSocket->getBufferSize();
} }
@ -185,14 +147,8 @@ void Listener::CreateUDPSockets() {
void Listener::ShutDownUDPSocket() { void Listener::ShutDownUDPSocket() {
if(udpSocket){ if(udpSocket){
udpSocketAlive = false; udpSocketAlive = false;
udpSocket->ShutDownSocket(); udpSocket->Shutdown();
LOG(logINFO) << "Shut down of UDP port " << *udpPortNumber; LOG(logINFO) << "Shut down of UDP port " << *udpPortNumber;
fflush(stdout);
// wait only if the threads have started as it is the threads that
//give a post to semaphore(at stopListening)
if (runningFlag)
sem_wait(&semaphore_socket);
sem_destroy(&semaphore_socket);
} }
} }
@ -220,7 +176,7 @@ void Listener::CreateDummySocketForUDPSocketBufferSize(int64_t s) {
*udpSocketBufferSize); *udpSocketBufferSize);
// doubled due to kernel bookkeeping (could also be less due to permissions) // doubled due to kernel bookkeeping (could also be less due to permissions)
*actualUDPSocketBufferSize = g.getActualUDPSocketBufferSize(); *actualUDPSocketBufferSize = g.getBufferSize();
if (*actualUDPSocketBufferSize == -1) { if (*actualUDPSocketBufferSize == -1) {
*udpSocketBufferSize = temp; *udpSocketBufferSize = temp;
} else { } else {
@ -300,10 +256,8 @@ void Listener::StopListening(char* buf) {
(*((uint32_t*)buf)) = DUMMY_PACKET_VALUE; (*((uint32_t*)buf)) = DUMMY_PACKET_VALUE;
fifo->PushAddress(buf); fifo->PushAddress(buf);
StopRunning(); StopRunning();
LOG(logDEBUG1) << index << ": Listening Packets (" << *udpPortNumber << ") : " << numPacketsCaught;
sem_post(&semaphore_socket); LOG(logDEBUG1) << index << ": Listening Completed";
LOG(logDEBUG1) << index << ": Listening Packets (" << *udpPortNumber << ") : " << numPacketsCaught;
LOG(logDEBUG1) << index << ": Listening Completed";
} }

View File

@ -12,13 +12,10 @@
#include <memory> #include <memory>
#include <atomic> #include <atomic>
#include "ThreadObject.h" #include "ThreadObject.h"
#include "UdpRxSocket.h"
class GeneralData; class GeneralData;
class Fifo; class Fifo;
namespace sls{
class UdpRxSocket;
}
class Listener : private virtual slsDetectorDefs, public ThreadObject { class Listener : private virtual slsDetectorDefs, public ThreadObject {
@ -53,40 +50,20 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
*/ */
~Listener(); ~Listener();
//*** getters ***
/**
* Returns if the thread is currently running
* @returns true if thread is running, else false
*/
bool IsRunning() override;
/** /**
* Get Packets caught * Get Packets caught
* @return Packets caught * @return Packets caught
*/ */
uint64_t GetPacketsCaught(); uint64_t GetPacketsCaught() const;
/** /**
* Get Last Frame index caught * Get Last Frame index caught
* @return last frame index caught * @return last frame index caught
*/ */
uint64_t GetLastFrameIndexCaught(); uint64_t GetLastFrameIndexCaught() const;
/** Get number of missing packets */ /** Get number of missing packets */
uint64_t GetNumMissingPacket(bool stoppedFlag, uint64_t numPackets); uint64_t GetNumMissingPacket(bool stoppedFlag, uint64_t numPackets) const;
//*** setters ***
/**
* Set bit in RunningMask to allow thread to run
*/
void StartRunning();
/**
* Reset bit in RunningMask to prevent thread from running
*/
void StopRunning();
/** /**
* Set Fifo pointer to the one given * Set Fifo pointer to the one given
@ -140,7 +117,7 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
void RecordFirstIndex(uint64_t fnum); void RecordFirstIndex(uint64_t fnum);
/** /**
* Thread Exeution for Listener Class * Thread Execution for Listener Class
* Pop free addresses, listen to udp socket, * Pop free addresses, listen to udp socket,
* write to memory & push the address into fifo * write to memory & push the address into fifo
*/ */
@ -168,16 +145,11 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
*/ */
void PrintFifoStatistics(); void PrintFifoStatistics();
/** type of thread */ /** type of thread */
static const std::string TypeName; static const std::string TypeName;
/** Object running status */
std::atomic<bool> runningFlag;
/** GeneralData (Detector Data) object */ /** GeneralData (Detector Data) object */
GeneralData* generalData; GeneralData* generalData{nullptr};
/** Fifo structure */ /** Fifo structure */
Fifo* fifo; Fifo* fifo;
@ -190,7 +162,7 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
std::atomic<runStatus>* status; std::atomic<runStatus>* status;
/** UDP Socket - Detector to Receiver */ /** UDP Socket - Detector to Receiver */
std::unique_ptr<sls::UdpRxSocket> udpSocket; std::unique_ptr<sls::UdpRxSocket> udpSocket{nullptr};
/** UDP Port Number */ /** UDP Port Number */
uint32_t* udpPortNumber; uint32_t* udpPortNumber;
@ -228,36 +200,34 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
/** row hardcoded as 1D or 2d, /** row hardcoded as 1D or 2d,
* if detector does not send them yet or * if detector does not send them yet or
* missing packets/deactivated (eiger/jungfrau sends 2d pos) **/ * missing packets/deactivated (eiger/jungfrau sends 2d pos) **/
uint16_t row; uint16_t row{0};
/** column hardcoded as 2D, /** column hardcoded as 2D,
* deactivated eiger/missing packets (eiger/jungfrau sends 2d pos) **/ * deactivated eiger/missing packets (eiger/jungfrau sends 2d pos) **/
uint16_t column; uint16_t column{0};
// acquisition start // acquisition start
/** Aquisition Started flag */ /** Aquisition Started flag */
std::atomic<bool> startedFlag; std::atomic<bool> startedFlag{false};
/** Frame Number of First Frame */ /** Frame Number of First Frame */
uint64_t firstIndex; uint64_t firstIndex{0};
// for acquisition summary // for acquisition summary
/** Number of complete Packets caught */ /** Number of complete Packets caught */
std::atomic<uint64_t> numPacketsCaught; std::atomic<uint64_t> numPacketsCaught{0};
/** Last Frame Index caught from udp network */ /** Last Frame Index caught from udp network */
std::atomic<uint64_t> lastCaughtFrameIndex; std::atomic<uint64_t> lastCaughtFrameIndex{0};
// parameters to acquire image // parameters to acquire image
/** Current Frame Index, default value is 0 /** Current Frame Index, default value is 0
* ( always check startedFlag for validity first) * ( always check startedFlag for validity first)
*/ */
uint64_t currentFrameIndex; uint64_t currentFrameIndex{0};
/** True if there is a packet carry over from previous Image */ /** True if there is a packet carry over from previous Image */
bool carryOverFlag; bool carryOverFlag{false};
/** Carry over packet buffer */ /** Carry over packet buffer */
std::unique_ptr<char []> carryOverPacket; std::unique_ptr<char []> carryOverPacket;
@ -266,22 +236,19 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
std::unique_ptr<char []> listeningPacket; std::unique_ptr<char []> listeningPacket;
/** if the udp socket is connected */ /** if the udp socket is connected */
std::atomic<bool> udpSocketAlive; std::atomic<bool> udpSocketAlive{false};
/** Semaphore to synchonize deleting udp socket */ // for print progress during acquisition
sem_t semaphore_socket;
// for print progress during acqusition
/** number of packets for statistic */ /** number of packets for statistic */
uint32_t numPacketsStatistic; uint32_t numPacketsStatistic{0};
/** number of images for statistic */ /** number of images for statistic */
uint32_t numFramesStatistic; uint32_t numFramesStatistic{0};
/** /**
* starting packet number is odd or evern, accordingly increment frame number * starting packet number is odd or even, accordingly increment frame number
* to get first packet number as 0 * to get first packet number as 0
* (pecific to gotthard, can vary between modules, hence defined here) */ * (pecific to gotthard, can vary between modules, hence defined here) */
bool oddStartingPacket; bool oddStartingPacket{true};
}; };

View File

@ -42,17 +42,14 @@ int main(int argc, char *argv[]) {
LOG(logERROR) << "Could not set handler function for SIGPIPE"; LOG(logERROR) << "Could not set handler function for SIGPIPE";
} }
std::unique_ptr<Receiver> receiver = nullptr;
try { try {
receiver = sls::make_unique<Receiver>(argc, argv); Receiver r(argc, argv);
LOG(logINFO) << "[ Press \'Ctrl+c\' to exit ]";
sem_wait(&semaphore);
sem_destroy(&semaphore);
} catch (...) { } catch (...) {
LOG(logINFOBLUE) << "Exiting [ Tid: " << syscall(SYS_gettid) << " ]"; //pass
throw;
} }
LOG(logINFO) << "[ Press \'Ctrl+c\' to exit ]";
sem_wait(&semaphore);
sem_destroy(&semaphore);
LOG(logINFOBLUE) << "Exiting [ Tid: " << syscall(SYS_gettid) << " ]"; LOG(logINFOBLUE) << "Exiting [ Tid: " << syscall(SYS_gettid) << " ]";
LOG(logINFO) << "Exiting Receiver"; LOG(logINFO) << "Exiting Receiver";
return 0; return 0;

View File

@ -3,56 +3,51 @@
* @short creates/destroys a thread * @short creates/destroys a thread
***********************************************/ ***********************************************/
#include "ThreadObject.h" #include "ThreadObject.h"
#include "container_utils.h" #include "container_utils.h"
#include <iostream> #include <iostream>
#include <sys/syscall.h> #include <sys/syscall.h>
#include <unistd.h> #include <unistd.h>
ThreadObject::ThreadObject(int threadIndex, std::string threadType) ThreadObject::ThreadObject(int threadIndex, std::string threadType)
: index(threadIndex), type(threadType) { : index(threadIndex), type(threadType) {
LOG(logDEBUG) << type << " thread created: " << index; LOG(logDEBUG) << type << " thread created: " << index;
sem_init(&semaphore,1,0); sem_init(&semaphore,1,0);
try { try {
threadObject = sls::make_unique<std::thread>(&ThreadObject::RunningThread, this); threadObject = std::thread(&ThreadObject::RunningThread, this);
} catch (...) { } catch (...) {
throw sls::RuntimeError("Could not create " + type + " thread with index " + std::to_string(index)); throw sls::RuntimeError("Could not create " + type + " thread with index " + std::to_string(index));
} }
} }
ThreadObject::~ThreadObject() { ThreadObject::~ThreadObject() {
killThread = true; killThread = true;
sem_post(&semaphore); sem_post(&semaphore);
threadObject.join();
threadObject->join();
sem_destroy(&semaphore); sem_destroy(&semaphore);
} }
bool ThreadObject::IsRunning() const{
return runningFlag;
}
void ThreadObject::StartRunning() {
runningFlag = true;
}
void ThreadObject::StopRunning() {
runningFlag = false;
}
void ThreadObject::RunningThread() { void ThreadObject::RunningThread() {
LOG(logINFOBLUE) << "Created [ " << type << "Thread " << index << ", Tid: " << syscall(SYS_gettid) << "]"; LOG(logINFOBLUE) << "Created [ " << type << "Thread " << index << ", Tid: " << syscall(SYS_gettid) << "]";
LOG(logDEBUG) << type << " thread " << index << " created successfully."; while(!killThread) {
while(true) {
while(IsRunning()) { while(IsRunning()) {
ThreadExecution(); ThreadExecution();
} }
//wait till the next acquisition //wait till the next acquisition
sem_wait(&semaphore); sem_wait(&semaphore);
if(killThread) {
break;
}
} }
LOG(logDEBUG) << type << " thread with index " << index << " destroyed successfully.";
LOG(logINFOBLUE) << "Exiting [ " << type << " Thread " << index << ", Tid: " << syscall(SYS_gettid) << "]"; LOG(logINFOBLUE) << "Exiting [ " << type << " Thread " << index << ", Tid: " << syscall(SYS_gettid) << "]";
} }
@ -61,11 +56,10 @@ void ThreadObject::Continue() {
sem_post(&semaphore); sem_post(&semaphore);
} }
void ThreadObject::SetThreadPriority(int priority) { void ThreadObject::SetThreadPriority(int priority) {
struct sched_param param; struct sched_param param;
param.sched_priority = priority; param.sched_priority = priority;
if (pthread_setschedparam(threadObject->native_handle(), SCHED_FIFO, &param) == EPERM) { if (pthread_setschedparam(threadObject.native_handle(), SCHED_FIFO, &param) == EPERM) {
if (index == 0) { if (index == 0) {
LOG(logWARNING) << "Could not prioritize " << type << " thread. " LOG(logWARNING) << "Could not prioritize " << type << " thread. "
"(No Root Privileges?)"; "(No Root Privileges?)";

View File

@ -7,41 +7,40 @@
*@short creates/destroys a thread *@short creates/destroys a thread
*/ */
#include "sls_detector_defs.h"
#include "logger.h" #include "logger.h"
#include "sls_detector_defs.h"
#include <atomic>
#include <thread>
#include <semaphore.h> #include <semaphore.h>
#include <string> #include <string>
#include <atomic>
#include <future>
class ThreadObject : private virtual slsDetectorDefs { class ThreadObject : private virtual slsDetectorDefs {
protected:
const int index{0};
public: private:
ThreadObject(int threadIndex, std::string threadType); std::atomic<bool> killThread{false};
virtual ~ThreadObject(); std::atomic<bool> runningFlag{false};
virtual bool IsRunning() = 0; std::thread threadObject;
void Continue(); sem_t semaphore;
void SetThreadPriority(int priority); const std::string type;
protected: public:
virtual void ThreadExecution() = 0; ThreadObject(int threadIndex, std::string threadType);
virtual ~ThreadObject();
bool IsRunning() const;
void StartRunning();
void StopRunning();
void Continue();
void SetThreadPriority(int priority);
private: private:
/** virtual void ThreadExecution() = 0;
* Thread called: An infinite while loop in which, /**
* semaphore starts executing its contents as long RunningMask is satisfied * Thread called: An infinite while loop in which,
* Then it exits the thread on its own if killThread is true * semaphore starts executing its contents as long RunningMask is satisfied
*/ * Then it exits the thread on its own if killThread is true
void RunningThread(); */
void RunningThread();
protected:
int index{0};
std::string type;
std::atomic<bool> killThread{false};
std::unique_ptr<std::thread> threadObject;
sem_t semaphore;
}; };

View File

@ -8,6 +8,7 @@ set(SOURCES
src/ToString.cpp src/ToString.cpp
src/network_utils.cpp src/network_utils.cpp
src/ZmqSocket.cpp src/ZmqSocket.cpp
src/UdpRxSocket.cpp
) )
set(HEADERS set(HEADERS
@ -41,11 +42,13 @@ add_library(slsSupportLib SHARED
${HEADERS} ${HEADERS}
) )
check_ipo_supported(RESULT result)
if(result) if(SLS_LTO_AVAILABLE)
set_property(TARGET slsSupportLib PROPERTY INTERPROCEDURAL_OPTIMIZATION True) set_property(TARGET slsSupportLib PROPERTY INTERPROCEDURAL_OPTIMIZATION True)
endif() endif()
target_include_directories(slsSupportLib PUBLIC target_include_directories(slsSupportLib PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>" "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>" "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"

View File

@ -21,7 +21,7 @@ class DataSocket {
//No copy since the class manage the underlying socket //No copy since the class manage the underlying socket
DataSocket(const DataSocket &) = delete; DataSocket(const DataSocket &) = delete;
DataSocket &operator=(DataSocket const &) = delete; DataSocket &operator=(DataSocket const &) = delete;
int getSocketId() const { return socketId_; } int getSocketId() const { return sockfd_; }
int Send(const void *buffer, size_t size); int Send(const void *buffer, size_t size);
@ -51,9 +51,10 @@ class DataSocket {
int setReceiveTimeout(int us); int setReceiveTimeout(int us);
void close(); void close();
void shutDownSocket(); void shutDownSocket();
void shutdown();
private: private:
int socketId_ = -1; int sockfd_ = -1;
}; };
}; // namespace sls }; // namespace sls

View File

@ -1,141 +1,30 @@
#pragma once
/* /*
UdpRxSocket provies socket control to receive UDP socket class to receive data. The intended use is in the
data on a udp socket. receiver listener loop. Should be used RAII style...
It provides a drop in replacement for
genericSocket. But please be careful since
this might be deprecated in the future
*/ */
#include "network_utils.h" #include <sys/types.h> //ssize_t
#include "sls_detector_exceptions.h"
#include <cstdint>
#include <errno.h>
#include <iostream>
#include <netdb.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <vector>
namespace sls { namespace sls {
class UdpRxSocket { class UdpRxSocket {
const ssize_t packet_size; const ssize_t packet_size_;
char *buff; int sockfd_{-1};
int fd = -1;
public: public:
UdpRxSocket(int port, ssize_t packet_size, const char *hostname = nullptr, UdpRxSocket(int port, ssize_t packet_size, const char *hostname = nullptr,
ssize_t buffer_size = 0) size_t kernel_buffer_size = 0);
: packet_size(packet_size) { ~UdpRxSocket();
/* hostname = nullptr -> wildcard */ bool ReceivePacket(char *dst) noexcept;
size_t getBufferSize() const;
void setBufferSize(ssize_t size);
ssize_t getPacketSize() const noexcept;
void Shutdown();
struct addrinfo hints; // Only for backwards compatibility, this drops the EIGER small pkt, may be
memset(&hints, 0, sizeof(hints)); // removed
hints.ai_family = AF_UNSPEC; ssize_t ReceiveDataOnly(char *dst) noexcept;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = 0;
hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
struct addrinfo *res = 0;
const std::string portname = std::to_string(port);
if (getaddrinfo(hostname, portname.c_str(), &hints, &res)) {
throw RuntimeError("Failed at getaddrinfo with " +
std::string(hostname));
}
fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (fd == -1) {
throw RuntimeError("Failed to create UDP RX socket");
}
if (bind(fd, res->ai_addr, res->ai_addrlen) == -1) {
throw RuntimeError("Failed to bind UDP RX socket");
}
freeaddrinfo(res);
// If we get a specified buffer size that is larger than the set one
// we set it. Otherwise we leave it there since it could have been
// set by the rx_udpsocksize command
if (buffer_size) {
auto current = getBufferSize() / 2;
if (current < buffer_size) {
setBufferSize(buffer_size);
if (getBufferSize() / 2 < buffer_size) {
LOG(logWARNING)
<< "Could not set buffer size. Got: "
<< getBufferSize() / 2 << " instead of " << buffer_size;
}
}
}
// Allocate at the end to avoid memory leak if we throw
buff = new char[packet_size];
}
~UdpRxSocket() {
delete[] buff;
Shutdown();
}
const char *LastPacket() const noexcept { return buff; }
ssize_t getPacketSize() const noexcept { return packet_size; }
bool ReceivePacket() noexcept { return ReceivePacket(buff); }
bool ReceivePacket(char *dst, int flags = 0) noexcept {
auto bytes_received =
recvfrom(fd, dst, packet_size, flags, nullptr, nullptr);
return bytes_received == packet_size;
}
bool PeekPacket() noexcept{
return ReceivePacket(buff, MSG_PEEK);
}
// Only for backwards compatibility this function will be removed during
// refactoring of the receiver
ssize_t ReceiveDataOnly(char *dst) {
auto r = recvfrom(fd, dst, packet_size, 0, nullptr, nullptr);
constexpr ssize_t eiger_header_packet =
40; // only detector that has this
if (r == eiger_header_packet) {
LOG(logWARNING) << "Got header pkg";
r = recvfrom(fd, dst, packet_size, 0, nullptr, nullptr);
}
return r;
}
ssize_t getBufferSize() const {
uint64_t ret_size = 0;
socklen_t optlen = sizeof(uint64_t);
if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &ret_size, &optlen) == -1)
return -1;
else
return ret_size;
}
// Only for backwards compatibility will be removed
ssize_t getActualUDPSocketBufferSize() const { return getBufferSize(); }
// Only for backwards compatibility will be removed
void ShutDownSocket() { Shutdown(); }
void setBufferSize(ssize_t size) {
socklen_t optlen = sizeof(size);
if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, optlen)) {
throw RuntimeError("Could not set socket buffer size");
}
}
void Shutdown() {
shutdown(fd, SHUT_RDWR);
if (fd >= 0) {
close(fd);
fd = -1;
}
}
}; };
} // namespace sls } // namespace sls

View File

@ -40,6 +40,8 @@ struct zmqHeader {
uint64_t acqIndex{0}; uint64_t acqIndex{0};
/** frame index (starting at 0 for each acquisition) */ /** frame index (starting at 0 for each acquisition) */
uint64_t frameIndex{0}; uint64_t frameIndex{0};
/** progress in percentage */
int progress{0};
/** file name prefix */ /** file name prefix */
std::string fname{""}; std::string fname{""};
/** header from detector */ /** header from detector */

View File

@ -87,8 +87,7 @@ class slsDetectorDefs {
/** return values */ /** return values */
enum { enum {
OK, /**< function succeeded */ OK, /**< function succeeded */
FAIL, /**< function failed */ FAIL /**< function failed */
FORCE_UPDATE
}; };
/** staus mask */ /** staus mask */
@ -176,7 +175,7 @@ class slsDetectorDefs {
struct ROI { struct ROI {
int xmin{-1}; /**< is the roi xmin (in channel number) */ int xmin{-1}; /**< is the roi xmin (in channel number) */
int xmax{-1}; /**< is the roi xmax (in channel number)*/ int xmax{-1}; /**< is the roi xmax (in channel number)*/
}; }__attribute__((packed));
#else #else
typedef struct { typedef struct {
int xmin; /**< is the roi xmin (in channel number) */ int xmin; /**< is the roi xmin (in channel number) */
@ -204,7 +203,7 @@ class slsDetectorDefs {
int y{0}; int y{0};
xy() = default; xy() = default;
xy(int x, int y):x(x),y(y){}; xy(int x, int y):x(x),y(y){};
}; }__attribute__((packed));
#endif #endif
@ -245,7 +244,8 @@ class slsDetectorDefs {
AUTO_TIMING, /**< internal timing */ AUTO_TIMING, /**< internal timing */
TRIGGER_EXPOSURE, /**< trigger mode i.e. exposure is triggered */ TRIGGER_EXPOSURE, /**< trigger mode i.e. exposure is triggered */
GATED, /**< gated */ GATED, /**< gated */
BURST_TRIGGER /**< trigger a burst of frames */ BURST_TRIGGER, /**< trigger a burst of frames */
NUM_TIMING_MODES
}; };
/** /**
@ -448,7 +448,8 @@ class slsDetectorDefs {
enum burstMode { enum burstMode {
BURST_OFF, BURST_OFF,
BURST_INTERNAL, BURST_INTERNAL,
BURST_EXTERNAL BURST_EXTERNAL,
NUM_BURST_MODES
}; };
/** /**
@ -459,6 +460,44 @@ class slsDetectorDefs {
TIMING_EXTERNAL TIMING_EXTERNAL
}; };
#ifdef __cplusplus
/**
* structure to udpate receiver
*/
struct rxParameters {
detectorType detType{GENERIC};
xy multiSize;
int detId{0};
char hostname[MAX_STR_LENGTH];
int udpInterfaces{1};
int udp_dstport{0};
uint32_t udp_dstip{0U};
uint64_t udp_dstmac{0LU};
int udp_dstport2{0};
uint32_t udp_dstip2{0U};
uint64_t udp_dstmac2{0LU};
int64_t frames{0};
int64_t triggers{0};
int64_t bursts{0};
int analogSamples{0};
int digitalSamples{0};
int64_t expTimeNs{0};
int64_t periodNs{0};
int64_t subExpTimeNs{0};
int64_t subDeadTimeNs{0};
int activate{0};
int quad{0};
int dynamicRange{16};
timingMode timMode{AUTO_TIMING};
int tenGiga{0};
readoutMode roMode{ANALOG_ONLY};
uint32_t adcMask{0};
uint32_t adc10gMask{0};
ROI roi;
uint32_t countermask{0};
burstMode burstType{BURST_OFF};
}__attribute__((packed));
#endif
#ifdef __cplusplus #ifdef __cplusplus
protected: protected:
@ -480,7 +519,6 @@ struct detParameters {
int nChipX{0}; int nChipX{0};
int nChipY{0}; int nChipY{0};
int nDacs{0}; int nDacs{0};
int dynamicRange{0};
detParameters() = default; detParameters() = default;
explicit detParameters(slsDetectorDefs::detectorType type) { explicit detParameters(slsDetectorDefs::detectorType type) {
@ -491,7 +529,6 @@ struct detParameters {
nChipX = 10; nChipX = 10;
nChipY = 1; nChipY = 1;
nDacs = 8; nDacs = 8;
dynamicRange = 16;
break; break;
case slsDetectorDefs::detectorType::JUNGFRAU: case slsDetectorDefs::detectorType::JUNGFRAU:
nChanX = 256; nChanX = 256;
@ -499,7 +536,6 @@ struct detParameters {
nChipX = 4; nChipX = 4;
nChipY = 2; nChipY = 2;
nDacs = 8; nDacs = 8;
dynamicRange = 16;
break; break;
case slsDetectorDefs::detectorType::CHIPTESTBOARD: case slsDetectorDefs::detectorType::CHIPTESTBOARD:
nChanX = 36; nChanX = 36;
@ -507,7 +543,6 @@ struct detParameters {
nChipX = 1; nChipX = 1;
nChipY = 1; nChipY = 1;
nDacs = 24; nDacs = 24;
dynamicRange = 16;
break; break;
case slsDetectorDefs::detectorType::MOENCH: case slsDetectorDefs::detectorType::MOENCH:
nChanX = 32; nChanX = 32;
@ -515,7 +550,6 @@ struct detParameters {
nChipX = 1; nChipX = 1;
nChipY = 1; nChipY = 1;
nDacs = 8; nDacs = 8;
dynamicRange = 16;
break; break;
case slsDetectorDefs::detectorType::EIGER: case slsDetectorDefs::detectorType::EIGER:
nChanX = 256; nChanX = 256;
@ -523,7 +557,6 @@ struct detParameters {
nChipX = 4; nChipX = 4;
nChipY = 1; nChipY = 1;
nDacs = 16; nDacs = 16;
dynamicRange = 16;
break; break;
case slsDetectorDefs::detectorType::MYTHEN3: case slsDetectorDefs::detectorType::MYTHEN3:
nChanX = 128 * 3; nChanX = 128 * 3;
@ -531,7 +564,6 @@ struct detParameters {
nChipX = 10; nChipX = 10;
nChipY = 1; nChipY = 1;
nDacs = 16; nDacs = 16;
dynamicRange = 32;
break; break;
case slsDetectorDefs::detectorType::GOTTHARD2: case slsDetectorDefs::detectorType::GOTTHARD2:
nChanX = 128; nChanX = 128;
@ -539,7 +571,6 @@ struct detParameters {
nChipX = 10; nChipX = 10;
nChipY = 1; nChipY = 1;
nDacs = 14; nDacs = 14;
dynamicRange = 16;
break; break;
default: default:
throw sls::RuntimeError("Unknown detector type! " + std::to_string(type)); throw sls::RuntimeError("Unknown detector type! " + std::to_string(type));

View File

@ -74,7 +74,6 @@ enum detFuncs{
F_LOCK_SERVER, F_LOCK_SERVER,
F_GET_LAST_CLIENT_IP, F_GET_LAST_CLIENT_IP,
F_SET_PORT, F_SET_PORT,
F_UPDATE_CLIENT,
F_ENABLE_TEN_GIGA, F_ENABLE_TEN_GIGA,
F_SET_ALL_TRIMBITS, F_SET_ALL_TRIMBITS,
F_SET_PATTERN_IO_CONTROL, F_SET_PATTERN_IO_CONTROL,
@ -197,6 +196,8 @@ enum detFuncs{
F_GET_TIMING_SOURCE, F_GET_TIMING_SOURCE,
F_SET_TIMING_SOURCE, F_SET_TIMING_SOURCE,
F_GET_NUM_CHANNELS, F_GET_NUM_CHANNELS,
F_UPDATE_RATE_CORRECTION,
F_GET_RECEIVER_PARAMETERS,
NUM_DET_FUNCTIONS, NUM_DET_FUNCTIONS,
RECEIVER_ENUM_START = 256, /**< detector function should not exceed this (detector server should not compile anyway) */ RECEIVER_ENUM_START = 256, /**< detector function should not exceed this (detector server should not compile anyway) */
@ -207,10 +208,13 @@ enum detFuncs{
F_GET_LAST_RECEIVER_CLIENT_IP, F_GET_LAST_RECEIVER_CLIENT_IP,
F_SET_RECEIVER_PORT, F_SET_RECEIVER_PORT,
F_GET_RECEIVER_VERSION, F_GET_RECEIVER_VERSION,
F_GET_RECEIVER_TYPE,
F_SEND_RECEIVER_DETHOSTNAME,
F_RECEIVER_SET_ROI, F_RECEIVER_SET_ROI,
F_RECEIVER_SET_NUM_FRAMES, F_RECEIVER_SET_NUM_FRAMES,
F_SET_RECEIVER_NUM_TRIGGERS,
F_SET_RECEIVER_NUM_BURSTS,
F_SET_RECEIVER_NUM_ADD_STORAGE_CELLS,
F_SET_RECEIVER_TIMING_MODE,
F_SET_RECEIVER_BURST_MODE,
F_RECEIVER_SET_NUM_ANALOG_SAMPLES, F_RECEIVER_SET_NUM_ANALOG_SAMPLES,
F_RECEIVER_SET_NUM_DIGITAL_SAMPLES, F_RECEIVER_SET_NUM_DIGITAL_SAMPLES,
F_RECEIVER_SET_EXPTIME, F_RECEIVER_SET_EXPTIME,
@ -247,8 +251,6 @@ enum detFuncs{
F_SET_FLIPPED_DATA_RECEIVER, F_SET_FLIPPED_DATA_RECEIVER,
F_SET_RECEIVER_FILE_FORMAT, F_SET_RECEIVER_FILE_FORMAT,
F_GET_RECEIVER_FILE_FORMAT, F_GET_RECEIVER_FILE_FORMAT,
F_SEND_RECEIVER_DETPOSID,
F_SEND_RECEIVER_MULTIDETSIZE,
F_SET_RECEIVER_STREAMING_PORT, F_SET_RECEIVER_STREAMING_PORT,
F_GET_RECEIVER_STREAMING_PORT, F_GET_RECEIVER_STREAMING_PORT,
F_SET_RECEIVER_STREAMING_SRC_IP, F_SET_RECEIVER_STREAMING_SRC_IP,
@ -287,6 +289,9 @@ enum detFuncs{
F_INCREMENT_FILE_INDEX, F_INCREMENT_FILE_INDEX,
F_SET_ADDITIONAL_JSON_PARAMETER, F_SET_ADDITIONAL_JSON_PARAMETER,
F_GET_ADDITIONAL_JSON_PARAMETER, F_GET_ADDITIONAL_JSON_PARAMETER,
F_GET_RECEIVER_PROGRESS,
F_SETUP_RECEIVER,
NUM_REC_FUNCTIONS NUM_REC_FUNCTIONS
}; };
@ -357,7 +362,6 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_LOCK_SERVER: return "F_LOCK_SERVER"; case F_LOCK_SERVER: return "F_LOCK_SERVER";
case F_GET_LAST_CLIENT_IP: return "F_GET_LAST_CLIENT_IP"; case F_GET_LAST_CLIENT_IP: return "F_GET_LAST_CLIENT_IP";
case F_SET_PORT: return "F_SET_PORT"; case F_SET_PORT: return "F_SET_PORT";
case F_UPDATE_CLIENT: return "F_UPDATE_CLIENT";
case F_ENABLE_TEN_GIGA: return "F_ENABLE_TEN_GIGA"; case F_ENABLE_TEN_GIGA: return "F_ENABLE_TEN_GIGA";
case F_SET_ALL_TRIMBITS: return "F_SET_ALL_TRIMBITS"; case F_SET_ALL_TRIMBITS: return "F_SET_ALL_TRIMBITS";
case F_SET_PATTERN_IO_CONTROL: return "F_SET_PATTERN_IO_CONTROL"; case F_SET_PATTERN_IO_CONTROL: return "F_SET_PATTERN_IO_CONTROL";
@ -480,6 +484,8 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_GET_TIMING_SOURCE: return "F_GET_TIMING_SOURCE"; case F_GET_TIMING_SOURCE: return "F_GET_TIMING_SOURCE";
case F_SET_TIMING_SOURCE: return "F_SET_TIMING_SOURCE"; case F_SET_TIMING_SOURCE: return "F_SET_TIMING_SOURCE";
case F_GET_NUM_CHANNELS: return "F_GET_NUM_CHANNELS"; case F_GET_NUM_CHANNELS: return "F_GET_NUM_CHANNELS";
case F_UPDATE_RATE_CORRECTION: return "F_UPDATE_RATE_CORRECTION";
case F_GET_RECEIVER_PARAMETERS: return "F_GET_RECEIVER_PARAMETERS";
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";
@ -490,10 +496,14 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_GET_LAST_RECEIVER_CLIENT_IP: return "F_GET_LAST_RECEIVER_CLIENT_IP"; case F_GET_LAST_RECEIVER_CLIENT_IP: return "F_GET_LAST_RECEIVER_CLIENT_IP";
case F_SET_RECEIVER_PORT: return "F_SET_RECEIVER_PORT"; case F_SET_RECEIVER_PORT: return "F_SET_RECEIVER_PORT";
case F_GET_RECEIVER_VERSION: return "F_GET_RECEIVER_VERSION"; case F_GET_RECEIVER_VERSION: return "F_GET_RECEIVER_VERSION";
case F_GET_RECEIVER_TYPE: return "F_GET_RECEIVER_TYPE"; case F_SETUP_RECEIVER: return "F_SETUP_RECEIVER";
case F_SEND_RECEIVER_DETHOSTNAME: return "F_SEND_RECEIVER_DETHOSTNAME";
case F_RECEIVER_SET_ROI: return "F_RECEIVER_SET_ROI"; case F_RECEIVER_SET_ROI: return "F_RECEIVER_SET_ROI";
case F_RECEIVER_SET_NUM_FRAMES: return "F_RECEIVER_SET_NUM_FRAMES"; case F_RECEIVER_SET_NUM_FRAMES: return "F_RECEIVER_SET_NUM_FRAMES";
case F_SET_RECEIVER_NUM_TRIGGERS: return "F_SET_RECEIVER_NUM_TRIGGERS";
case F_SET_RECEIVER_NUM_BURSTS: return "F_SET_RECEIVER_NUM_BURSTS";
case F_SET_RECEIVER_NUM_ADD_STORAGE_CELLS: return "F_SET_RECEIVER_NUM_ADD_STORAGE_CELLS";
case F_SET_RECEIVER_TIMING_MODE: return "F_SET_RECEIVER_TIMING_MODE";
case F_SET_RECEIVER_BURST_MODE: return "F_SET_RECEIVER_BURST_MODE";
case F_RECEIVER_SET_NUM_ANALOG_SAMPLES: return "F_RECEIVER_SET_NUM_ANALOG_SAMPLES"; case F_RECEIVER_SET_NUM_ANALOG_SAMPLES: return "F_RECEIVER_SET_NUM_ANALOG_SAMPLES";
case F_RECEIVER_SET_NUM_DIGITAL_SAMPLES:return "F_RECEIVER_SET_NUM_DIGITAL_SAMPLES"; case F_RECEIVER_SET_NUM_DIGITAL_SAMPLES:return "F_RECEIVER_SET_NUM_DIGITAL_SAMPLES";
case F_RECEIVER_SET_EXPTIME: return "F_RECEIVER_SET_EXPTIME"; case F_RECEIVER_SET_EXPTIME: return "F_RECEIVER_SET_EXPTIME";
@ -530,8 +540,6 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_SET_FLIPPED_DATA_RECEIVER: return "F_SET_FLIPPED_DATA_RECEIVER"; case F_SET_FLIPPED_DATA_RECEIVER: return "F_SET_FLIPPED_DATA_RECEIVER";
case F_SET_RECEIVER_FILE_FORMAT: return "F_SET_RECEIVER_FILE_FORMAT"; case F_SET_RECEIVER_FILE_FORMAT: return "F_SET_RECEIVER_FILE_FORMAT";
case F_GET_RECEIVER_FILE_FORMAT: return "F_GET_RECEIVER_FILE_FORMAT"; case F_GET_RECEIVER_FILE_FORMAT: return "F_GET_RECEIVER_FILE_FORMAT";
case F_SEND_RECEIVER_DETPOSID: return "F_SEND_RECEIVER_DETPOSID";
case F_SEND_RECEIVER_MULTIDETSIZE: return "F_SEND_RECEIVER_MULTIDETSIZE";
case F_SET_RECEIVER_STREAMING_PORT: return "F_SET_RECEIVER_STREAMING_PORT"; case F_SET_RECEIVER_STREAMING_PORT: return "F_SET_RECEIVER_STREAMING_PORT";
case F_GET_RECEIVER_STREAMING_PORT: return "F_GET_RECEIVER_STREAMING_PORT"; case F_GET_RECEIVER_STREAMING_PORT: return "F_GET_RECEIVER_STREAMING_PORT";
case F_SET_RECEIVER_STREAMING_SRC_IP: return "F_SET_RECEIVER_STREAMING_SRC_IP"; case F_SET_RECEIVER_STREAMING_SRC_IP: return "F_SET_RECEIVER_STREAMING_SRC_IP";
@ -570,6 +578,7 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_INCREMENT_FILE_INDEX: return "F_INCREMENT_FILE_INDEX"; case F_INCREMENT_FILE_INDEX: return "F_INCREMENT_FILE_INDEX";
case F_SET_ADDITIONAL_JSON_PARAMETER: return "F_SET_ADDITIONAL_JSON_PARAMETER"; case F_SET_ADDITIONAL_JSON_PARAMETER: return "F_SET_ADDITIONAL_JSON_PARAMETER";
case F_GET_ADDITIONAL_JSON_PARAMETER: return "F_GET_ADDITIONAL_JSON_PARAMETER"; case F_GET_ADDITIONAL_JSON_PARAMETER: return "F_GET_ADDITIONAL_JSON_PARAMETER";
case F_GET_RECEIVER_PROGRESS: return "F_GET_RECEIVER_PROGRESS";
case NUM_REC_FUNCTIONS: return "NUM_REC_FUNCTIONS"; case NUM_REC_FUNCTIONS: return "NUM_REC_FUNCTIONS";
default: return "Unknown Function"; default: return "Unknown Function";

View File

@ -1,12 +1,12 @@
/** API versions */ /** API versions */
#define GITBRANCH "developer" #define GITBRANCH "setrxhostname"
#define APILIB 0x200227 #define APILIB 0x200409
#define APIRECEIVER 0x200227 #define APIRECEIVER 0x200409
#define APIGUI 0x200227 #define APIGUI 0x200409
#define APICTB 0x200311 #define APIEIGER 0x200409
#define APIGOTTHARD 0x200326 #define APICTB 0x200409
#define APIGOTTHARD2 0x200326 #define APIGOTTHARD 0x200409
#define APIJUNGFRAU 0x200326 #define APIGOTTHARD2 0x200409
#define APIMYTHEN3 0x200311 #define APIJUNGFRAU 0x200409
#define APIMOENCH 0x200326 #define APIMYTHEN3 0x200409
#define APIEIGER 0x200326 #define APIMOENCH 0x200409

View File

@ -15,13 +15,13 @@
namespace sls { namespace sls {
DataSocket::DataSocket(int socketId) : socketId_(socketId) { DataSocket::DataSocket(int socketId) : sockfd_(socketId) {
int value = 1; int value = 1;
setsockopt(socketId_, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value)); setsockopt(sockfd_, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value));
} }
DataSocket::~DataSocket() { DataSocket::~DataSocket() {
if (socketId_ <= 0) { if (sockfd_ <= 0) {
return; return;
} else { } else {
try { try {
@ -32,7 +32,7 @@ DataSocket::~DataSocket() {
} }
void DataSocket::swap(DataSocket &other) noexcept { void DataSocket::swap(DataSocket &other) noexcept {
std::swap(socketId_, other.socketId_); std::swap(sockfd_, other.sockfd_);
} }
DataSocket::DataSocket(DataSocket &&move) noexcept { move.swap(*this); } DataSocket::DataSocket(DataSocket &&move) noexcept { move.swap(*this); }
@ -121,19 +121,23 @@ int DataSocket::setTimeOut(int t_seconds) {
} }
void DataSocket::close() { void DataSocket::close() {
if (socketId_ > 0) { if (sockfd_ > 0) {
if (::close(socketId_)) { if (::close(sockfd_)) {
throw SocketError("could not close socket"); throw SocketError("could not close socket");
} }
socketId_ = -1; sockfd_ = -1;
} else { } else {
throw std::runtime_error("Socket ERROR: close called on bad socket\n"); throw std::runtime_error("Socket ERROR: close called on bad socket\n");
} }
} }
void DataSocket::shutDownSocket() { void DataSocket::shutDownSocket() {
shutdown(getSocketId(), SHUT_RDWR); ::shutdown(getSocketId(), SHUT_RDWR);
close(); close();
} }
void DataSocket::shutdown(){
::shutdown(sockfd_, SHUT_RDWR);
}
} // namespace sls } // namespace sls

View File

@ -11,7 +11,7 @@ std::string ToString(const defs::runStatus s) {
case defs::RUNNING: case defs::RUNNING:
return std::string("running"); return std::string("running");
case defs::TRANSMITTING: case defs::TRANSMITTING:
return std::string("data"); return std::string("transmitting");
case defs::RUN_FINISHED: case defs::RUN_FINISHED:
return std::string("finished"); return std::string("finished");
case defs::STOPPED: case defs::STOPPED:

View File

@ -0,0 +1,96 @@
#include "UdpRxSocket.h"
#include "network_utils.h"
#include "sls_detector_exceptions.h"
#include <cstdint>
#include <errno.h>
#include <iostream>
#include <netdb.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
namespace sls {
UdpRxSocket::UdpRxSocket(int port, ssize_t packet_size, const char *hostname,
size_t kernel_buffer_size)
: packet_size_(packet_size) {
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = 0;
hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
struct addrinfo *res = 0;
const std::string portname = std::to_string(port);
if (getaddrinfo(hostname, portname.c_str(), &hints, &res)) {
throw RuntimeError("Failed at getaddrinfo with " +
std::string(hostname));
}
sockfd_ = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (sockfd_ == -1) {
throw RuntimeError("Failed to create UDP RX socket");
}
if (bind(sockfd_, res->ai_addr, res->ai_addrlen) == -1) {
throw RuntimeError("Failed to bind UDP RX socket");
}
freeaddrinfo(res);
// If we get a specified buffer size that is larger than the set one
// we set it. Otherwise we leave it there since it could have been
// set by the rx_udpsocksize command
if (kernel_buffer_size) {
auto current = getBufferSize() / 2;
if (current < kernel_buffer_size) {
setBufferSize(kernel_buffer_size);
if (getBufferSize() / 2 < kernel_buffer_size) {
LOG(logWARNING)
<< "Could not set buffer size. Got: " << getBufferSize() / 2
<< " instead of " << kernel_buffer_size;
}
}
}
}
UdpRxSocket::~UdpRxSocket() { Shutdown(); }
ssize_t UdpRxSocket::getPacketSize() const noexcept { return packet_size_; }
bool UdpRxSocket::ReceivePacket(char *dst) noexcept{
auto bytes_received =
recvfrom(sockfd_, dst, packet_size_, 0, nullptr, nullptr);
return bytes_received == packet_size_;
}
ssize_t UdpRxSocket::ReceiveDataOnly(char *dst) noexcept {
auto r = recvfrom(sockfd_, dst, packet_size_, 0, nullptr, nullptr);
constexpr ssize_t eiger_header_packet =
40; // only detector that has this
if (r == eiger_header_packet) {
LOG(logWARNING) << "Got header pkg";
r = recvfrom(sockfd_, dst, packet_size_, 0, nullptr, nullptr);
}
return r;
}
size_t UdpRxSocket::getBufferSize() const {
size_t ret = 0;
socklen_t optlen = sizeof(ret);
if (getsockopt(sockfd_, SOL_SOCKET, SO_RCVBUF, &ret, &optlen) == -1)
throw RuntimeError("Could not get socket buffer size");
return ret;
}
void UdpRxSocket::setBufferSize(ssize_t size) {
if (setsockopt(sockfd_, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)))
throw RuntimeError("Could not set socket buffer size");
}
void UdpRxSocket::Shutdown() {
shutdown(sockfd_, SHUT_RDWR);
if (sockfd_ >= 0) {
close(sockfd_);
sockfd_ = -1;
}
}
} // namespace sls

View File

@ -158,6 +158,7 @@ int ZmqSocket::SendHeader(
"\"size\":%u, " "\"size\":%u, "
"\"acqIndex\":%lu, " "\"acqIndex\":%lu, "
"\"frameIndex\":%lu, " "\"frameIndex\":%lu, "
"\"progress\":%u, "
"\"fname\":\"%s\", " "\"fname\":\"%s\", "
"\"data\": %d, " "\"data\": %d, "
"\"completeImage\": %d, " "\"completeImage\": %d, "
@ -193,6 +194,7 @@ int ZmqSocket::SendHeader(
header.imageSize, header.imageSize,
header.acqIndex, header.acqIndex,
header.frameIndex, header.frameIndex,
header.progress,
header.fname.c_str(), header.fname.c_str(),
header.data ? 1 : 0, header.data ? 1 : 0,
header.completeImage ? 1 : 0, header.completeImage ? 1 : 0,
@ -324,6 +326,7 @@ int ZmqSocket::ParseHeader(const int index, int length, char *buff,
zHeader.imageSize = document["size"].GetUint(); zHeader.imageSize = document["size"].GetUint();
zHeader.acqIndex = document["acqIndex"].GetUint64(); zHeader.acqIndex = document["acqIndex"].GetUint64();
zHeader.frameIndex = document["frameIndex"].GetUint64(); zHeader.frameIndex = document["frameIndex"].GetUint64();
zHeader.progress = document["progress"].GetUint();
zHeader.fname = document["fname"].GetString(); zHeader.fname = document["fname"].GetString();
zHeader.frameNumber = document["frameNumber"].GetUint64(); zHeader.frameNumber = document["frameNumber"].GetUint64();

View File

@ -109,7 +109,7 @@ TEST_CASE("run status"){
using defs = slsDetectorDefs; using defs = slsDetectorDefs;
REQUIRE(ToString(defs::runStatus::ERROR) == "error"); REQUIRE(ToString(defs::runStatus::ERROR) == "error");
REQUIRE(ToString(defs::runStatus::WAITING) == "waiting"); REQUIRE(ToString(defs::runStatus::WAITING) == "waiting");
REQUIRE(ToString(defs::runStatus::TRANSMITTING) == "data"); //?? REQUIRE(ToString(defs::runStatus::TRANSMITTING) == "transmitting");
REQUIRE(ToString(defs::runStatus::RUN_FINISHED) == "finished"); REQUIRE(ToString(defs::runStatus::RUN_FINISHED) == "finished");
REQUIRE(ToString(defs::runStatus::STOPPED) == "stopped"); REQUIRE(ToString(defs::runStatus::STOPPED) == "stopped");
REQUIRE(ToString(defs::runStatus::IDLE) == "idle"); REQUIRE(ToString(defs::runStatus::IDLE) == "idle");

View File

@ -4,6 +4,14 @@
#include <future> #include <future>
#include <thread> #include <thread>
#include <vector> #include <vector>
#include <cstdint>
#include <errno.h>
#include <iostream>
#include <netdb.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
constexpr int default_port = 50001; constexpr int default_port = 50001;
@ -29,46 +37,49 @@ int open_socket(int port) {
throw sls::RuntimeError("Failed to create UDP RX socket"); throw sls::RuntimeError("Failed to create UDP RX socket");
} }
if (connect(fd, res->ai_addr, res->ai_addrlen)){ if (connect(fd, res->ai_addr, res->ai_addrlen)) {
throw sls::RuntimeError("Failed to connect socket"); throw sls::RuntimeError("Failed to connect socket");
} }
freeaddrinfo(res); freeaddrinfo(res);
return fd; return fd;
} }
TEST_CASE("Receive data on localhost") { TEST_CASE("Get packet size returns the packet size we set in the constructor"){
constexpr int port = 50001;
constexpr ssize_t packet_size = 8000;
sls::UdpRxSocket s{port, packet_size};
CHECK(s.getPacketSize() == packet_size);
}
TEST_CASE("Receive data from a vector") {
constexpr int port = 50001; constexpr int port = 50001;
std::vector<int> data_to_send{4, 5, 3, 2, 5, 7, 2, 3}; std::vector<int> data_to_send{4, 5, 3, 2, 5, 7, 2, 3};
std::vector<int> data_received(data_to_send.size());
ssize_t packet_size = ssize_t packet_size =
sizeof(decltype(data_to_send)::value_type) * data_to_send.size(); sizeof(decltype(data_to_send)::value_type) * data_to_send.size();
sls::UdpRxSocket udpsock{port, packet_size};
sls::UdpRxSocket udpsock{port, packet_size};
int fd = open_socket(port); int fd = open_socket(port);
auto n = write(fd, data_to_send.data(), packet_size); auto n = write(fd, data_to_send.data(), packet_size);
CHECK(n == packet_size); CHECK(n == packet_size);
CHECK(udpsock.ReceivePacket());
CHECK(udpsock.ReceivePacket((char*)data_received.data()));
close(fd); close(fd);
// Copy data from buffer and compare values CHECK(data_to_send == data_received);
std::vector<int> data_received(data_to_send.size());
memcpy(data_received.data(), udpsock.LastPacket(), udpsock.getPacketSize());
CHECK(data_received.size() == data_to_send.size()); // sanity check
for (size_t i = 0; i != data_to_send.size(); ++i) {
CHECK(data_to_send[i] == data_received[i]);
}
} }
TEST_CASE("Shutdown socket without hanging when waiting for data") { TEST_CASE("Shutdown socket without hanging when waiting for data") {
constexpr int port = 50001; constexpr int port = 50001;
constexpr ssize_t packet_size = 8000; constexpr ssize_t packet_size = 8000;
sls::UdpRxSocket s{port, packet_size}; sls::UdpRxSocket s{port, packet_size};
char buff[packet_size];
// Start a thread and wait for package // Start a thread and wait for package
// if the socket is left open we would block // if the socket is left open we would block
std::future<bool> ret = std::future<bool> ret =
std::async(static_cast<bool (sls::UdpRxSocket::*)()>( std::async(&sls::UdpRxSocket::ReceivePacket, &s, (char *)&buff);
&sls::UdpRxSocket::ReceivePacket),
&s);
s.Shutdown(); s.Shutdown();
auto r = ret.get(); auto r = ret.get();
@ -76,60 +87,23 @@ TEST_CASE("Shutdown socket without hanging when waiting for data") {
CHECK(r == false); // since we didn't get the packet CHECK(r == false); // since we didn't get the packet
} }
TEST_CASE("Too small packet"){ TEST_CASE("Too small packet") {
constexpr int port = 50001; constexpr int port = 50001;
sls::UdpRxSocket s(port, 2*sizeof(uint32_t)); sls::UdpRxSocket s(port, 2 * sizeof(uint32_t));
auto fd = open_socket(port); auto fd = open_socket(port);
uint32_t val = 10; uint32_t val = 10;
write(fd, &val, sizeof(val)); write(fd, &val, sizeof(val));
CHECK(s.ReceivePacket() == false); uint32_t buff[2];
CHECK(s.ReceivePacket((char *)&buff) == false);
close(fd); close(fd);
} }
TEST_CASE("Receive an int to an external buffer") {
TEST_CASE("Receive an int to internal buffer"){
int to_send = 5; int to_send = 5;
int received = -1; int received = -1;
auto fd = open_socket(default_port); auto fd = open_socket(default_port);
sls::UdpRxSocket s(default_port, sizeof(int)); sls::UdpRxSocket s(default_port, sizeof(int));
write(fd, &to_send, sizeof(to_send)); write(fd, &to_send, sizeof(to_send));
CHECK(s.ReceivePacket()); CHECK(s.ReceivePacket(reinterpret_cast<char *>(&received)));
memcpy(&received, s.LastPacket(), sizeof(int));
CHECK(received == to_send); CHECK(received == to_send);
} }
TEST_CASE("Receive an int to an external buffer"){
int to_send = 5;
int received = -1;
auto fd = open_socket(default_port);
sls::UdpRxSocket s(default_port, sizeof(int));
write(fd, &to_send, sizeof(to_send));
CHECK(s.ReceivePacket(reinterpret_cast<char*>(&received)));
CHECK(received == to_send);
}
TEST_CASE("PEEK data"){
int to_send = 5;
int to_send2 = 12;
int received = -1;
auto fd = open_socket(default_port);
sls::UdpRxSocket s(default_port, sizeof(int));
write(fd, &to_send, sizeof(to_send));
write(fd, &to_send2, sizeof(to_send));
CHECK(s.PeekPacket());
memcpy(&received, s.LastPacket(), sizeof(int));
CHECK(received == to_send);
CHECK(s.PeekPacket());
memcpy(&received, s.LastPacket(), sizeof(int));
CHECK(received == to_send);
CHECK(s.ReceivePacket());
memcpy(&received, s.LastPacket(), sizeof(int));
CHECK(received == to_send);
CHECK(s.ReceivePacket());
memcpy(&received, s.LastPacket(), sizeof(int));
CHECK(received == to_send2);
}