Compare commits

..

74 Commits

Author SHA1 Message Date
92be88ee19 zmq fixed WIP 2020-04-27 18:43:41 +02:00
56bc9c4e08 fix for segfault WIP 2020-04-27 14:00:00 +02:00
edbd70e91a free fix WIP 2020-04-27 13:53:13 +02:00
4f712fcd70 WIP 2020-04-24 15:28:41 +02:00
bb32b2f653 rxr done WIP 2020-04-24 15:13:37 +02:00
085cbbf0d6 WIP, separated rxr from module 2020-04-23 16:09:40 +02:00
45a770cf38 WIP 2020-04-23 15:16:14 +02:00
990008c9d9 WIP 2020-04-23 12:20:04 +02:00
5339e16101 port sequences and client zmq implementation needs revisit, WIP 2020-04-22 17:55:02 +02:00
c976c63fb5 WIP udp 2020-04-22 14:05:20 +02:00
9ee2d389fb WIP 2020-04-22 13:43:10 +02:00
8d0146949c WIP 2020-04-22 12:54:55 +02:00
6de68eacc2 WIP 2020-04-21 18:48:04 +02:00
94103a05b1 parallel3 fix, software version check 2020-04-21 18:27:52 +02:00
1185f1ea17 WIP, a in shm name 2020-04-21 18:02:27 +02:00
d3f420ffd4 WIP, indexstring 2020-04-21 17:14:09 +02:00
6b5511c9e5 WIP, moved bool primaryinterface to an int interface_id 2020-04-21 14:34:48 +02:00
d8aa1ab08e json para and header added 2020-04-21 14:10:07 +02:00
b4c31327d6 WIP, temp fix 2020-04-21 12:35:08 +02:00
c408f9807a Merge branch 'developer' into separateRxr 2020-04-21 11:30:23 +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
9df128fced WIP, cant compile squash for rxParameters 2020-04-20 18:35:30 +02:00
e39ec65d19 Merge branch 'developer' into separateRxr 2020-04-20 18:33:37 +02:00
601be462af WIP, rxhostname 2020-04-20 18:33:14 +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
1d31695cc1 WIP 2020-04-17 12:15:16 +02:00
df63a6dffe rx_statusL unknown, but others good WIP 2020-04-17 12:09:23 +02:00
cfa9049ed3 WIP: none to remove receivers 2020-04-17 10:34:10 +02:00
a1a5a20845 from thread sanitizer 2020-04-17 09:35:38 +02:00
9a208caca8 WIP: first connect to rxr 2020-04-16 18:20:04 +02:00
78fb8080ce WIP: some bug fixes and reducing redundant code 2020-04-16 18:07:11 +02:00
cd45f9d45b WIP, parallel 2020-04-16 16:18:50 +02:00
c725a05ef8 fix RH7 2020-04-16 15:51:28 +02:00
d536ad2b5b WIP, rxr constr done 2020-04-16 13:58:59 +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
2921cbfac8 WIP 2020-04-14 12:44:43 +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
93 changed files with 6805 additions and 5277 deletions

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

@ -3,6 +3,7 @@ set(SOURCES
src/slsDetectorUsers.cpp src/slsDetectorUsers.cpp
src/Module.cpp src/Module.cpp
src/Detector.cpp src/Detector.cpp
src/Receiver.cpp
src/CmdProxy.cpp src/CmdProxy.cpp
src/CmdParser.cpp src/CmdParser.cpp
) )

View File

@ -19,7 +19,7 @@ class IpAddr;
//Free function to avoid dependence on class //Free function to avoid dependence on class
//and avoid the option to free another objects //and avoid the option to free another objects
//shm by mistake //shm by mistake
void freeSharedMemory(int multiId, int detPos = -1); void freeSharedMemory(int detectorId, int moduleId = -1);
/** /**
@ -57,6 +57,8 @@ class Detector {
/* Frees shared memory, adds detectors to the list /* Frees shared memory, adds detectors to the list
* and updates local detector cache */ * and updates local detector cache */
void setHostname(const std::vector<std::string> &hostname); void setHostname(const std::vector<std::string> &hostname);
void setHostname(const std::vector<std::string> &hostname,
const std::vector<int> &port);
/** connects to n servers at local host starting at specific control port */ /** connects to n servers at local host starting at specific control port */
void setVirtualDetectorServers(int numServers, int startingPort); void setVirtualDetectorServers(int numServers, int startingPort);
@ -344,11 +346,15 @@ class Detector {
Result<defs::runStatus> getDetectorStatus(Positions pos = {}) const; Result<defs::runStatus> getDetectorStatus(Positions pos = {}) const;
Result<defs::runStatus> getReceiverStatus(Positions pos = {}) const; Result<defs::runStatus> getReceiverStatus() const;
/** interface is by 1 (primary udp interface),
* 2 for second udp interface [Eiger][Jungfrau] */
Result<defs::runStatus> getReceiverStatus(const int udpInterface,
Positions pos = {}) const;
Result<int64_t> getFramesCaught(Positions pos = {}) const; Result<uint64_t> getFramesCaught(Positions pos = {}) const;
Result<std::vector<uint64_t>> getNumMissingPackets(Positions pos = {}) const; Result<uint64_t> getNumMissingPackets(Positions pos = {}) const;
/** [Eiger][Jungfrau] */ /** [Eiger][Jungfrau] */
Result<uint64_t> getStartingFrameNumber(Positions pos = {}) const; Result<uint64_t> getStartingFrameNumber(Positions pos = {}) const;
@ -503,28 +509,40 @@ class Detector {
* * * *
* ************************************************/ * ************************************************/
/** interface is by 1 (primary udp interface),
* 2 for second udp interface [Eiger][Jungfrau] */
void removeReceivers(const int udpInterface);
/** true when slsReceiver is used */ /** true when slsReceiver is used */
Result<bool> getUseReceiverFlag(Positions pos = {}) const; Result<bool> getUseReceiverFlag(Positions pos = {}) const;
Result<std::string> getRxHostname(Positions pos = {}) const; /** interface is by 1 (primary udp interface),
* 2 for second udp interface [Eiger][Jungfrau]
*/
Result<std::string> getRxHostname(const int udpInterface, Positions pos = {}) const;
/** /**
* Validates and sets the receiver. * Validates and sets the receiver.
* Updates local receiver cache parameters
* Configures the detector to the receiver as UDP destination * Configures the detector to the receiver as UDP destination
* @param receiver receiver hostname or IP address, can include tcp port eg. hostname:port * interface is by 1 (primary udp interface),
* 2 for second udp interface [Eiger][Jungfrau]
*/ */
void setRxHostname(const std::string &receiver, Positions pos = {}); void setRxHostname(const int udpInterface, const std::string &hostname,
Positions pos = {});
/** multiple rx hostnames (same as setRxHostname) */ /** cannot be for multiple detectors as port is unique */
void setRxHostname(const std::vector<std::string> &name); void setRxHostname(const int udpInterface, const std::string &hostname,
const int port, int module_id);
Result<int> getRxPort(Positions pos = {}) const; /** interface is by 1 (primary udp interface),
* 2 for second udp interface [Eiger][Jungfrau] */
Result<int> getRxPort(const int udpInterface, Positions pos = {}) const;
/** Receiver TCP port (for client communication with Receiver) /** Receiver TCP port (for client communication with Receiver)
* module_id is -1 for all detectors, ports for each module is calculated * module_id is -1 for all detectors, ports for each module is calculated
* (increments) */ * (increments)
void setRxPort(int port, int module_id = -1); * interface is by 1 (primary udp interface),
* 2 for second udp interface [Eiger][Jungfrau] */
void setRxPort(const int udpInterface, const int port, int module_id = -1);
Result<int> getRxFifoDepth(Positions pos = {}) const; Result<int> getRxFifoDepth(Positions pos = {}) const;
@ -656,6 +674,9 @@ class Detector {
void setRxZmqIP(const IpAddr ip, Positions pos = {}); void setRxZmqIP(const IpAddr ip, Positions pos = {});
Result<bool> getClientZmq(Positions pos = {}) const;
void setClientZmq(const bool enable, Positions pos = {});
Result<int> getClientZmqPort(Positions pos = {}) const; Result<int> getClientZmqPort(Positions pos = {}) const;
/** /**
@ -1352,8 +1373,6 @@ class Detector {
Result<uint64_t> getRxCurrentFrameIndex(Positions pos = {}) const; Result<uint64_t> getRxCurrentFrameIndex(Positions pos = {}) const;
private:
std::vector<int> getPortNumbers(int start_port);
}; };
} // namespace sls } // namespace sls

View File

@ -115,13 +115,29 @@ std::string CmdProxy::ListCommands(int action) {
} }
/* configuration */ /* configuration */
std::pair<std::string, int>
CmdProxy::parseHostnameAndPort(std::string name) {
std::string host = name;
std::string hostname;
int port = 0;
auto res = sls::split(host, ':');
if (res.size() > 1) {
hostname = res[0];
port = StringTo<int>(res[1]);
} else {
hostname = host;
}
return std::make_pair(hostname, port);
}
std::string CmdProxy::Hostname(int action) { std::string CmdProxy::Hostname(int action) {
std::ostringstream os; std::ostringstream os;
os << cmd << ' '; os << cmd << ' ';
if (action == defs::HELP_ACTION) { if (action == defs::HELP_ACTION) {
os << "\n\tFrees shared memory and sets hostname (or IP address) of " os << "\n\tFrees shared memory and sets hostname (or IP address) of "
"all modules concatenated by +." "all modules concatenated by +.\n\t"
"[hostname or ip address]:[tcp port] Use this for virtual servers\n\t"
<< '\n'; << '\n';
} else if (action == defs::GET_ACTION) { } else if (action == defs::GET_ACTION) {
if (!args.empty()) { if (!args.empty()) {
@ -136,17 +152,35 @@ std::string CmdProxy::Hostname(int action) {
if (det_id != -1) { if (det_id != -1) {
throw sls::RuntimeError("Cannot execute this at module level"); throw sls::RuntimeError("Cannot execute this at module level");
} }
std::vector<std::string> arguments;
// only args[0], but many hostames concatenated with + // only args[0], but many hostames concatenated with +
if (args[0].find('+') != std::string::npos) { if (args[0].find('+') != std::string::npos) {
auto t = sls::split(args[0], '+'); if (args.size() > 1) {
det->setHostname(t); throw sls::RuntimeError("Cannot have concatenated hostnames and"
os << ToString(t) << '\n'; "multiple arguments");
}
arguments = sls::split(args[0], '+');
} }
// either hostnames separated by space, or single hostname // either hostnames separated by space, or single hostname
else { else {
det->setHostname(args); arguments.assign(args.begin(), args.end());
os << ToString(args) << '\n';
} }
// separate hostname and port
std::vector<std::string> hostnames;
std::vector<int> ports;
for (size_t i = 0; i < arguments.size(); ++i) {
std::pair<std::string, int> res = parseHostnameAndPort(arguments[i]);
hostnames.push_back(res.first);
if (res.second == 0) {
ports.push_back(DEFAULT_PORTNO);
} else {
ports.push_back(res.second);
}
}
det->setHostname(hostnames, ports);
auto t = det->getHostname({det_id});
os << OutString(t) << '\n';
} else { } else {
throw sls::RuntimeError("Unknown action"); throw sls::RuntimeError("Unknown action");
} }
@ -402,37 +436,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 +488,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 +588,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 +604,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 +819,60 @@ std::vector<std::string> CmdProxy::DacCommands() {
} }
/* acquisition */ /* acquisition */
std::string CmdProxy::ReceiverStatus(int action) {
int udpInterface = 1;
if (cmd == "rx_status") {
udpInterface = 1;
} else if (cmd == "rx_status2") {
udpInterface = 2;
} else {
throw sls::RuntimeError("Unknown command, use list to list all commands");
}
std::ostringstream os;
os << cmd << ' ';
if (action == defs::HELP_ACTION) {
if (cmd == "rx_status") {
os << "running, idle]\n\tReceiver listener status."
<< '\n';
} else {
os << "running, idle]\n\tReceiver listener status for second udp port."
<< '\n';
}
} else if (action == defs::GET_ACTION) {
if (args.size() != 0) {
WrongNumberOfParameters(0);
}
auto t = det->getReceiverStatus(udpInterface, {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) {
@ -848,61 +952,76 @@ std::string CmdProxy::UDPDestinationIP2(int action) {
} }
/* Receiver Config */ /* Receiver Config */
std::string CmdProxy::ReceiveHostname(int action) { std::string CmdProxy::ReceiverHostname(int action) {
int udpInterface = 1;
if (cmd == "rx_hostname") {
udpInterface = 1;
} else if (cmd == "rx_hostname2") {
udpInterface = 2;
} else {
throw sls::RuntimeError("Unknown command, use list to list all commands");
}
std::ostringstream os; std::ostringstream os;
os << cmd << ' '; os << cmd << ' ';
if (action == defs::HELP_ACTION) { if (action == defs::HELP_ACTION) {
os << "[hostname or ip address]\n\t" if (cmd == "rx_hostname") {
"[hostname or ip address]:[tcp port]\n\t" os << "[hostname or ip address]\n\t"
"[hostname1]:[tcp_port1]+[hostname2]:[tcp_port2]+\n\t" "[hostname or ip address]:[tcp port]\n\t"
"Receiver hostname or IP. If port included, then the receiver tcp port.\n\t" "Receiver hostname or IP. Port is the receiver tcp port (optional).\n\t"
"Used for TCP control communication between client and receiver " "Use 'none' to remove receivers\n\t"
"to configure receiver. Also updates receiver with detector parameters." "Used for TCP control communication between client and receiver "
<< '\n'; "to configure receiver. Also updates receiver with detector parameters.\n\t"
"TCP port must be unique, if included.\n\t"
"If port not included and not set earlier, then it takes default port 1954"
" and calculates from there. \n\t"
"[Eiger][Jungfrau] For the 2nd udp interface, use rx_hostname2."
<< '\n';
} else {
os << "[hostname or ip address]\n\t"
"[hostname or ip address]:[tcp port]\n\t"
"[Eiger][Jungfrau] Receiver hostname or IP for the second udp port. "
"Port is the receiver tcp port (optional).\n\t"
"Use 'none' to remove receivers\n\t"
"Refer rx_hostname help for details"
<< '\n';
}
} else if (action == defs::GET_ACTION) { } else if (action == defs::GET_ACTION) {
if (!args.empty()) { if (!args.empty()) {
WrongNumberOfParameters(0); WrongNumberOfParameters(0);
} }
auto t = det->getRxHostname({det_id}); auto t = det->getRxHostname(udpInterface, {det_id});
os << OutString(t) << '\n'; os << OutString(t) << '\n';
} else if (action == defs::PUT_ACTION) { } else if (action == defs::PUT_ACTION) {
if (args.size() < 1) { if (args.size() != 1) {
WrongNumberOfParameters(1); WrongNumberOfParameters(1);
} }
// multiple arguments if (args[0].find('+') != std::string::npos) {
if (args.size() > 1) { throw sls::RuntimeError("Cannot concatenate receiver hostnames");
// multiple in mulitple
if (args[0].find('+') != std::string::npos) {
throw sls::RuntimeError("Cannot add multiple receivers at module level");
}
if (det_id != -1) {
throw sls::RuntimeError("Cannot add multiple receivers at module level");
}
det->setRxHostname(args);
os << ToString(args) << '\n';
} }
// single argument std::pair<std::string, int> res = parseHostnameAndPort(args[0]);
// removing receivers
if (res.first == "none") {
det->removeReceivers(udpInterface);
os << "removed" << '\n';
}
// adding receivers
else { else {
// multiple receivers concatenated with + std::string hostname = res.first;
if (args[0].find('+') != std::string::npos) { int port = res.second;
if (det_id != -1) { if (port == 0) {
throw sls::RuntimeError("Cannot add multiple receivers at module level"); det->setRxHostname(udpInterface, hostname, {det_id});
} } else {
auto t = sls::split(args[0], '+'); det->setRxHostname(udpInterface, hostname, port, det_id);
det->setRxHostname(t);
os << ToString(t) << '\n';
}
// single receiver
else {
det->setRxHostname(args[0], {det_id});
os << ToString(args) << '\n';
} }
auto t = det->getRxHostname(udpInterface, {det_id});
os << OutString(t) << '\n';
} }
} else { } else {
throw sls::RuntimeError("Unknown action"); throw sls::RuntimeError("Unknown action");
} }
return os.str(); return os.str();
} }
/* File */ /* File */
/* ZMQ Streaming Parameters (Receiver<->Client) */ /* ZMQ Streaming Parameters (Receiver<->Client) */
/* Eiger Specific */ /* Eiger Specific */

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},
@ -719,8 +719,10 @@ class CmdProxy {
{"txndelay_right", &CmdProxy::txndelay_right}, {"txndelay_right", &CmdProxy::txndelay_right},
/* Receiver Config */ /* Receiver Config */
{"rx_hostname", &CmdProxy::ReceiveHostname}, {"rx_hostname", &CmdProxy::ReceiverHostname},
{"rx_hostname2", &CmdProxy::ReceiverHostname},
{"rx_tcpport", &CmdProxy::rx_tcpport}, {"rx_tcpport", &CmdProxy::rx_tcpport},
{"rx_tcpport2", &CmdProxy::rx_tcpport2},
{"rx_fifodepth", &CmdProxy::rx_fifodepth}, {"rx_fifodepth", &CmdProxy::rx_fifodepth},
{"rx_silent", &CmdProxy::rx_silent}, {"rx_silent", &CmdProxy::rx_silent},
{"rx_discardpolicy", &CmdProxy::rx_discardpolicy}, {"rx_discardpolicy", &CmdProxy::rx_discardpolicy},
@ -911,6 +913,7 @@ class CmdProxy {
/* configuration */ /* configuration */
std::string free(int action); std::string free(int action);
// std::string config2(int action); // std::string config2(int action);
std::pair<std::string, int> parseHostnameAndPort(std::string name);
std::string Hostname(int action); std::string Hostname(int action);
std::string VirtualServer(int action); std::string VirtualServer(int action);
std::string FirmwareVersion(int action); std::string FirmwareVersion(int action);
@ -934,11 +937,13 @@ 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);
/* Receiver Config */ /* Receiver Config */
std::string ReceiveHostname(int action); std::string ReceiverHostname(int action);
/* File */ /* File */
/* ZMQ Streaming Parameters (Receiver<->Client) */ /* ZMQ Streaming Parameters (Receiver<->Client) */
/* Eiger Specific */ /* Eiger Specific */
@ -1363,12 +1368,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.");
@ -1435,9 +1434,12 @@ class CmdProxy {
/* Receiver Config */ /* Receiver Config */
INTEGER_COMMAND(rx_tcpport, getRxPort, setRxPort, StringTo<int>, INTEGER_IND_COMMAND(rx_tcpport, getRxPort, setRxPort, StringTo<int>, 1,
"[port]\n\tTCP port for client-receiver communication. Default is 1954. Must be different if multiple receivers on same pc. Must be first command to set a receiver parameter. Multi command will automatically increment for individual modules."); "[port]\n\tTCP port for client-receiver communication. Default is 1954. Must be different if multiple receivers on same pc. Must be first command to set a receiver parameter. Multi command will automatically increment for individual modules.");
INTEGER_IND_COMMAND(rx_tcpport2, getRxPort, setRxPort, StringTo<int>, 2,
"[port]\n\t[Eiger][Jungfrau] TCP port for client-receiver communication for 2nd udp port. For details, refer rx_tcpport.");
INTEGER_COMMAND(rx_fifodepth, getRxFifoDepth, setRxFifoDepth, StringTo<int>, INTEGER_COMMAND(rx_fifodepth, getRxFifoDepth, setRxFifoDepth, StringTo<int>,
"[n_frames]\n\tSet the number of frames in the receiver fifo (buffer between listener and writer threads)."); "[n_frames]\n\tSet the number of frames in the receiver fifo (buffer between listener and writer threads).");

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,6 @@
#include "logger.h" #include "logger.h"
#include "sls_detector_defs.h" #include "sls_detector_defs.h"
class ZmqSocket;
class detectorData; class detectorData;
#include <memory> #include <memory>
@ -15,8 +14,8 @@ class detectorData;
#include <thread> #include <thread>
#include <vector> #include <vector>
#define MULTI_SHMAPIVERSION 0x190809 #define DETECTOR_SHMAPIVERSION 0x190809
#define MULTI_SHMVERSION 0x200319 #define DETECTOR_SHMVERSION 0x200319
#define SHORT_STRING_LENGTH 50 #define SHORT_STRING_LENGTH 50
#include <future> #include <future>
@ -25,12 +24,13 @@ class detectorData;
namespace sls{ namespace sls{
class Module; class Module;
class Receiver;
/** /**
* @short structure allocated in shared memory to store detector settings * @short structure allocated in shared memory to store detector settings
* for IPC and cache * for IPC and cache
*/ */
struct sharedMultiSlsDetector { struct sharedDetector {
/* FIXED PATTERN FOR STATIC FUNCTIONS. DO NOT CHANGE, ONLY APPEND /* FIXED PATTERN FOR STATIC FUNCTIONS. DO NOT CHANGE, ONLY APPEND
* ------*/ * ------*/
@ -47,7 +47,7 @@ struct sharedMultiSlsDetector {
/** last time stamp when accessing the shared memory */ /** last time stamp when accessing the shared memory */
char lastDate[SHORT_STRING_LENGTH]; char lastDate[SHORT_STRING_LENGTH];
int numberOfDetectors; int numberOfModules;
slsDetectorDefs::detectorType multiDetectorType; slsDetectorDefs::detectorType multiDetectorType;
/** END OF FIXED PATTERN /** END OF FIXED PATTERN
@ -68,12 +68,12 @@ class DetectorImpl : public virtual slsDetectorDefs {
public: public:
/** /**
* Constructor * Constructor
* @param id multi detector id * @param detector_id multi detector id
* @param verify true to verify if shared memory version matches existing * @param verify true to verify if shared memory version matches existing
* one * one
* @param update true to update last user pid, date etc * @param update true to update last user pid, date etc
*/ */
explicit DetectorImpl(int multi_id = 0, bool verify = true, explicit DetectorImpl(int detector_id = 0, bool verify = true,
bool update = true); bool update = true);
/** /**
@ -189,14 +189,460 @@ class DetectorImpl : public virtual slsDetectorDefs {
} }
template <typename RT, typename... CT>
sls::Result<RT> Parallel1(RT (sls::Receiver::*somefunc)(CT...),
std::vector<int> dPositions,
std::vector<int> rxPositions,
typename NonDeduced<CT>::type... Args) {
if (receivers.size() == 0)
throw sls::RuntimeError("No receivers added");
if (dPositions.empty() ||
(dPositions.size() == 1 && dPositions[0] == -1)) {
dPositions.resize(receivers.size());
std::iota(begin(dPositions), end(dPositions), 0);
}
if (rxPositions.empty() ||
(rxPositions.size() == 1 && rxPositions[0] == -1)) {
rxPositions.resize(receivers[0].size());
std::iota(begin(rxPositions), end(rxPositions), 0);
}
std::vector<std::future<RT>> futures;
futures.reserve(dPositions.size() * rxPositions.size());
for (size_t i : dPositions) {
if (i >= receivers.size())
throw sls::RuntimeError("Detector out of range");
// each entry
for (size_t j : rxPositions) {
futures.push_back(std::async(std::launch::async, somefunc,
receivers[i][j].get(), Args...));
}
}
sls::Result<RT> result;
result.reserve(dPositions.size() * rxPositions.size());
for (auto &i : futures) {
result.push_back(i.get());
}
return result;
}
template <typename RT, typename... CT>
sls::Result<RT> Parallel1(RT (sls::Receiver::*somefunc)(CT...) const,
std::vector<int> dPositions,
std::vector<int> rxPositions,
typename NonDeduced<CT>::type... Args) const {
if (receivers.size() == 0)
throw sls::RuntimeError("No receivers added");
if (dPositions.empty() ||
(dPositions.size() == 1 && dPositions[0] == -1)) {
dPositions.resize(receivers.size());
std::iota(begin(dPositions), end(dPositions), 0);
}
if (rxPositions.empty() ||
(rxPositions.size() == 1 && rxPositions[0] == -1)) {
rxPositions.resize(receivers[0].size());
std::iota(begin(rxPositions), end(rxPositions), 0);
}
std::vector<std::future<RT>> futures;
futures.reserve(dPositions.size() * rxPositions.size());
for (size_t i : dPositions) {
if (i >= receivers.size())
throw sls::RuntimeError("Detector out of range");
// each entry
for (size_t j : rxPositions) {
futures.push_back(std::async(std::launch::async, somefunc,
receivers[i][j].get(), Args...));
}
}
sls::Result<RT> result;
result.reserve(dPositions.size() * rxPositions.size());
for (auto &i : futures) {
result.push_back(i.get());
}
return result;
}
template <typename... CT>
void Parallel1(void (sls::Receiver::*somefunc)(CT...),
std::vector<int> dPositions,
std::vector<int> rxPositions,
typename NonDeduced<CT>::type... Args) {
if (receivers.size() == 0)
throw sls::RuntimeError("No receivers added");
if (dPositions.empty() ||
(dPositions.size() == 1 && dPositions[0] == -1)) {
dPositions.resize(receivers.size());
std::iota(begin(dPositions), end(dPositions), 0);
}
if (rxPositions.empty() ||
(rxPositions.size() == 1 && rxPositions[0] == -1)) {
rxPositions.resize(receivers[0].size());
std::iota(begin(rxPositions), end(rxPositions), 0);
}
std::vector<std::future<void>> futures;
futures.reserve(dPositions.size() * rxPositions.size());
for (size_t i : dPositions) {
if (i >= receivers.size())
throw sls::RuntimeError("Detector out of range");
// each entry
for (size_t j : rxPositions) {
futures.push_back(std::async(std::launch::async, somefunc,
receivers[i][j].get(), Args...));
}
}
for (auto &i : futures) {
i.get();
}
}
template <typename... CT>
void Parallel1(void (sls::Receiver::*somefunc)(CT...) const,
std::vector<int> dPositions,
std::vector<int> rxPositions,
typename NonDeduced<CT>::type... Args) const {
if (receivers.size() == 0)
throw sls::RuntimeError("No receivers added");
if (dPositions.empty() ||
(dPositions.size() == 1 && dPositions[0] == -1)) {
dPositions.resize(receivers.size());
std::iota(begin(dPositions), end(dPositions), 0);
}
if (rxPositions.empty() ||
(rxPositions.size() == 1 && rxPositions[0] == -1)) {
rxPositions.resize(receivers[0].size());
std::iota(begin(rxPositions), end(rxPositions), 0);
}
std::vector<std::future<void>> futures;
futures.reserve(dPositions.size() * rxPositions.size());
for (size_t i : dPositions) {
if (i >= receivers.size())
throw sls::RuntimeError("Detector out of range");
// each entry
for (size_t j : rxPositions) {
futures.push_back(std::async(std::launch::async, somefunc,
receivers[i][j].get(), Args...));
}
}
for (auto &i : futures) {
i.get();
}
}
template <typename RT, typename... CT>
sls::Result<RT> Parallel2(RT (sls::Receiver::*somefunc)(CT...),
std::vector<int> dPositions,
std::vector<int> rxPositions,
typename NonDeduced<CT>::type... Args) {
if (receivers2.size() == 0)
throw sls::RuntimeError("No receivers2 added");
if (dPositions.empty() ||
(dPositions.size() == 1 && dPositions[0] == -1)) {
dPositions.resize(receivers2.size());
std::iota(begin(dPositions), end(dPositions), 0);
}
if (rxPositions.empty() ||
(rxPositions.size() == 1 && rxPositions[0] == -1)) {
rxPositions.resize(receivers2[0].size());
std::iota(begin(rxPositions), end(rxPositions), 0);
}
std::vector<std::future<RT>> futures;
futures.reserve(dPositions.size() * rxPositions.size());
for (size_t i : dPositions) {
if (i >= receivers2.size())
throw sls::RuntimeError("Detector out of range");
// each entry
for (size_t j : rxPositions) {
futures.push_back(std::async(std::launch::async, somefunc,
receivers2[i][j].get(), Args...));
}
}
sls::Result<RT> result;
result.reserve(dPositions.size() * rxPositions.size());
for (auto &i : futures) {
result.push_back(i.get());
}
return result;
}
template <typename RT, typename... CT>
sls::Result<RT> Parallel2(RT (sls::Receiver::*somefunc)(CT...) const,
std::vector<int> dPositions,
std::vector<int> rxPositions,
typename NonDeduced<CT>::type... Args) const {
if (receivers2.size() == 0)
throw sls::RuntimeError("No receivers2 added");
if (dPositions.empty() ||
(dPositions.size() == 1 && dPositions[0] == -1)) {
dPositions.resize(receivers2.size());
std::iota(begin(dPositions), end(dPositions), 0);
}
if (rxPositions.empty() ||
(rxPositions.size() == 1 && rxPositions[0] == -1)) {
rxPositions.resize(receivers2[0].size());
std::iota(begin(rxPositions), end(rxPositions), 0);
}
std::vector<std::future<RT>> futures;
futures.reserve(dPositions.size() * rxPositions.size());
for (size_t i : dPositions) {
if (i >= receivers2.size())
throw sls::RuntimeError("Detector out of range");
// each entry
for (size_t j : rxPositions) {
futures.push_back(std::async(std::launch::async, somefunc,
receivers2[i][j].get(), Args...));
}
}
sls::Result<RT> result;
result.reserve(dPositions.size() * rxPositions.size());
for (auto &i : futures) {
result.push_back(i.get());
}
return result;
}
template <typename... CT>
void Parallel2(void (sls::Receiver::*somefunc)(CT...),
std::vector<int> dPositions,
std::vector<int> rxPositions,
typename NonDeduced<CT>::type... Args) {
if (receivers2.size() == 0)
throw sls::RuntimeError("No receivers2 added");
if (dPositions.empty() ||
(dPositions.size() == 1 && dPositions[0] == -1)) {
dPositions.resize(receivers2.size());
std::iota(begin(dPositions), end(dPositions), 0);
}
if (rxPositions.empty() ||
(rxPositions.size() == 1 && rxPositions[0] == -1)) {
rxPositions.resize(receivers2[0].size());
std::iota(begin(rxPositions), end(rxPositions), 0);
}
std::vector<std::future<void>> futures;
futures.reserve(dPositions.size() * rxPositions.size());
for (size_t i : dPositions) {
if (i >= receivers2.size())
throw sls::RuntimeError("Detector out of range");
// each entry
for (size_t j : rxPositions) {
futures.push_back(std::async(std::launch::async, somefunc,
receivers2[i][j].get(), Args...));
}
}
for (auto &i : futures) {
i.get();
}
}
template <typename... CT>
void Parallel2(void (sls::Receiver::*somefunc)(CT...) const,
std::vector<int> dPositions,
std::vector<int> rxPositions,
typename NonDeduced<CT>::type... Args) const {
if (receivers2.size() == 0)
throw sls::RuntimeError("No receivers2 added");
if (dPositions.empty() ||
(dPositions.size() == 1 && dPositions[0] == -1)) {
dPositions.resize(receivers2.size());
std::iota(begin(dPositions), end(dPositions), 0);
}
if (rxPositions.empty() ||
(rxPositions.size() == 1 && rxPositions[0] == -1)) {
rxPositions.resize(receivers2[0].size());
std::iota(begin(rxPositions), end(rxPositions), 0);
}
std::vector<std::future<void>> futures;
futures.reserve(dPositions.size() * rxPositions.size());
for (size_t i : dPositions) {
if (i >= receivers2.size())
throw sls::RuntimeError("Detector out of range");
// each entry
for (size_t j : rxPositions) {
futures.push_back(std::async(std::launch::async, somefunc,
receivers2[i][j].get(), Args...));
}
}
for (auto &i : futures) {
i.get();
}
}
// for all , but dont complain if receiver2 doesnt exist
template <typename RT, typename... CT>
sls::Result<RT> Parallel3(RT (sls::Receiver::*somefunc)(CT...),
typename NonDeduced<CT>::type... Args) {
if (receivers.size() == 0)
throw sls::RuntimeError("No receivers added");
std::vector<int> dPositions;
dPositions.resize(receivers.size());
std::iota(begin(dPositions), end(dPositions), 0);
std::vector<int> rxPositions;
rxPositions.resize(receivers[0].size());
std::iota(begin(rxPositions), end(rxPositions), 0);
// multiply by 2 if receivers2 exists
size_t futureSize = dPositions.size() * rxPositions.size() *
(receivers2.size() > 0 ? 2 : 1);
std::vector<std::future<RT>> futures;
futures.reserve(futureSize);
for (size_t i : dPositions) {
// each entry
for (size_t j : rxPositions) {
futures.push_back(std::async(std::launch::async, somefunc,
receivers[i][j].get(), Args...));
if (receivers2.size()) {
futures.push_back(std::async(std::launch::async, somefunc,
receivers2[i][j].get(), Args...));
}
}
}
sls::Result<RT> result;
result.reserve(futureSize);
for (auto &i : futures) {
result.push_back(i.get());
}
return result;
}
template <typename RT, typename... CT>
sls::Result<RT> Parallel3(RT (sls::Receiver::*somefunc)(CT...) const,
typename NonDeduced<CT>::type... Args) const {
if (receivers.size() == 0)
throw sls::RuntimeError("No receivers added");
std::vector<int> dPositions;
dPositions.resize(receivers.size());
std::iota(begin(dPositions), end(dPositions), 0);
std::vector<int> rxPositions;
rxPositions.resize(receivers[0].size());
std::iota(begin(rxPositions), end(rxPositions), 0);
// multiply by 2 if receivers2 exists
size_t futureSize = dPositions.size() * rxPositions.size() *
(receivers2.size() > 0 ? 2 : 1);
std::vector<std::future<RT>> futures;
futures.reserve(futureSize);
for (size_t i : dPositions) {
// each entry
for (size_t j : rxPositions) {
futures.push_back(std::async(std::launch::async, somefunc,
receivers[i][j].get(), Args...));
if (receivers2.size()) {
futures.push_back(std::async(std::launch::async, somefunc,
receivers2[i][j].get(), Args...));
}
}
}
sls::Result<RT> result;
result.reserve(futureSize);
for (auto &i : futures) {
result.push_back(i.get());
}
return result;
}
template <typename... CT>
void Parallel3(void (sls::Receiver::*somefunc)(CT...),
typename NonDeduced<CT>::type... Args) {
if (receivers.size() == 0)
throw sls::RuntimeError("No receivers added");
std::vector<int> dPositions;
dPositions.resize(receivers.size());
std::iota(begin(dPositions), end(dPositions), 0);
std::vector<int> rxPositions;
rxPositions.resize(receivers[0].size());
std::iota(begin(rxPositions), end(rxPositions), 0);
// multiply by 2 if receivers2 exists
size_t futureSize = dPositions.size() * rxPositions.size() *
(receivers2.size() > 0 ? 2 : 1);
std::vector<std::future<void>> futures;
futures.reserve(futureSize);
for (size_t i : dPositions) {
// each entry
for (size_t j : rxPositions) {
futures.push_back(std::async(std::launch::async, somefunc,
receivers[i][j].get(), Args...));
if (receivers2.size()) {
futures.push_back(std::async(std::launch::async, somefunc,
receivers2[i][j].get(), Args...));
}
}
}
for (auto &i : futures) {
i.get();
}
}
template <typename... CT>
void Parallel3(void (sls::Receiver::*somefunc)(CT...) const,
typename NonDeduced<CT>::type... Args) const {
if (receivers.size() == 0)
throw sls::RuntimeError("No receivers added");
std::vector<int> dPositions;
dPositions.resize(receivers.size());
std::iota(begin(dPositions), end(dPositions), 0);
std::vector<int> rxPositions;
rxPositions.resize(receivers[0].size());
std::iota(begin(rxPositions), end(rxPositions), 0);
// multiply by 2 if receivers2 exists
size_t futureSize = dPositions.size() * rxPositions.size() *
(receivers2.size() > 0 ? 2 : 1);
std::vector<std::future<void>> futures;
futures.reserve(futureSize);
for (size_t i : dPositions) {
// each entry
for (size_t j : rxPositions) {
futures.push_back(std::async(std::launch::async, somefunc,
receivers[i][j].get(), Args...));
if (receivers2.size()) {
futures.push_back(std::async(std::launch::async, somefunc,
receivers2[i][j].get(), Args...));
}
}
}
for (auto &i : futures) {
i.get();
}
}
/** set acquiring flag in shared memory */ /** set acquiring flag in shared memory */
void setAcquiringFlag(bool flag); void setAcquiringFlag(bool flag);
/** return multi detector shared memory ID */ /** return detector shared memory ID */
int getMultiId() const; int getDetectorId() const;
/** Free specific shared memory from the command line without creating object */ /** Free specific shared memory from the command line without creating object */
static void freeSharedMemory(int multiId, int detPos = -1); static void freeSharedMemory(int detectorId, int moduleId = -1);
/** Free all modules from current multi Id shared memory and delete members */ /** Free all modules from current multi Id shared memory and delete members */
void freeSharedMemory(); void freeSharedMemory();
@ -217,8 +663,18 @@ class DetectorImpl : public virtual slsDetectorDefs {
*/ */
void setVirtualDetectorServers(const int numdet, const int port); void setVirtualDetectorServers(const int numdet, const int port);
/** Sets the hostname of all sls detectors in shared memory and updates local cache */
void setHostname(const std::vector<std::string> &name); void setHostname(const std::vector<std::string> &name);
void setHostname(const std::vector<std::string> &name,
const std::vector<int> &port);
int getNumberofReceiversPerModule() const;
void initReceiver(const int udpInterface);
bool isReceiverInitialized(const int udpInterface);
void removeReceivers(const int udpInterface);
void configureReceiver(const int udpInterface, Positions pos,
const std::string &hostname);
void configureReceiver(const int udpInterface, int module_id,
const std::string &hostname, const int port);
/** Gets the total number of detectors */ /** Gets the total number of detectors */
int size() const; int size() const;
@ -236,13 +692,6 @@ class DetectorImpl : public virtual slsDetectorDefs {
/** [Eiger][Jungfrau] */ /** [Eiger][Jungfrau] */
void setGapPixelsinCallback(const bool enable); void setGapPixelsinCallback(const bool enable);
/**
* Enable data streaming to client
* @param enable 0 to disable, 1 to enable, -1 to get the value
* @returns data streaming to client enable
*/
bool enableDataStreamingToClient(int enable = -1);
/** /**
* register callback for accessing acquisition final data * register callback for accessing acquisition final data
* @param func function to be called at the end of the acquisition. * @param func function to be called at the end of the acquisition.
@ -298,7 +747,7 @@ class DetectorImpl : public virtual slsDetectorDefs {
* one * one
* @param update true to update last user pid, date etc * @param update true to update last user pid, date etc
*/ */
void setupMultiDetector(bool verify = true, bool update = true); void setupDetector(bool verify = true, bool update = true);
/** /**
* Creates shm and initializes shm structure OR * Creates shm and initializes shm structure OR
@ -324,17 +773,10 @@ class DetectorImpl : public virtual slsDetectorDefs {
/** Execute command in terminal and return result */ /** Execute command in terminal and return result */
std::string exec(const char *cmd); std::string exec(const char *cmd);
void addSlsDetector(const std::string &hostname); void addModule(const std::string &hostname, const int port);
void updateDetectorSize(); void updateDetectorSize();
/**
* Create Receiving Data Sockets
* @param destroy is true to destroy all the sockets
* @returns OK or FAIL
*/
int createReceivingDataSockets(const bool destroy = false);
/** /**
* Reads frames from receiver through a constant socket * Reads frames from receiver through a constant socket
* Called during acquire() when call back registered or when using gui * Called during acquire() when call back registered or when using gui
@ -354,13 +796,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();
@ -383,19 +819,18 @@ class DetectorImpl : public virtual slsDetectorDefs {
int kbhit(); int kbhit();
/** Multi detector Id */ /** Multi detector Id */
const int multiId{0}; const int detectorId{0};
/** Shared Memory object */ /** Shared Memory object */
sls::SharedMemory<sharedMultiSlsDetector> multi_shm{0, -1}; sls::SharedMemory<sharedDetector> detector_shm{0, -1};
/** pointers to the Module structures */ /** pointers to the Module structures */
std::vector<std::unique_ptr<sls::Module>> detectors; std::vector<std::unique_ptr<sls::Module>> detectors;
/** data streaming (down stream) enabled in client (zmq sckets created) */ /** pointers to the Receiver structures, each row for a module */
bool client_downstream{false}; std::vector<std::vector<std::unique_ptr<sls::Receiver>>> receivers;
/** for the second udp port [Eiger][Jungfrau] */
/** ZMQ Socket - Receiver to Client */ std::vector<std::vector<std::unique_ptr<sls::Receiver>>> receivers2;
std::vector<std::unique_ptr<ZmqSocket>> zmqSocket;
/** semaphore to let postprocessing thread continue for next /** semaphore to let postprocessing thread continue for next
* scan/measurement */ * scan/measurement */
@ -405,12 +840,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;

File diff suppressed because it is too large Load Diff

View File

@ -13,8 +13,9 @@
class ServerInterface; class ServerInterface;
#define SLS_SHMAPIVERSION 0x190726 #define MODULE_SHMRXVERSION 0x200415
#define SLS_SHMVERSION 0x200324 #define MODULE_SHMAPIVERSION 0x190726
#define MODULE_SHMVERSION 0x200423
namespace sls{ namespace sls{
@ -22,7 +23,7 @@ namespace sls{
* @short structure allocated in shared memory to store detector settings for * @short structure allocated in shared memory to store detector settings for
* IPC and cache * IPC and cache
*/ */
struct sharedSlsDetector { struct sharedModule {
/* FIXED PATTERN FOR STATIC FUNCTIONS. DO NOT CHANGE, ONLY APPEND ------*/ /* FIXED PATTERN FOR STATIC FUNCTIONS. DO NOT CHANGE, ONLY APPEND ------*/
@ -36,10 +37,13 @@ struct sharedSlsDetector {
/** detector type \ see :: detectorType*/ /** detector type \ see :: detectorType*/
slsDetectorDefs::detectorType myDetectorType; slsDetectorDefs::detectorType myDetectorType;
int numberOfReceivers;
int numberOfReceivers2;
/** END OF FIXED PATTERN -----------------------------------------------*/ /** END OF FIXED PATTERN -----------------------------------------------*/
/** Number of detectors in multi list in x dir and y dir */ /** Number of detectors in multi list in x dir and y dir */
slsDetectorDefs::xy multiSize; slsDetectorDefs::xy detectorSize;
/** is the port used for control functions */ /** is the port used for control functions */
int controlPort; int controlPort;
@ -62,54 +66,8 @@ 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 */
char rxHostname[MAX_STR_LENGTH];
/** is the TCP port used to communicate between client and the receiver */
int rxTCPPort;
/** is set if the receiver hostname given and is connected,
* unset if socket connection is not possible */
bool useReceiverFlag;
/** tcp port from gui/different process to receiver (only data) */
int zmqport;
/** zmq tcp src ip address in client (only data) **/
sls::IpAddr zmqip;
/** num udp interfaces */ /** num udp interfaces */
int numUDPInterfaces; int numUDPInterfaces;
/** stopped flag to inform rxr */
bool stoppedFlag;
}; };
class Module : public virtual slsDetectorDefs { class Module : public virtual slsDetectorDefs {
@ -117,22 +75,22 @@ class Module : public virtual slsDetectorDefs {
/** /**
* Constructor called when creating new shared memory * Constructor called when creating new shared memory
* @param type detector type * @param type detector type
* @param multi_id multi detector shared memory id * @param detector_id multi detector shared memory id
* @param id sls detector id (position in detectors list) * @param module_id module id (position in detectors list)
* @param verify true to verify if shared memory version matches existing * @param verify true to verify if shared memory version matches existing
* one * one
*/ */
explicit Module(detectorType type, int multi_id = 0, int det_id = 0, explicit Module(detectorType type, int detector_id = 0, int module_id = 0,
bool verify = true); bool verify = true);
/** /**
* Constructor called when opening existing shared memory * Constructor called when opening existing shared memory
* @param multi_id multi detector shared memory id * @param detector_id multi detector shared memory id
* @param id sls detector id (position in detectors list) * @param module_id module id (position in detectors list)
* @param verify true to verify if shared memory version matches existing * @param verify true to verify if shared memory version matches existing
* one * one
*/ */
explicit Module(int multi_id = 0, int det_id = 0, bool verify = true); explicit Module(int detector_id = 0, int module_id = 0, bool verify = true);
/** /**
* Destructor * Destructor
@ -145,10 +103,12 @@ class Module : public virtual slsDetectorDefs {
*/ */
bool isFixedPatternSharedMemoryCompatible(); bool isFixedPatternSharedMemoryCompatible();
/** static bool hasSharedMemoryReceiverList(int version);
* Check version compatibility with receiver software
*/ int getNumberOfReceivers() const;
void checkReceiverVersionCompatibility(); void setNumberOfReceivers(const int num);
int getNumberOfReceivers2() const;
void setNumberOfReceivers2(const int num);
/** /**
* Check version compatibility with detector software * Check version compatibility with detector software
@ -161,14 +121,9 @@ class Module : public virtual slsDetectorDefs {
int64_t getSerialNumber(); int64_t getSerialNumber();
/**
* Get Receiver Software version
*/
int64_t getReceiverSoftwareVersion() const;
/** /**
* Free shared memory and delete shared memory structure * Free shared memory and delete shared memory structure
* occupied by the sharedSlsDetector structure * occupied by the sharedModule structure
* Is only safe to call if one deletes the Module object afterward * Is only safe to call if one deletes the Module object afterward
* and frees multi shared memory/updates * and frees multi shared memory/updates
* thisMultiDetector->numberOfDetectors * thisMultiDetector->numberOfDetectors
@ -203,13 +158,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
@ -247,12 +195,12 @@ class Module : public virtual slsDetectorDefs {
* Set Detector offset in shared memory in dimension d * Set Detector offset in shared memory in dimension d
* @param det detector size * @param det detector size
*/ */
void updateMultiSize(slsDetectorDefs::xy det); void updateDetectorSize(slsDetectorDefs::xy det);
int setControlPort(int port_number); int setControlPort(int port_number);
/** /**
* Returns the detector TCP control port \sa sharedSlsDetector * Returns the detector TCP control port
* @returns the detector TCP control port * @returns the detector TCP control port
*/ */
int getControlPort() const; int getControlPort() const;
@ -260,19 +208,11 @@ class Module : public virtual slsDetectorDefs {
int setStopPort(int port_number); int setStopPort(int port_number);
/** /**
* Returns the detector TCP stop port \sa sharedSlsDetector * Returns the detector TCP stop port
* @returns the detector TCP stop port * @returns the detector TCP stop port
*/ */
int getStopPort() const; int getStopPort() const;
int setReceiverPort(int port_number);
/**
* Returns the receiver TCP port \sa sharedSlsDetector
* @returns the receiver TCP port
*/
int getReceiverPort() const;
/** /**
* Lock server for this client IP * Lock server for this client IP
* @param p 0 to unlock, 1 to lock (-1 gets) * @param p 0 to unlock, 1 to lock (-1 gets)
@ -298,21 +238,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 +251,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)
@ -359,13 +280,13 @@ class Module : public virtual slsDetectorDefs {
int tb = 1); int tb = 1);
/** /**
* Returns the detector trimbit/settings directory \sa sharedSlsDetector * Returns the detector trimbit/settings directory
* @returns the trimbit/settings directory * @returns the trimbit/settings directory
*/ */
std::string getSettingsDir(); std::string getSettingsDir();
/** /**
* Sets the detector trimbit/settings directory \sa sharedSlsDetector * Sets the detector trimbit/settings directory
* @param s trimbits/settings directory * @param s trimbits/settings directory
* @returns the trimbit/settings directory * @returns the trimbit/settings directory
*/ */
@ -445,10 +366,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 +473,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
@ -696,21 +608,8 @@ class Module : public virtual slsDetectorDefs {
*/ */
uint32_t clearBit(uint32_t addr, int n); uint32_t clearBit(uint32_t addr, int n);
/** /** gets receiver parameters from detector and shared memory */
* Validates and sets the receiver. rxParameters getReceiverParameters();
* Also updates the receiver with all the shared memory parameters
* significant for the receiver Also configures the detector to the receiver
* as UDP destination
* @param receiver receiver hostname or IP address
* @returns the receiver IP address from shared memory
*/
std::string setReceiverHostname(const std::string &receiver);
/**
* Returns the receiver IP address\sa sharedSlsDetector
* @returns the receiver IP address
*/
std::string getReceiverHostname() const;
/** /**
* Validates the format of the detector MAC address and sets it * Validates the format of the detector MAC address and sets it
@ -776,13 +675,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 +690,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
@ -831,26 +716,26 @@ class Module : public virtual slsDetectorDefs {
sls::MacAddr getDestinationUDPMAC2(); sls::MacAddr getDestinationUDPMAC2();
/** /**
* Sets the receiver UDP port\sa sharedSlsDetector * Sets the receiver UDP port
* @param udpport receiver UDP port * @param udpport receiver UDP port
*/ */
void setDestinationUDPPort(int udpport); void setDestinationUDPPort(int udpport);
/** /**
* Returns the receiver UDP port\sa sharedSlsDetector * Returns the receiver UDP port
* @returns the receiver UDP port * @returns the receiver UDP port
*/ */
int getDestinationUDPPort(); int getDestinationUDPPort();
/** /**
* Sets the receiver UDP port 2\sa sharedSlsDetector (Eiger and Jungfrau * Sets the receiver UDP port 2 (Eiger and Jungfrau
* only) * only)
* @param udpport receiver UDP port 2 * @param udpport receiver UDP port 2
*/ */
void setDestinationUDPPort2(int udpport); void setDestinationUDPPort2(int udpport);
/** /**
* Returns the receiver UDP port 2 of same interface\sa sharedSlsDetector * Returns the receiver UDP port 2 of same interface
* (Eiger and Jungfrau only) * (Eiger and Jungfrau only)
* @returns the receiver UDP port 2 of same interface * @returns the receiver UDP port 2 of same interface
*/ */
@ -889,53 +774,7 @@ class Module : public virtual slsDetectorDefs {
*/ */
int getSelectedUDPInterface(); int getSelectedUDPInterface();
/** std::string printUDPConfiguration();
* Sets the client zmq port\sa sharedSlsDetector
* @param port client zmq port
*/
void setClientStreamingPort(int port);
/**
* Returns the client zmq port \sa sharedSlsDetector
* @returns the client zmq port
*/
int getClientStreamingPort();
/**
* Sets the receiver zmq port\sa sharedSlsDetector
* @param port receiver zmq port
*/
void setReceiverStreamingPort(int port);
/**
* Returns the receiver zmq port \sa sharedSlsDetector
* @returns the receiver zmq port
*/
int getReceiverStreamingPort();
/**
* Sets the client zmq ip\sa sharedSlsDetector
* @param ip client zmq ip
*/
void setClientStreamingIP(const sls::IpAddr ip);
/**
* Returns the client zmq ip \sa sharedSlsDetector
* @returns the client zmq ip
*/
sls::IpAddr getClientStreamingIP();
/**
* Sets the receiver zmq ip\sa sharedSlsDetector
* @param ip receiver zmq ip
*/
void setReceiverStreamingIP(const sls::IpAddr ip);
/**
* Returns the receiver zmq ip \sa sharedSlsDetector
* @returns the receiver zmq ip
*/
sls::IpAddr getReceiverStreamingIP();
/** update receiver stremaing ip from shm to receiver /** update receiver stremaing ip from shm to receiver
* if empty, use rx_hostname ip * if empty, use rx_hostname ip
@ -979,35 +818,6 @@ class Module : public virtual slsDetectorDefs {
*/ */
void setTransmissionDelayRight(int value); void setTransmissionDelayRight(int value);
/** empty vector deletes entire additional json header */
void setAdditionalJsonHeader(const std::map<std::string, std::string> &jsonHeader);
std::map<std::string, std::string> getAdditionalJsonHeader();
/**
* Sets the value for the additional json header parameter key if found, else
* append it. If value empty, then deletes parameter */
void setAdditionalJsonParameter(const std::string &key, const std::string &value);
std::string getAdditionalJsonParameter(const std::string &key);
/**
* Sets the receiver UDP socket buffer size
* @param udpsockbufsize additional json header
* @returns receiver udp socket buffer size
*/
int64_t setReceiverUDPSocketBufferSize(int64_t udpsockbufsize = -1);
/**
* Returns the receiver UDP socket buffer size\sa sharedSlsDetector
* @returns the receiver UDP socket buffer size
*/
int64_t getReceiverUDPSocketBufferSize();
/**
* Returns the receiver real UDP socket buffer size\sa sharedSlsDetector
* @returns the receiver real UDP socket buffer size
*/
int64_t getReceiverRealUDPSocketBufferSize() const;
/** [Gotthard][Jungfrau][CTB][Moench] */ /** [Gotthard][Jungfrau][CTB][Moench] */
void executeFirmwareTest(); void executeFirmwareTest();
@ -1085,28 +895,10 @@ class Module : public virtual slsDetectorDefs {
*/ */
slsDetectorDefs::ROI getROI(); slsDetectorDefs::ROI getROI();
/**
* Set ADC Enable Mask (CTB, Moench)
* @param mask ADC Enable mask
*/
void setADCEnableMask(uint32_t mask); void setADCEnableMask(uint32_t mask);
/**
* Get ADC Enable Mask (CTB, Moench)
* @returns ADC Enable mask
*/
uint32_t getADCEnableMask(); uint32_t getADCEnableMask();
/**
* Set 10Gb ADC Enable Mask (CTB, Moench)
* @param mask ADC Enable mask
*/
void setTenGigaADCEnableMask(uint32_t mask); void setTenGigaADCEnableMask(uint32_t mask);
/**
* Get 10Gb ADC Enable Mask (CTB, Moench)
* @returns ADC Enable mask
*/
uint32_t getTenGigaADCEnableMask(); uint32_t getTenGigaADCEnableMask();
/** /**
@ -1153,14 +945,6 @@ class Module : public virtual slsDetectorDefs {
*/ */
int getExternalSampling(); int getExternalSampling();
/** digital data bits enable (CTB only) */
void setReceiverDbitList(const std::vector<int>& list);
std::vector<int> getReceiverDbitList() const;
/** Set digital data offset in bytes (CTB only) */
void setReceiverDbitOffset(int value);
int getReceiverDbitOffset();
/** /**
* Write to ADC register (Gotthard, Jungfrau, ChipTestBoard). For expert * Write to ADC register (Gotthard, Jungfrau, ChipTestBoard). For expert
* users * users
@ -1169,32 +953,10 @@ class Module : public virtual slsDetectorDefs {
*/ */
void writeAdcRegister(uint32_t addr, uint32_t val); void writeAdcRegister(uint32_t addr, uint32_t val);
/** /** [Eiger] */
* Activates/Deactivates the detector (Eiger only) bool getActivate();
* @param enable active (1) or inactive (0), -1 gets /** [Eiger] */
* @returns 0 (inactive) or 1 (active)for activate mode void setActivate(const bool enable);
*/
int activate(int const enable = -1);
bool getDeactivatedRxrPaddingMode();
/**
* Set deactivated Receiver padding mode (Eiger only)
*/
void setDeactivatedRxrPaddingMode(bool padding);
/**
* Returns the enable if data will be flipped across x axis (Eiger)
* @returns if flipped across x axis
*/
bool getFlippedDataX();
/**
* Sets the enable which determines if
* data will be flipped across x axis (Eiger)
* @param value 0 or 1 to reset/set
*/
void setFlippedDataX(bool value);
/** /**
* Sets all the trimbits to a particular value (Eiger) * Sets all the trimbits to a particular value (Eiger)
@ -1205,7 +967,6 @@ class Module : public virtual slsDetectorDefs {
/** /**
* Sets the number of trim energies and their value (Eiger) * Sets the number of trim energies and their value (Eiger)
* \sa sharedSlsDetector
* @param nen number of energies * @param nen number of energies
* @param vector os trimmed energies * @param vector os trimmed energies
* @returns number of trim energies * @returns number of trim energies
@ -1214,7 +975,6 @@ class Module : public virtual slsDetectorDefs {
/** /**
* Returns a vector with the trimmed energies (Eiger) * Returns a vector with the trimmed energies (Eiger)
* \sa sharedSlsDetector
* @returns vector with the trimmed energies * @returns vector with the trimmed energies
*/ */
std::vector<int> getTrimEn(); std::vector<int> getTrimEn();
@ -1363,168 +1123,8 @@ class Module : public virtual slsDetectorDefs {
*/ */
void updateRateCorrection(); void updateRateCorrection();
/** bool getTenGiga();
* Prints receiver configuration void setTenGiga(bool value);
* @returns receiver configuration
*/
std::string printReceiverConfiguration();
/**
* Gets the use receiver flag from shared memory
*/
bool getUseReceiverFlag() const;
/**
* Locks/Unlocks the connection to the receiver
* @param lock sets (1), usets (0), gets (-1) the lock
* @returns lock status of the receiver
*/
int lockReceiver(int lock = -1);
/**
* Returns the IP of the last client connecting to the receiver
* @returns the IP of the last client connecting to the receiver
*/
sls::IpAddr getReceiverLastClientIP() const;
/**
* Exits the receiver TCP server
*/
void exitReceiver();
/**
* Executes a system command on the receiver server
* e.g. mount an nfs disk, reboot and returns answer etc.
* @param cmd command to be executed
*/
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();
void setFilePath(const std::string &path);
std::string getFileName();
void setFileName(const std::string &fname);
int64_t getFileIndex();
void setFileIndex(int64_t file_index);
void incrementFileIndex();
fileFormat getFileFormat() ;
void setFileFormat(fileFormat f);
int getFramesPerFile();
/** 0 will set frames per file to unlimited */
void setFramesPerFile(int n_frames);
frameDiscardPolicy getReceiverFramesDiscardPolicy();
void setReceiverFramesDiscardPolicy(frameDiscardPolicy f);
bool getPartialFramesPadding();
void setPartialFramesPadding(bool padding);
/**
* Receiver starts listening to packets
*/
void startReceiver();
/**
* Stops the listening mode of receiver
*/
void stopReceiver();
/**
* Gets the status of the listening mode of receiver
* @returns status
*/
runStatus getReceiverStatus() const;
/**
* Gets the number of frames caught by receiver
* @returns number of frames caught by receiver
*/
int64_t getFramesCaughtByReceiver() const;
/** Gets number of missing packets */
std::vector<uint64_t> getNumMissingPackets() const;
/**
* Gets the current frame index of receiver
* @returns current frame index of receiver
*/
uint64_t getReceiverCurrentFrameIndex() const;
void setFileWrite(bool value);
bool getFileWrite();
void setMasterFileWrite(bool value);
bool getMasterFileWrite();
void setFileOverWrite(bool value);
bool getFileOverWrite();
int getReceiverStreamingFrequency();
/**
* (previously setReadReceiverFrequency)
* Sets the receiver streaming frequency
* @param freq nth frame streamed out, if 0, streamed out at a timer of 200
* ms
* @param detPos -1 for all detectors in list or specific detector position
*/
void setReceiverStreamingFrequency(int freq);
/**
* (previously setReceiverReadTimer)
* Sets the receiver streaming timer
* If receiver streaming frequency is 0, then this timer between each
* data stream is set. Default is 200 ms.
* @param time_in_ms timer between frames
* @returns receiver streaming timer in ms
*/
int setReceiverStreamingTimer(int time_in_ms = 200);
bool getReceiverStreaming();
void setReceiverStreaming(bool enable);
/**
* Enable/disable or 10Gbe
* @param i is -1 to get, 0 to disable and 1 to enable
* @returns if 10Gbe is enabled
*/
bool enableTenGigabitEthernet(int value = -1);
/**
* Set/get receiver fifo depth
* @param i is -1 to get, any other value to set the fifo deph
* @returns the receiver fifo depth
*/
int setReceiverFifoDepth(int n_frames = -1);
bool getReceiverSilentMode();
void setReceiverSilentMode(bool enable);
/**
* If data streaming in receiver is enabled,
* restream the stop dummy packet from receiver
* Used usually for Moench,
* in case it is lost in network due to high data rate
*/
void restreamStopFromReceiver();
/** /**
* Opens pattern file and sends pattern to CTB * Opens pattern file and sends pattern to CTB
@ -1660,9 +1260,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();
@ -1728,67 +1325,23 @@ class Module : public virtual slsDetectorDefs {
void sendToDetectorStop(int fnum) const; void sendToDetectorStop(int fnum) const;
/**
* Send function parameters to receiver
* @param fnum function enum
* @param args argument pointer
* @param args_size size of argument
* @param retval return pointers
* @param retval_size size of return value
*/
void sendToReceiver(int fnum, const void *args, size_t args_size,
void *retval, size_t retval_size);
void sendToReceiver(int fnum, const void *args, size_t args_size,
void *retval, size_t retval_size) const;
template <typename Arg, typename Ret>
void sendToReceiver(int fnum, const Arg &args, Ret &retval);
template <typename Arg, typename Ret>
void sendToReceiver(int fnum, const Arg &args, Ret &retval) const;
template <typename Arg>
void sendToReceiver(int fnum, const Arg &args, std::nullptr_t);
template <typename Arg>
void sendToReceiver(int fnum, const Arg &args, std::nullptr_t) const;
template <typename Ret>
void sendToReceiver(int fnum, std::nullptr_t, Ret &retval);
template <typename Ret>
void sendToReceiver(int fnum, std::nullptr_t, Ret &retval) const;
template <typename Ret>
Ret sendToReceiver(int fnum);
template <typename Ret>
Ret sendToReceiver(int fnum) const;
template <typename Ret, typename Arg>
Ret sendToReceiver(int fnum, const Arg &args);
template <typename Ret, typename Arg>
Ret sendToReceiver(int fnum, const Arg &args) const;
/** /**
* Get Detector Type from Shared Memory (opening shm without verifying size) * Get Detector Type from Shared Memory (opening shm without verifying size)
* @param multi_id multi detector Id * @param detector_id multi detector Id
* @param verify true to verify if shm size matches existing one * @param verify true to verify if shm size matches existing one
* @returns detector type * @returns detector type
*/ */
detectorType getDetectorTypeFromShm(int multi_id, bool verify = true); detectorType getDetectorTypeFromShm(int detector_id, bool verify = true);
/** /**
* Initialize shared memory * Initialize shared memory
* @param created true if shared memory must be created, else false to open * @param created true if shared memory must be created, else false to open
* @param type type of detector * @param type type of detector
* @param multi_id multi detector Id * @param detector_id multi detector Id
* @param verify true to verify if shm size matches existing one * @param verify true to verify if shm size matches existing one
* @returns true if the shared memory was created now * @returns true if the shared memory was created now
*/ */
void initSharedMemory(detectorType type, int multi_id, bool verify = true); void initSharedMemory(detectorType type, int detector_id, bool verify = true);
/** /**
* Initialize detector structure to defaults * Initialize detector structure to defaults
@ -1871,10 +1424,10 @@ class Module : public virtual slsDetectorDefs {
std::vector<std::string> getSettingsFileDacNames(); std::vector<std::string> getSettingsFileDacNames();
/** Module Id or position in the detectors list */ /** Module Id or position in the detectors list */
const int detId; const int moduleId;
/** Shared Memory object */ /** Shared Memory object */
mutable sls::SharedMemory<sharedSlsDetector> shm{0, 0}; mutable sls::SharedMemory<sharedModule> shm{0, 0};
}; };
}// sls }// sls

View File

@ -0,0 +1,918 @@
#include "Receiver.h"
#include "ClientSocket.h"
#include "ZmqSocket.h"
#include "FixedCapacityContainer.h"
#include "string_utils.h"
#include "versionAPI.h"
#include "ToString.h"
#include "container_utils.h"
namespace sls {
// create shm
Receiver::Receiver(int detector_id, int module_id, int interface_id,
int receiver_id, int tcp_port, std::string hostname,
int zmq_port) :
receiverId(receiver_id), interfaceId(interface_id), moduleId(module_id),
shm(detector_id, module_id, interface_id, receiver_id) {
createIndexString();
// ensure shared memory was not created before
if (shm.IsExisting()) {
LOG(logWARNING) << "This shared memory should have been deleted "
"before! " << shm.GetName() << ". Freeing it again";
shm.RemoveSharedMemory();
}
shm = SharedMemory<sharedReceiver>(detector_id, module_id, interface_id,
receiver_id);
shm.CreateSharedMemory();
// initalize receiver structure
shm()->shmversion = RECEIVER_SHMVERSION;
memset(shm()->hostname, 0, MAX_STR_LENGTH);
shm()->tcpPort = DEFAULT_RX_PORTNO + receiver_id;
shm()-> stoppedFlag = false;
shm()->zmqPort = DEFAULT_ZMQ_RX_PORTNO + receiver_id;
shm()->zmqIp = IpAddr{};
// copy port, hostname if given
if (tcp_port != 0) {
setTCPPort(tcp_port);
}
if (zmq_port != 0) {
shm()->zmqPort = zmq_port;
}
if (!hostname.empty()) {
setHostname(hostname);
}
}
// open shm
Receiver::Receiver(int detector_id, int module_id, int interface_id,
int receiver_id, bool verify) :
receiverId(receiver_id), interfaceId(interface_id), moduleId(module_id),
shm(detector_id, module_id, interface_id, receiver_id) {
createIndexString();
shm.OpenSharedMemory();
if (verify && shm()->shmversion != RECEIVER_SHMVERSION) {
std::ostringstream ss;
ss << "Receiver shared memory (" << detector_id << "-" << indexString
<< ":" << receiverId << ") version mismatch (expected 0x" << std::hex
<< RECEIVER_SHMVERSION << " but got 0x" << shm()->shmversion << ")"
<< std::dec << ". Clear Shared memory to continue.";
throw SharedMemoryError(ss.str());
}
}
Receiver::~Receiver() = default;
void Receiver::createIndexString() {
std::ostringstream oss;
oss << '(' << moduleId << (char)(interfaceId + 97) << "." << receiverId << ')';
indexString = oss.str();
}
/** Configuration */
void Receiver::freeSharedMemory() {
if (shm.IsExisting()) {
shm.RemoveSharedMemory();
}
}
std::string Receiver::getHostname() const {
return shm()->hostname;
}
void Receiver::setHostname(const std::string &hostname) {
if (hostname.empty()) {
throw RuntimeError("Invalid receiver hostname. Cannot be empty.");
}
sls::strcpy_safe(shm()->hostname, hostname.c_str());
checkVersionCompatibility();
}
int Receiver::getTCPPort() const {
return shm()->tcpPort;
}
void Receiver::setTCPPort(const int port) {
LOG(logDEBUG1) << "Setting reciever port to " << port;
if (port >= 0 && port != shm()->tcpPort) {
if (strlen(shm()->hostname) != 0) {
int retval = -1;
sendToReceiver(F_SET_RECEIVER_PORT, port, retval);
shm()->tcpPort = retval;
LOG(logDEBUG1) << "Receiver port: " << retval;
} else {
shm()->tcpPort = port;
}
}
}
void Receiver::checkVersionCompatibility() {
int64_t arg = APIRECEIVER;
LOG(logDEBUG1)
<< "Checking version compatibility with receiver with value "
<< std::hex << arg << std::dec;
sendToReceiver(F_RECEIVER_CHECK_VERSION, arg, nullptr);
}
sls::MacAddr Receiver::configure(slsDetectorDefs::rxParameters arg) {
// hostname
memset(arg.hostname, 0, sizeof(arg.hostname));
strcpy_safe(arg.hostname, shm()->hostname);
// interface id
arg.interfaceId = interfaceId;
// zmqip
{
sls::IpAddr ip;
// Hostname could be ip try to decode otherwise look up the hostname
ip = sls::IpAddr{shm()->hostname};
if (ip == 0) {
ip = HostnameToIp(shm()->hostname);
}
LOG(logINFO) << "Setting default receiver " << indexString
<< " streaming zmq ip to " << ip;
// if client zmqip is empty, update it
if (shm()->zmqIp == 0) {
shm()->zmqIp = ip;
}
memcpy(&arg.zmq_ip, &ip, sizeof(ip));
}
if (arg.detType == EIGER) {
arg.udpInterfaces = 2;
}
LOG(logDEBUG)
<< "detType:" << arg.detType << std::endl
<< "detectorSize.x:" << arg.detectorSize.x << std::endl
<< "detectorSize.y:" << arg.detectorSize.y << std::endl
<< "moduleId:" << arg.moduleId << std::endl
<< "hostname:" << arg.hostname << std::endl
<< "interfaceId: " << arg.interfaceId << std::endl
<< "zmq ip:" << arg.zmq_ip << std::endl
<< "udpInterfaces:" << arg.udpInterfaces << std::endl
<< "udp_dstport:" << arg.udp_dstport << std::endl
<< "udp_dstip:" << sls::IpAddr(arg.udp_dstip) << std::endl
<< "udp_dstmac:" << sls::MacAddr(arg.udp_dstmac) << std::endl
<< "udp_dstport2:" << arg.udp_dstport2 << std::endl
<< "udp_dstip2:" << sls::IpAddr(arg.udp_dstip2) << std::endl
<< "udp_dstmac2:" << sls::MacAddr(arg.udp_dstmac2) << std::endl
<< "frames:" << arg.frames << std::endl
<< "triggers:" << arg.triggers << std::endl
<< "bursts:" << arg.bursts << std::endl
<< "analogSamples:" << arg.analogSamples << std::endl
<< "digitalSamples:" << arg.digitalSamples << std::endl
<< "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;
sls::MacAddr mac;
{
sls::MacAddr retval;
sendToReceiver(F_SETUP_RECEIVER, arg, retval);
// detector does not have customized udp mac
if (arg.udp_dstmac == 0) {
mac = retval;
}
}
if (arg.detType == MOENCH) {
setAdditionalJsonParameter("adcmask_1g", std::to_string(arg.adcMask));
setAdditionalJsonParameter("adcmask_10g", std::to_string(arg.adc10gMask));
}
LOG(logINFOBLUE) << "reciever " << indexString << " configured!";
return mac;
}
std::string Receiver::printConfiguration() {
std::ostringstream oss;
oss << std::endl << std::endl
<< "Receiver " << indexString << std::endl
<< "Hostname : " << shm()->hostname << std::endl
<< "Tcp port : " << shm()->tcpPort << std::endl;
/*
os << "\nReceiver UDP IP:\t"
<< getDestinationUDPIP() << "\nReceiver UDP MAC:\t" << getDestinationUDPMAC();
if (shm()->myDetectorType == JUNGFRAU) {
os << "\nDetector UDP IP2:\t" << getSourceUDPIP2()
<< "\nDetector UDP MAC2:\t" << getSourceUDPMAC2()
<< "\nReceiver UDP IP2:\t" << getDestinationUDPIP2()
<< "\nReceiver UDP MAC2:\t" << getDestinationUDPMAC2();
}
os << "\nReceiver UDP Port:\t" << getDestinationUDPPort();
if (shm()->myDetectorType == JUNGFRAU || shm()->myDetectorType == EIGER) {
os << "\nReceiver UDP Port2:\t" << getDestinationUDPPort2();
}
*/
oss << "\n";
return oss.str();
}
int64_t Receiver::getSoftwareVersion() const {
LOG(logDEBUG1) << "Getting receiver software version";
return sendToReceiver<int64_t>(F_GET_RECEIVER_VERSION);
}
/** Acquisition */
void Receiver::start() {
LOG(logDEBUG1) << "Starting Receiver";
shm()->stoppedFlag = false;
sendToReceiver(F_START_RECEIVER, nullptr, nullptr);
}
void Receiver::stop() {
LOG(logDEBUG1) << "Stopping Receiver";
int arg = static_cast<int>(shm()->stoppedFlag);
sendToReceiver(F_STOP_RECEIVER, arg, nullptr);
}
slsDetectorDefs::runStatus Receiver::getStatus() const {
runStatus retval = ERROR;
LOG(logDEBUG1) << "Getting Receiver Status";
sendToReceiver(F_GET_RECEIVER_STATUS, nullptr, retval);
LOG(logDEBUG1) << "Receiver Status: " << ToString(retval);
return retval;
}
int Receiver::getProgress() const {
int retval = -1;
sendToReceiver(F_GET_RECEIVER_PROGRESS, nullptr, retval);
LOG(logDEBUG1) << "Current Progress of Receiver: " << retval;
return retval;
}
void Receiver::setStoppedFlag() {
shm()->stoppedFlag = true;
}
void Receiver::restreamStop() {
LOG(logDEBUG1) << "Restream stop dummy from Receiver via zmq";
sendToReceiver(F_RESTREAM_STOP_FROM_RECEIVER, nullptr, nullptr);
}
uint64_t Receiver::getFramesCaught() const {
return sendToReceiver<uint64_t>(F_GET_RECEIVER_FRAMES_CAUGHT);
}
uint64_t Receiver::getNumMissingPackets() const {
return sendToReceiver<uint64_t>(F_GET_NUM_MISSING_PACKETS);
}
uint64_t Receiver::getCurrentFrameIndex() const {
return sendToReceiver<uint64_t>(F_GET_RECEIVER_FRAME_INDEX);
}
/** Network Configuration (Detector<->Receiver) */
sls::MacAddr Receiver::setUDPIP(const IpAddr ip) {
LOG(logDEBUG1) << "Setting udp ip to receier: " << ip;
if (ip == 0) {
throw RuntimeError("Invalid destination udp ip address");
}
sls::MacAddr retval(0LU);
sendToReceiver(F_SET_RECEIVER_UDP_IP, ip, retval);
return retval;
}
void Receiver::setUDPPort(const int port) {
LOG(logDEBUG1) << "Setting udp port to receiver: " << port;
sendToReceiver(F_SET_RECEIVER_UDP_PORT, port, nullptr);
}
int64_t Receiver::getUDPSocketBufferSize() const {
return sendToReceiver<int64_t>(F_GET_RECEIVER_UDP_SOCK_BUF_SIZE);
}
void Receiver::setUDPSocketBufferSize(int64_t value) {
LOG(logDEBUG1) << "Sending UDP Socket Buffer size to receiver: "
<< value;
sendToReceiver(F_SET_RECEIVER_UDP_SOCK_BUF_SIZE, value, nullptr);
}
int64_t Receiver::getRealUDPSocketBufferSize() const {
return sendToReceiver<int64_t>(F_GET_RECEIVER_REAL_UDP_SOCK_BUF_SIZE);
}
/** ZMQ Streaming Parameters (Receiver<->Client) */
bool Receiver::getZmq() const {
return sendToReceiver<int>(F_GET_RECEIVER_STREAMING);
}
void Receiver::setZmq(const bool enable) {
int arg = static_cast<int>(enable);
sendToReceiver(F_SET_RECEIVER_STREAMING, arg, nullptr);
}
int Receiver::getZmqFrequency() const {
return sendToReceiver<int>(F_GET_RECEIVER_STREAMING_FREQUENCY);
}
void Receiver::setZmqFrequency(const int freq) {
if (freq < 0) {
throw RuntimeError("Invalid streaming frequency " + std::to_string(freq));
}
sendToReceiver(F_SET_RECEIVER_STREAMING_FREQUENCY, freq, nullptr);
}
int Receiver::getZmqTimer() const {
return sendToReceiver<int>(F_GET_RECEIVER_STREAMING_TIMER);
}
void Receiver::setZmqTimer(const int time_in_ms) {
sendToReceiver(F_SET_RECEIVER_STREAMING_TIMER, time_in_ms, nullptr);
}
int Receiver::getZmqPort() const {
return sendToReceiver<int>(F_GET_RECEIVER_STREAMING_PORT);
}
void Receiver::setZmqPort(int port) {
sendToReceiver(F_SET_RECEIVER_STREAMING_PORT, port, nullptr);
}
sls::IpAddr Receiver::getZmqIP() const {
return sendToReceiver<sls::IpAddr>(F_GET_RECEIVER_STREAMING_SRC_IP);
}
void Receiver::setZmqIP(const sls::IpAddr ip) {
if (ip == 0) {
throw RuntimeError("Invalid receiver zmq ip address");
}
// if client zmqip is empty, update it
if (shm()->zmqIp == 0) {
shm()->zmqIp = ip;
}
sendToReceiver(F_SET_RECEIVER_STREAMING_SRC_IP, ip, nullptr);
}
int Receiver::getClientZmqPort() const {
return shm()->zmqPort;
}
void Receiver::setClientZmqPort(const int port) {
shm()->zmqPort = port;
}
sls::IpAddr Receiver::getClientZmqIP() const {
return shm()->zmqIp;
}
void Receiver::setClientZmqIP(const sls::IpAddr ip) {
LOG(logDEBUG1) << "Setting client zmq ip to " << ip;
if (ip == 0) {
throw RuntimeError("Invalid client zmq ip address");
}
shm()->zmqIp = ip;
}
bool Receiver::getClientZmq() const {
return (zmqSocket != nullptr);
}
void Receiver::setClientZmq(const bool enable) {
// destroy
if (!enable) {
if (zmqSocket != nullptr) {
zmqSocket.reset();
}
}
// create
else {
if (zmqSocket == nullptr) {
try {
zmqSocket = sls::make_unique<ZmqSocket>(
shm()->zmqIp.str().c_str(), shm()->zmqPort);
LOG(logINFO) << "Zmq Client[" << indexString << "] at "
<< zmqSocket->GetZmqServerAddress();
} catch(...) {
throw RuntimeError(
"Could not create Zmq socket [" + indexString
+ " on port " + std::to_string(shm()->zmqPort));
}
}
}
}
ZmqSocket* Receiver::getZmqSocket() {
return zmqSocket.get();
}
/** Receiver Parameters */
bool Receiver::getLock() const {
return sendToReceiver<int>(F_GET_LOCK_RECEIVER);
}
void Receiver::setLock(const bool lock) {
LOG(logDEBUG1) << "Setting receiver server lock to " << lock;
sendToReceiver(F_SET_LOCK_RECEIVER, lock, nullptr);
}
sls::IpAddr Receiver::getLastClientIP() const {
return sendToReceiver<sls::IpAddr>(F_GET_LAST_RECEIVER_CLIENT_IP);
}
void Receiver::exitServer() {
LOG(logDEBUG1) << "Sending exit command to receiver server";
sendToReceiver(F_EXIT_RECEIVER, nullptr, nullptr);
}
bool Receiver::getDeactivatedPaddingMode() const {
return sendToReceiver<int>(F_GET_RECEIVER_DEACTIVATED_PADDING);
}
void Receiver::setDeactivatedPaddingMode(const bool padding) {
int arg = static_cast<int>(padding);
sendToReceiver(F_SET_RECEIVER_DEACTIVATED_PADDING, arg, nullptr);
}
bool Receiver::getFlippedDataX() const {
int arg = -1;
return sendToReceiver<int>(F_GET_FLIPPED_DATA_RECEIVER, arg);
}
void Receiver::setFlippedDataX(const bool value) {
int arg = static_cast<int>(value);
LOG(logDEBUG1) << "Setting flipped data across x axis with value: "
<< value;
sendToReceiver(F_SET_FLIPPED_DATA_RECEIVER, arg, nullptr);
}
slsDetectorDefs::frameDiscardPolicy Receiver::getFramesDiscardPolicy() const {
return static_cast<frameDiscardPolicy>(
sendToReceiver<int>(F_GET_RECEIVER_DISCARD_POLICY));
}
void Receiver::setFramesDiscardPolicy(const frameDiscardPolicy f) {
int arg = static_cast<int>(f);
sendToReceiver(F_SET_RECEIVER_DISCARD_POLICY, arg, nullptr);
}
bool Receiver::getPartialFramesPadding() const {
return sendToReceiver<int>(F_GET_RECEIVER_PADDING);
}
void Receiver::setPartialFramesPadding(const bool padding) {
int arg = static_cast<int>(padding);
sendToReceiver(F_SET_RECEIVER_PADDING, arg, nullptr);
}
int Receiver::getFifoDepth() const {
return sendToReceiver<int>(F_GET_RECEIVER_FIFO_DEPTH);
}
void Receiver::setFifoDepth(const int value) {
sendToReceiver(F_SET_RECEIVER_FIFO_DEPTH, value, nullptr);
}
bool Receiver::getSilentMode() const {
return sendToReceiver<int>(F_GET_RECEIVER_SILENT_MODE);
}
void Receiver::setSilentMode(const bool enable) {
int arg = static_cast<int>(enable);
sendToReceiver(F_SET_RECEIVER_SILENT_MODE, arg, nullptr);
}
/** File */
std::string Receiver::getFilePath() const {
char retvals[MAX_STR_LENGTH]{};
sendToReceiver(F_GET_RECEIVER_FILE_PATH, nullptr, retvals);
return std::string(retvals);
}
void Receiver::setFilePath(const std::string &path) {
if (path.empty()) {
throw RuntimeError("Cannot set empty file path");
}
char args[MAX_STR_LENGTH]{};
sls::strcpy_safe(args, path.c_str());
sendToReceiver(F_SET_RECEIVER_FILE_PATH, args, nullptr);
}
std::string Receiver::getFileName() const {
char retvals[MAX_STR_LENGTH]{};
sendToReceiver(F_GET_RECEIVER_FILE_NAME, nullptr, retvals);
return std::string(retvals);
}
void Receiver::setFileName(const std::string &fname) {
if (fname.empty()) {
throw RuntimeError("Cannot set empty file name prefix");
}
char args[MAX_STR_LENGTH]{};
sls::strcpy_safe(args, fname.c_str());
sendToReceiver(F_SET_RECEIVER_FILE_NAME, args, nullptr);
}
int64_t Receiver::getFileIndex() const {
return sendToReceiver<int64_t>(F_GET_RECEIVER_FILE_INDEX);
}
void Receiver::setFileIndex(const int64_t file_index) {
sendToReceiver(F_SET_RECEIVER_FILE_INDEX, file_index, nullptr);
}
void Receiver::incrementFileIndex() {
sendToReceiver(F_INCREMENT_FILE_INDEX, nullptr, nullptr);
}
slsDetectorDefs::fileFormat Receiver::getFileFormat() const {
return static_cast<fileFormat>(
sendToReceiver<int>(F_GET_RECEIVER_FILE_FORMAT));
}
void Receiver::setFileFormat(const fileFormat f) {
int arg = static_cast<int>(f);
sendToReceiver(F_SET_RECEIVER_FILE_FORMAT, arg, nullptr);
}
int Receiver::getFramesPerFile() const {
return sendToReceiver<int>(F_GET_RECEIVER_FRAMES_PER_FILE);
}
void Receiver::setFramesPerFile(const int n_frames) {
sendToReceiver(F_SET_RECEIVER_FRAMES_PER_FILE, n_frames, nullptr);
}
bool Receiver::getFileWrite() const {
return sendToReceiver<int>(F_GET_RECEIVER_FILE_WRITE);
}
void Receiver::setFileWrite(const bool value) {
int arg = static_cast<int>(value);
sendToReceiver(F_SET_RECEIVER_FILE_WRITE, arg, nullptr);
}
bool Receiver::getMasterFileWrite() const {
return sendToReceiver<int>(F_GET_RECEIVER_MASTER_FILE_WRITE);
}
void Receiver::setMasterFileWrite(const bool value) {
int arg = static_cast<int>(value);
sendToReceiver(F_SET_RECEIVER_MASTER_FILE_WRITE, arg, nullptr);
}
bool Receiver::getFileOverWrite() const {
return sendToReceiver<int>(F_GET_RECEIVER_OVERWRITE);
}
void Receiver::setFileOverWrite(const bool value) {
int arg = static_cast<int>(value);
sendToReceiver(F_SET_RECEIVER_OVERWRITE, arg, nullptr);
}
/** Detector Parameters */
void Receiver::setNumberOfFrames(const int64_t value) {
LOG(logDEBUG1) << "Sending number of frames to Receiver: " << value;
sendToReceiver(F_RECEIVER_SET_NUM_FRAMES, value, nullptr);
}
void Receiver::setNumberOfTriggers(const int64_t value) {
LOG(logDEBUG1) << "Sending number of triggers to Receiver: " << value;
sendToReceiver(F_SET_RECEIVER_NUM_TRIGGERS, value, nullptr);
}
void Receiver::setNumberOfBursts(const int64_t value) {
LOG(logDEBUG1) << "Sending number of bursts to Receiver: " << value;
sendToReceiver(F_SET_RECEIVER_NUM_BURSTS, value, nullptr);
}
void Receiver::setNumberOfAnalogSamples(const int value) {
LOG(logDEBUG1) << "Sending number of analog samples to Receiver: " << value;
sendToReceiver(F_RECEIVER_SET_NUM_ANALOG_SAMPLES, value, nullptr);
}
void Receiver::setNumberOfDigitalSamples(const int value) {
LOG(logDEBUG1) << "Sending number of digital samples to Receiver: " << value;
sendToReceiver(F_RECEIVER_SET_NUM_DIGITAL_SAMPLES, value, nullptr);
}
void Receiver::setExptime(const int64_t value) {
LOG(logDEBUG1) << "Sending exptime to Receiver: " << value;
sendToReceiver(F_RECEIVER_SET_EXPTIME, value, nullptr);
}
void Receiver::setPeriod(const int64_t value) {
LOG(logDEBUG1) << "Sending period to Receiver: " << value;
sendToReceiver(F_RECEIVER_SET_PERIOD, value, nullptr);
}
void Receiver::setSubExptime(const int64_t value) {
LOG(logDEBUG1) << "Sending sub exptime to Receiver: " << value;
sendToReceiver(F_RECEIVER_SET_SUB_EXPTIME, value, nullptr);
}
void Receiver::setSubDeadTime(const int64_t value) {
LOG(logDEBUG1) << "Sending sub deadtime to Receiver: " << value;
sendToReceiver(F_RECEIVER_SET_SUB_DEADTIME, value, nullptr);
}
void Receiver::setTimingMode(const timingMode value) {
LOG(logDEBUG1) << "Sending timing mode to Receiver: " << value;
sendToReceiver(F_SET_RECEIVER_TIMING_MODE, value, nullptr);
}
void Receiver::setDynamicRange(const int n) {
int retval = -1;
LOG(logDEBUG1) << "Sending dynamic range to receiver: " << n;
sendToReceiver(F_SET_RECEIVER_DYNAMIC_RANGE, n, retval);
}
void Receiver::setReadoutMode(const slsDetectorDefs::readoutMode mode) {
sendToReceiver(F_RECEIVER_SET_READOUT_MODE, mode, nullptr);
}
void Receiver::setQuad(const bool enable) {
int value = enable ? 1 : 0;
LOG(logDEBUG1) << "Setting Quad type to " << value << " in Receiver";
sendToReceiver(F_SET_RECEIVER_QUAD, value, nullptr);
}
void Receiver::setReadNLines(const int value) {
LOG(logDEBUG1) << "Setting read n lines to " << value
<< " in Receiver";
sendToReceiver(F_SET_RECEIVER_READ_N_LINES, value, nullptr);
}
void Receiver::setADCEnableMask(const uint32_t mask) {
sendToReceiver(F_RECEIVER_SET_ADC_MASK, mask, nullptr);
}
void Receiver::setTenGigaADCEnableMask(const uint32_t mask) {
sendToReceiver(F_RECEIVER_SET_ADC_MASK_10G, mask, nullptr);
}
void Receiver::setBurstMode(const slsDetectorDefs::burstMode value) {
LOG(logDEBUG1) << "Sending burst mode to Receiver: " << value;
sendToReceiver(F_SET_RECEIVER_BURST_MODE, value, nullptr);
}
void Receiver::setROI(const slsDetectorDefs::ROI arg) {
std::array<int, 2> args{arg.xmin, arg.xmax};
LOG(logDEBUG1) << "Sending ROI to receiver";
sendToReceiver(F_RECEIVER_SET_ROI, args, nullptr);
}
void Receiver::clearROI() {
LOG(logDEBUG1) << "Clearing ROI";
slsDetectorDefs::ROI arg;
arg.xmin = -1;
arg.xmax = -1;
setROI(arg);
}
std::vector<int> Receiver::getDbitList() const {
sls::FixedCapacityContainer<int, MAX_RX_DBIT> retval;
sendToReceiver(F_GET_RECEIVER_DBIT_LIST, nullptr, retval);
return retval;
}
void Receiver::setDbitList(const std::vector<int>& list) {
LOG(logDEBUG1) << "Setting Receiver Dbit List";
if (list.size() > 64) {
throw sls::RuntimeError("Dbit list size cannot be greater than 64\n");
}
for (auto &it : list) {
if (it < 0 || it > 63) {
throw sls::RuntimeError(
"Dbit list value must be between 0 and 63\n");
}
}
sls::FixedCapacityContainer<int, MAX_RX_DBIT> arg = list;
sendToReceiver(F_SET_RECEIVER_DBIT_LIST, arg, nullptr);
}
int Receiver::getDbitOffset() const {
return sendToReceiver<int>(F_GET_RECEIVER_DBIT_OFFSET);
}
void Receiver::setDbitOffset(const int value) {
sendToReceiver(F_SET_RECEIVER_DBIT_OFFSET, value, nullptr);
}
void Receiver::setActivate(const bool enable) {
int arg = static_cast<int>(enable);
sendToReceiver(F_RECEIVER_ACTIVATE, arg, nullptr);
}
void Receiver::setTenGiga(const bool enable) {
int arg = static_cast<int>(enable);
sendToReceiver(F_ENABLE_RECEIVER_TEN_GIGA, arg, nullptr);
}
void Receiver::setCounterMask(const uint32_t mask) {
int ncounters = __builtin_popcount(mask);
LOG(logDEBUG1) << "Sending Reciver #counters: " << ncounters;
sendToReceiver(F_RECEIVER_SET_NUM_COUNTERS, ncounters, nullptr);
}
/** Json */
std::map<std::string, std::string> Receiver::getAdditionalJsonHeader() const {
int fnum = F_GET_ADDITIONAL_JSON_HEADER;
int ret = FAIL;
int size = 0;
auto client = ReceiverSocket(shm()->hostname, shm()->tcpPort);
client.Send(&fnum, sizeof(fnum));
client.Receive(&ret, sizeof(ret));
if (ret == FAIL) {
char mess[MAX_STR_LENGTH]{};
client.Receive(mess, MAX_STR_LENGTH);
throw RuntimeError("Receiver " + std::to_string(moduleId) +
" returned error: " + std::string(mess));
} else {
client.Receive(&size, sizeof(size));
std::map<std::string, std::string> retval;
if (size > 0) {
char retvals[size * 2][SHORT_STR_LENGTH];
memset(retvals, 0, sizeof(retvals));
client.Receive(retvals, sizeof(retvals));
for (int i = 0; i < size; ++i) {
retval[retvals[2 * i]] = retvals[2 * i + 1];
}
}
LOG(logDEBUG) << "Getting additional json header " << ToString(retval);
return retval;
}
}
void Receiver::setAdditionalJsonHeader(const std::map<std::string, std::string> &jsonHeader) {
for (auto &it : jsonHeader) {
if (it.first.empty() || it.first.length() > SHORT_STR_LENGTH ||
it.second.length() > SHORT_STR_LENGTH ) {
throw RuntimeError(it.first + " or " + it.second + " pair has invalid size. "
"Key cannot be empty. Both can have max 20 characters");
}
}
const int size = jsonHeader.size();
int fnum = F_SET_ADDITIONAL_JSON_HEADER;
int ret = FAIL;
LOG(logDEBUG) << "Sending to receiver additional json header " << ToString(jsonHeader);
auto client = ReceiverSocket(shm()->hostname, shm()->tcpPort);
client.Send(&fnum, sizeof(fnum));
client.Send(&size, sizeof(size));
if (size > 0) {
char args[size * 2][SHORT_STR_LENGTH];
memset(args, 0, sizeof(args));
int iarg = 0;
for (auto &it : jsonHeader) {
sls::strcpy_safe(args[iarg], it.first.c_str());
sls::strcpy_safe(args[iarg + 1], it.second.c_str());
iarg += 2;
}
client.Send(args, sizeof(args));
}
client.Receive(&ret, sizeof(ret));
if (ret == FAIL) {
char mess[MAX_STR_LENGTH]{};
client.Receive(mess, MAX_STR_LENGTH);
throw RuntimeError("Receiver " + std::to_string(moduleId) +
" returned error: " + std::string(mess));
}
}
std::string Receiver::getAdditionalJsonParameter(const std::string &key) const {
char arg[SHORT_STR_LENGTH]{};
sls::strcpy_safe(arg, key.c_str());
char retval[SHORT_STR_LENGTH]{};
sendToReceiver(F_GET_ADDITIONAL_JSON_PARAMETER, arg, retval);
return retval;
}
void Receiver::setAdditionalJsonParameter(const std::string &key, const std::string &value) {
if (key.empty() || key.length() > SHORT_STR_LENGTH ||
value.length() > SHORT_STR_LENGTH ) {
throw RuntimeError(key + " or " + value + " pair has invalid size. "
"Key cannot be empty. Both can have max 2 characters");
}
char args[2][SHORT_STR_LENGTH]{};
sls::strcpy_safe(args[0], key.c_str());
sls::strcpy_safe(args[1], value.c_str());
sendToReceiver(F_SET_ADDITIONAL_JSON_PARAMETER, args, nullptr);
}
void Receiver::sendToReceiver(int fnum, const void *args, size_t args_size,
void *retval, size_t retval_size) {
static_cast<const Receiver &>(*this).sendToReceiver(
fnum, args, args_size, retval, retval_size);
}
void Receiver::sendToReceiver(int fnum, const void *args, size_t args_size,
void *retval, size_t retval_size) const {
if (strlen(shm()->hostname) == 0) {
throw RuntimeError("Reciver not added");
}
auto receiver = ReceiverSocket(shm()->hostname, shm()->tcpPort);
receiver.sendCommandThenRead(fnum, args, args_size, retval, retval_size);
receiver.close();
}
template <typename Arg, typename Ret>
void Receiver::sendToReceiver(int fnum, const Arg &args, Ret &retval) {
sendToReceiver(fnum, &args, sizeof(args), &retval, sizeof(retval));
}
template <typename Arg, typename Ret>
void Receiver::sendToReceiver(int fnum, const Arg &args, Ret &retval) const {
sendToReceiver(fnum, &args, sizeof(args), &retval, sizeof(retval));
}
template <typename Arg>
void Receiver::sendToReceiver(int fnum, const Arg &args, std::nullptr_t) {
sendToReceiver(fnum, &args, sizeof(args), nullptr, 0);
}
template <typename Arg>
void Receiver::sendToReceiver(int fnum, const Arg &args,
std::nullptr_t) const {
sendToReceiver(fnum, &args, sizeof(args), nullptr, 0);
}
template <typename Ret>
void Receiver::sendToReceiver(int fnum, std::nullptr_t, Ret &retval) {
sendToReceiver(fnum, nullptr, 0, &retval, sizeof(retval));
}
template <typename Ret>
void Receiver::sendToReceiver(int fnum, std::nullptr_t, Ret &retval) const {
sendToReceiver(fnum, nullptr, 0, &retval, sizeof(retval));
}
template <typename Ret>
Ret Receiver::sendToReceiver(int fnum){
LOG(logDEBUG1) << "Sending: ["
<< getFunctionNameFromEnum(static_cast<slsDetectorDefs::detFuncs>(fnum))
<< ", nullptr, 0, " << typeid(Ret).name() << ", " << sizeof(Ret) << "]";
Ret retval{};
sendToReceiver(fnum, nullptr, 0, &retval, sizeof(retval));
LOG(logDEBUG1) << "Got back: " << retval;
return retval;
}
template <typename Ret>
Ret Receiver::sendToReceiver(int fnum) const{
LOG(logDEBUG1) << "Sending: ["
<< getFunctionNameFromEnum(static_cast<slsDetectorDefs::detFuncs>(fnum))
<< ", nullptr, 0, " << typeid(Ret).name() << ", " << sizeof(Ret) << "]";
Ret retval{};
sendToReceiver(fnum, nullptr, 0, &retval, sizeof(retval));
LOG(logDEBUG1) << "Got back: " << retval;
return retval;
}
template <typename Ret, typename Arg>
Ret Receiver::sendToReceiver(int fnum, const Arg &args){
LOG(logDEBUG1) << "Sending: ["
<< getFunctionNameFromEnum(static_cast<slsDetectorDefs::detFuncs>(fnum))
<< ", " << args << ", " << sizeof(args) << ", " << typeid(Ret).name()
<< ", " << sizeof(Ret) << "]";
Ret retval{};
sendToReceiver(fnum, &args, sizeof(args), &retval, sizeof(retval));
LOG(logDEBUG1) << "Got back: " << retval;
return retval;
}
template <typename Ret, typename Arg>
Ret Receiver::sendToReceiver(int fnum, const Arg &args) const{
LOG(logDEBUG1) << "Sending: ["
<< getFunctionNameFromEnum(static_cast<slsDetectorDefs::detFuncs>(fnum))
<< ", " << args << ", " << sizeof(args) << ", " << typeid(Ret).name()
<< ", " << sizeof(Ret) << "]";
Ret retval{};
sendToReceiver(fnum, &args, sizeof(args), &retval, sizeof(retval));
LOG(logDEBUG1) << "Got back: " << retval;
return retval;
}
} // namespace sls

View File

@ -0,0 +1,258 @@
#pragma once
#include "SharedMemory.h"
#include "logger.h"
#include "sls_detector_defs.h"
#include "network_utils.h"
#include <map>
#include <memory>
#define RECEIVER_SHMVERSION 0x200421
class ZmqSocket;
namespace sls {
struct sharedReceiver {
/* FIXED PATTERN FOR STATIC FUNCTIONS. DO NOT CHANGE, ONLY APPEND ------*/
int shmversion;
char hostname[MAX_STR_LENGTH];
int tcpPort;
/** END OF FIXED PATTERN -----------------------------------------------*/
int stoppedFlag;
int zmqPort;
sls::IpAddr zmqIp;
};
class Receiver : public virtual slsDetectorDefs {
public:
static size_t getNumReceivers();
// create shm
explicit Receiver(int detector_id, int module_id, int interface_id,
int receiver_id, int tcp_port = 0, std::string hostname = "",
int zmq_port = 0);
// open shm
explicit Receiver(int detector_id, int module_id, int interface_id,
int receiver_id, bool verify);
virtual ~Receiver();
void createIndexString();
/**************************************************
* *
* Configuration *
* *
* ************************************************/
/**
* Free shared memory and delete shared memory structure
* occupied by the sharedReceiver structure
* Is only safe to call if one deletes the Receiver object afterward
* and frees multi shared memory/updates
* thisMultiDetector->numberOfReceivers
*/
void freeSharedMemory();
std::string getHostname() const;
void setHostname(const std::string &hostname);
sls::MacAddr configure(slsDetectorDefs::rxParameters arg);
int getTCPPort() const;
void setTCPPort(const int port);
std::string printConfiguration();
int64_t getSoftwareVersion() const;
/**************************************************
* *
* Acquisition *
* *
* ************************************************/
void start();
void stop();
slsDetectorDefs::runStatus getStatus() const;
int getProgress() const;
void setStoppedFlag();
void restreamStop();
uint64_t getFramesCaught() const;
uint64_t getNumMissingPackets() const;
uint64_t getCurrentFrameIndex() const;
/**************************************************
* *
* Network Configuration (Detector<->Receiver) *
* *
* ************************************************/
sls::MacAddr setUDPIP(const sls::IpAddr ip);
void setUDPPort(const int udpport);
int64_t getUDPSocketBufferSize() const;
void setUDPSocketBufferSize(int64_t value);
int64_t getRealUDPSocketBufferSize() const;
/**************************************************
* *
* ZMQ Streaming Parameters (Receiver<->Client)*
* *
* ************************************************/
bool getZmq() const;
void setZmq(const bool enable);
int getZmqFrequency() const;
/** Freq = 0 for a timer, else frequency */
void setZmqFrequency(const int freq);
int getZmqTimer() const;
void setZmqTimer(const int time_in_ms = 200);
int getZmqPort() const;
void setZmqPort(int port);
sls::IpAddr getZmqIP() const;
void setZmqIP(const sls::IpAddr ip);
int getClientZmqPort() const;
void setClientZmqPort(const int port);
sls::IpAddr getClientZmqIP() const;
void setClientZmqIP(const sls::IpAddr ip);
bool getClientZmq() const;
void setClientZmq(const bool enable);
ZmqSocket* getZmqSocket();
/**************************************************
* *
* Receiver Parameters *
* *
* ************************************************/
bool getLock() const;
void setLock(const bool lock);
sls::IpAddr getLastClientIP() const;
void exitServer();
bool getDeactivatedPaddingMode() const;
void setDeactivatedPaddingMode(const bool padding);
bool getFlippedDataX() const;
void setFlippedDataX(const bool value);
frameDiscardPolicy getFramesDiscardPolicy() const;
void setFramesDiscardPolicy(const frameDiscardPolicy f);
bool getPartialFramesPadding() const;
void setPartialFramesPadding(const bool padding);
int getFifoDepth() const;
void setFifoDepth(const int value);
bool getSilentMode() const;
void setSilentMode(const bool value);
/**************************************************
* *
* File *
* *
* ************************************************/
std::string getFilePath() const;
void setFilePath(const std::string &path);
std::string getFileName() const;
void setFileName(const std::string &fname);
int64_t getFileIndex() const;
void setFileIndex(const int64_t file_index);
void incrementFileIndex();
fileFormat getFileFormat() const;
void setFileFormat(const fileFormat f);
int getFramesPerFile() const;
/** 0 will set frames per file to unlimited */
void setFramesPerFile(const int n_frames);
bool getFileWrite() const;
void setFileWrite(const bool value);
bool getMasterFileWrite() const;
void setMasterFileWrite(const bool value);
bool getFileOverWrite() const;
void setFileOverWrite(const bool value);
/**************************************************
* *
* Detector Parameters *
* *
* ************************************************/
void setNumberOfFrames(const int64_t value);
void setNumberOfTriggers(const int64_t value);
void setNumberOfBursts(const int64_t value);
void setNumberOfAnalogSamples(const int value);
void setNumberOfDigitalSamples(const int value);
void setExptime(const int64_t value);
void setPeriod(const int64_t value);
void setSubExptime(const int64_t value);
void setSubDeadTime(const int64_t value);
void setTimingMode(const timingMode value);
void setDynamicRange(const int n);
void setReadoutMode(const readoutMode mode);
void setQuad(const bool enable);
void setReadNLines(const int value);
void setADCEnableMask(const uint32_t mask);
void setTenGigaADCEnableMask(const uint32_t mask);
void setBurstMode(const burstMode value);
void setROI(const slsDetectorDefs::ROI arg);
void clearROI();
std::vector<int> getDbitList() const;
/** digital data bits enable (CTB only) */
void setDbitList(const std::vector<int>& list);
int getDbitOffset() const;
/** Set digital data offset in bytes (CTB only) */
void setDbitOffset(const int value);
void setActivate(const bool enable);
void setTenGiga(const bool enable);
void setCounterMask(const uint32_t mask);
/**************************************************
* *
* Json *
* *
* ************************************************/
std::map<std::string, std::string> getAdditionalJsonHeader() const;
/** empty vector deletes entire additional json header */
void setAdditionalJsonHeader(const std::map<std::string, std::string> &jsonHeader);
std::string getAdditionalJsonParameter(const std::string &key) const;
/** Sets the value for the additional json header parameter key if found,
else append it. If value empty, then deletes parameter */
void setAdditionalJsonParameter(const std::string &key, const std::string &value);
private:
void sendToReceiver(int fnum, const void *args, size_t args_size,
void *retval, size_t retval_size);
void sendToReceiver(int fnum, const void *args, size_t args_size,
void *retval, size_t retval_size) const;
template <typename Arg, typename Ret>
void sendToReceiver(int fnum, const Arg &args, Ret &retval);
template <typename Arg, typename Ret>
void sendToReceiver(int fnum, const Arg &args, Ret &retval) const;
template <typename Arg>
void sendToReceiver(int fnum, const Arg &args, std::nullptr_t);
template <typename Arg>
void sendToReceiver(int fnum, const Arg &args, std::nullptr_t) const;
template <typename Ret>
void sendToReceiver(int fnum, std::nullptr_t, Ret &retval);
template <typename Ret>
void sendToReceiver(int fnum, std::nullptr_t, Ret &retval) const;
template <typename Ret>
Ret sendToReceiver(int fnum);
template <typename Ret>
Ret sendToReceiver(int fnum) const;
template <typename Ret, typename Arg>
Ret sendToReceiver(int fnum, const Arg &args);
template <typename Ret, typename Arg>
Ret sendToReceiver(int fnum, const Arg &args) const;
void checkVersionCompatibility();
const int receiverId{0};
const int interfaceId{0};
const int moduleId{0};
std::string indexString;
mutable sls::SharedMemory<sharedReceiver> shm{0, 0, 0, 0};
std::unique_ptr<ZmqSocket> zmqSocket;
};
} // sls

View File

@ -23,7 +23,8 @@
#include <unistd.h> #include <unistd.h>
#define SHM_MULTI_PREFIX "/slsDetectorPackage_multi_" #define SHM_MULTI_PREFIX "/slsDetectorPackage_multi_"
#define SHM_SLS_PREFIX "_sls_" #define SHM_MODULE_PREFIX "_module_"
#define SHM_RECEIVER_PREFIX "_receiver_"
#define SHM_ENV_NAME "SLSDETNAME" #define SHM_ENV_NAME "SLSDETNAME"
#include <iostream> #include <iostream>
@ -39,10 +40,12 @@ class SharedMemory {
* Constructor * Constructor
* creates the single/multi detector shared memory name * creates the single/multi detector shared memory name
* @param multiId multi detector id * @param multiId multi detector id
* @param slsId sls detector id, -1 if a multi detector shared memory * @param moduleId module detectr id, -1 if a multi detector shared memory
* @param interfaceId 0 for primary interface, 1 for secondary
* @param receiverId receiver id, -1 if not a rxr shm, else round robin entry
*/ */
SharedMemory(int multiId, int slsId) { SharedMemory(int multiId, int moduleId, int interfaceId = 0, int receiverId = -1) {
name = ConstructSharedMemoryName(multiId, slsId); name = ConstructSharedMemoryName(multiId, moduleId, interfaceId, receiverId);
} }
/** /**
@ -184,7 +187,8 @@ class SharedMemory {
// silent exit if shm did not exist anyway // silent exit if shm did not exist anyway
if (errno == ENOENT) if (errno == ENOENT)
return; return;
std::string msg = "Free Shared Memory " + name + " Failed: " + strerror(errno); std::string msg = "Free Shared Memory " + name + " Failed: " +
strerror(errno);
LOG(logERROR) << msg; LOG(logERROR) << msg;
throw SharedMemoryError(msg); throw SharedMemoryError(msg);
} }
@ -215,10 +219,13 @@ class SharedMemory {
* Create Shared memory name * Create Shared memory name
* throws exception if name created is longer than required 255(manpages) * throws exception if name created is longer than required 255(manpages)
* @param multiId multi detector id * @param multiId multi detector id
* @param slsId sls detector id, -1 if a multi detector shared memory * @param moduleId module detector id, -1 if a multi detector shared memory
* @param interfaceId 0 for primary interface, 1 for secondary
* @param receiverId receiver id, -1 if not a rxr shm, else round robin entry
* @returns shared memory name * @returns shared memory name
*/ */
std::string ConstructSharedMemoryName(int multiId, int slsId) { std::string ConstructSharedMemoryName(int multiId, int moduleId,
int interfaceId = 0, int receiverId = -1) {
// using environment path // using environment path
std::string sEnvPath = ""; std::string sEnvPath = "";
@ -229,14 +236,22 @@ class SharedMemory {
} }
std::stringstream ss; std::stringstream ss;
if (slsId < 0) if (moduleId < 0 && receiverId < 0)
ss << SHM_MULTI_PREFIX << multiId << sEnvPath; ss << SHM_MULTI_PREFIX << multiId << sEnvPath;
else if (receiverId < 0)
ss << SHM_MULTI_PREFIX << multiId <<
SHM_MODULE_PREFIX << moduleId << sEnvPath;
else else
ss << SHM_MULTI_PREFIX << multiId << SHM_SLS_PREFIX << slsId << sEnvPath; ss << SHM_MULTI_PREFIX << multiId <<
SHM_MODULE_PREFIX << moduleId <<
SHM_RECEIVER_PREFIX << (char)(interfaceId + 97) << '_' << receiverId << sEnvPath;
std::string temp = ss.str(); std::string temp = ss.str();
if (temp.length() > NAME_MAX_LENGTH) { if (temp.length() > NAME_MAX_LENGTH) {
std::string msg = "Shared memory initialization failed. " + temp + " has " + std::to_string(temp.length()) + " characters. \n" + "Maximum is " + std::to_string(NAME_MAX_LENGTH) + ". Change the environment variable " + SHM_ENV_NAME; std::string msg = "Shared memory initialization failed. " +
temp + " has " + std::to_string(temp.length()) + " characters. \n" +
"Maximum is " + std::to_string(NAME_MAX_LENGTH) +
". Change the environment variable " + SHM_ENV_NAME;
LOG(logERROR) << msg; LOG(logERROR) << msg;
throw SharedMemoryError(msg); throw SharedMemoryError(msg);
} }
@ -250,9 +265,11 @@ class SharedMemory {
*/ */
T *MapSharedMemory() { T *MapSharedMemory() {
void *addr = mmap(nullptr, sizeof(T), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); void *addr = mmap(nullptr, sizeof(T), PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0);
if (addr == MAP_FAILED) { if (addr == MAP_FAILED) {
std::string msg = "Mapping shared memory " + name + " failed: " + strerror(errno); std::string msg = "Mapping shared memory " + name + " failed: " +
strerror(errno);
LOG(logERROR) << msg; LOG(logERROR) << msg;
close(fd); close(fd);
throw SharedMemoryError(msg); throw SharedMemoryError(msg);
@ -271,7 +288,8 @@ class SharedMemory {
struct stat sb; struct stat sb;
// could not fstat // could not fstat
if (fstat(fd, &sb) < 0) { if (fstat(fd, &sb) < 0) {
std::string msg = "Could not verify existing shared memory " + name + " size match " + "(could not fstat): " + strerror(errno); std::string msg = "Could not verify existing shared memory " +
name + " size match " + "(could not fstat): " + strerror(errno);
LOG(logERROR) << msg; LOG(logERROR) << msg;
close(fd); close(fd);
throw SharedMemoryError(msg); throw SharedMemoryError(msg);
@ -280,7 +298,9 @@ class SharedMemory {
//size does not match //size does not match
auto sz = static_cast<size_t>(sb.st_size); auto sz = static_cast<size_t>(sb.st_size);
if (sz != expectedSize) { if (sz != expectedSize) {
std::string msg = "Existing shared memory " + name + " size does not match" + "Expected " + std::to_string(expectedSize) + ", found " + std::to_string(sz); std::string msg = "Existing shared memory " + name +
" size does not match" + "Expected " +
std::to_string(expectedSize) + ", found " + std::to_string(sz);
LOG(logERROR) << msg; LOG(logERROR) << msg;
throw SharedMemoryError(msg); throw SharedMemoryError(msg);
return 1; return 1;

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

File diff suppressed because it is too large Load Diff

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,22 @@ 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 set_lock_server(sls::ServerInterface &socket);
int get_lock_server(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);
@ -90,15 +105,16 @@ class ClientInterface : private virtual slsDetectorDefs {
int get_overwrite(sls::ServerInterface &socket); int get_overwrite(sls::ServerInterface &socket);
int enable_tengiga(sls::ServerInterface &socket); int enable_tengiga(sls::ServerInterface &socket);
int set_fifo_depth(sls::ServerInterface &socket); int set_fifo_depth(sls::ServerInterface &socket);
int get_fifo_depth(sls::ServerInterface &socket);
int set_activate(sls::ServerInterface &socket); int set_activate(sls::ServerInterface &socket);
int set_streaming(sls::ServerInterface &socket); int set_streaming(sls::ServerInterface &socket);
int get_streaming(sls::ServerInterface &socket); int get_streaming(sls::ServerInterface &socket);
int set_streaming_timer(sls::ServerInterface &socket); int set_streaming_timer(sls::ServerInterface &socket);
int get_streaming_timer(sls::ServerInterface &socket);
int set_flipped_data(sls::ServerInterface &socket); int set_flipped_data(sls::ServerInterface &socket);
int get_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);
@ -109,6 +125,7 @@ class ClientInterface : private virtual slsDetectorDefs {
int set_additional_json_header(sls::ServerInterface &socket); int set_additional_json_header(sls::ServerInterface &socket);
int get_additional_json_header(sls::ServerInterface &socket); int get_additional_json_header(sls::ServerInterface &socket);
int set_udp_socket_buffer_size(sls::ServerInterface &socket); int set_udp_socket_buffer_size(sls::ServerInterface &socket);
int get_udp_socket_buffer_size(sls::ServerInterface &socket);
int get_real_udp_socket_buffer_size(sls::ServerInterface &socket); int get_real_udp_socket_buffer_size(sls::ServerInterface &socket);
int set_frames_per_file(sls::ServerInterface &socket); int set_frames_per_file(sls::ServerInterface &socket);
int get_frames_per_file(sls::ServerInterface &socket); int get_frames_per_file(sls::ServerInterface &socket);
@ -127,16 +144,16 @@ 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);
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_num_interfaces(sls::ServerInterface &socket); int set_num_interfaces(sls::ServerInterface &socket);
int set_adc_mask_10g(sls::ServerInterface &socket); int set_adc_mask_10g(sls::ServerInterface &socket);
int set_num_counters(sls::ServerInterface &socket); int set_num_counters(sls::ServerInterface &socket);
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 +164,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 +179,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,24 +17,18 @@ 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* nr, 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]; numRx[0] = nr[0];
numDet[1] = nd[1]; numRx[1] = nr[1];
LOG(logDEBUG) << "DataStreamer " << ind << " created"; LOG(logDEBUG) << "DataStreamer " << ind << " created";
} }
@ -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;
@ -97,9 +74,9 @@ void DataStreamer::SetGeneralData(GeneralData* g) {
generalData->Print(); generalData->Print();
} }
void DataStreamer::SetNumberofDetectors(int* nd) { void DataStreamer::SetReceiverShape(int* nr) {
numDet[0] = nd[0]; numRx[0] = nr[0];
numDet[1] = nd[1]; numRx[1] = nr[1];
} }
void DataStreamer::SetFlippedDataX(int fd) { void DataStreamer::SetFlippedDataX(int fd) {
@ -234,13 +211,14 @@ int DataStreamer::SendHeader(sls_receiver_header* rheader, uint32_t size, uint32
zHeader.dynamicRange = *dynamicRange; zHeader.dynamicRange = *dynamicRange;
zHeader.fileIndex = *fileIndex; zHeader.fileIndex = *fileIndex;
zHeader.ndetx = numDet[0]; zHeader.nSocketX = numRx[0];
zHeader.ndety = numDet[1]; zHeader.nSocketY = numRx[1];
zHeader.npixelsx = nx; zHeader.npixelsx = nx;
zHeader.npixelsy = ny; zHeader.npixelsy = ny;
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

@ -29,11 +29,12 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
* @param r roi * @param r roi
* @param fi pointer to file index * @param fi pointer to file index
* @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 receivers 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* nr, 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
@ -78,10 +60,10 @@ class DataStreamer : private virtual slsDetectorDefs, public ThreadObject {
void SetGeneralData(GeneralData* g); void SetGeneralData(GeneralData* g);
/** /**
* Set number of detectors * Set receiver shape
* @param number of detectors in both dimensions * @param number of receivers in both dimensions
*/ */
void SetNumberofDetectors(int* nd); void SetReceiverShape(int* nr);
/** /**
* Set Flipped data enable across x dimension * Set Flipped data enable across x dimension
@ -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,22 +167,25 @@ 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 Recievers in X and Y dimension */
int numDet[2]; int numRx[2];
/** Quad Enable */ /** Quad Enable */
bool* quadEnable; bool* quadEnable;
/** Total number of frames */
uint64_t* totalNumFrames;
}; };

View File

@ -64,9 +64,6 @@ public:
/** Default Fifo depth */ /** Default Fifo depth */
uint32_t defaultFifoDepth; uint32_t defaultFifoDepth;
/** Threads per receiver */
uint32_t threadsPerReceiver;
/** Size of a header packet */ /** Size of a header packet */
uint32_t headerPacketSize; uint32_t headerPacketSize;
@ -105,7 +102,6 @@ public:
maxFramesPerFile(0), maxFramesPerFile(0),
fifoBufferHeaderSize(0), fifoBufferHeaderSize(0),
defaultFifoDepth(0), defaultFifoDepth(0),
threadsPerReceiver(1),
headerPacketSize(0), headerPacketSize(0),
nPixelsXComplete(0), nPixelsXComplete(0),
nPixelsYComplete(0), nPixelsYComplete(0),
@ -233,7 +229,6 @@ public:
LOG(level) << "Max Frames Per File: " << maxFramesPerFile; LOG(level) << "Max Frames Per File: " << maxFramesPerFile;
LOG(level) << "Fifo Buffer Header Size: " << fifoBufferHeaderSize; LOG(level) << "Fifo Buffer Header Size: " << fifoBufferHeaderSize;
LOG(level) << "Default Fifo Depth: " << defaultFifoDepth; LOG(level) << "Default Fifo Depth: " << defaultFifoDepth;
LOG(level) << "Threads Per Receiver: " << threadsPerReceiver;
LOG(level) << "Header Packet Size: " << headerPacketSize; LOG(level) << "Header Packet Size: " << headerPacketSize;
LOG(level) << "Complete Pixels X: " << nPixelsXComplete; LOG(level) << "Complete Pixels X: " << nPixelsXComplete;
LOG(level) << "Complete Pixels Y: " << nPixelsYComplete; LOG(level) << "Complete Pixels Y: " << nPixelsYComplete;
@ -414,8 +409,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;
headerPacketSize = 40; headerPacketSize = 40;
standardheader = true; standardheader = true;
}; };
@ -428,6 +422,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);
} }
/** /**
@ -478,7 +473,6 @@ class JungfrauData : public GeneralData {
nPixelsY = 256; nPixelsY = 256;
packetsPerFrame = 64; packetsPerFrame = 64;
imageSize = dataSize * packetsPerFrame; imageSize = dataSize * packetsPerFrame;
threadsPerReceiver = 2;
defaultUdpSocketBufferSize = (500 * 1024 * 1024); defaultUdpSocketBufferSize = (500 * 1024 * 1024);
} }
@ -487,7 +481,6 @@ class JungfrauData : public GeneralData {
nPixelsY = 512; nPixelsY = 512;
packetsPerFrame = 128; packetsPerFrame = 128;
imageSize = dataSize * packetsPerFrame; imageSize = dataSize * packetsPerFrame;
threadsPerReceiver = 1;
defaultUdpSocketBufferSize = (1000 * 1024 * 1024); defaultUdpSocketBufferSize = (1000 * 1024 * 1024);
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -29,7 +29,7 @@ class Implementation : private virtual slsDetectorDefs {
void setDetectorType(const detectorType d); void setDetectorType(const detectorType d);
int *getMultiDetectorSize() const; int *getMultiDetectorSize() const;
void setMultiDetectorSize(const int *size); void setDetectorSize(const int *size);
int getDetectorPositionId() const; int getDetectorPositionId() const;
void setDetectorPositionId(const int id); void setDetectorPositionId(const int id);
std::string getDetectorHostname() const; std::string getDetectorHostname() const;
@ -75,12 +75,13 @@ 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;
std::vector<uint64_t> getNumMissingPackets() const; int getProgress() const;
uint64_t getNumMissingPackets() const;
void startReceiver(); void startReceiver();
void setStoppedFlag(bool stopped); void setStoppedFlag(bool stopped);
void stopReceiver(); void stopReceiver();
void startReadout(); void startReadout();
void shutDownUDPSockets(); void shutDownUDPSocket();
void closeFiles(); void closeFiles();
void restreamStop(); void restreamStop();
@ -90,19 +91,15 @@ class Implementation : private virtual slsDetectorDefs {
* Network Configuration (UDP) * * Network Configuration (UDP) *
* * * *
* ************************************************/ * ************************************************/
int getInterfaceId() const;
void setInterfaceId(const int value);
int getNumberofUDPInterfaces() const; int getNumberofUDPInterfaces() const;
/* [Jungfrau] */ /* [Jungfrau] */
void setNumberofUDPInterfaces(const int n); void setNumberofUDPInterfaces(const int n);
std::string getEthernetInterface() const; std::string getEthernetInterface() const;
void setEthernetInterface(const std::string &c); void setEthernetInterface(const std::string &c);
std::string getEthernetInterface2() const;
/* [Jungfrau] */
void setEthernetInterface2(const std::string &c);
uint32_t getUDPPortNumber() const; uint32_t getUDPPortNumber() const;
void setUDPPortNumber(const uint32_t i); void setUDPPortNumber(const uint32_t i);
uint32_t getUDPPortNumber2() const;
/* [Eiger][Jungfrau] */
void setUDPPortNumber2(const uint32_t i);
int64_t getUDPSocketBufferSize() const; int64_t getUDPSocketBufferSize() const;
void setUDPSocketBufferSize(const int64_t s); void setUDPSocketBufferSize(const int64_t s);
int64_t getActualUDPSocketBufferSize() const; int64_t getActualUDPSocketBufferSize() const;
@ -134,8 +131,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;
@ -214,7 +222,7 @@ class Implementation : private virtual slsDetectorDefs {
void SetupFifoStructure(); void SetupFifoStructure();
void ResetParametersforNewAcquisition(); void ResetParametersforNewAcquisition();
void CreateUDPSockets(); void CreateUDPSocket();
void SetupWriter(); void SetupWriter();
void StartRunning(); void StartRunning();
@ -226,9 +234,9 @@ class Implementation : private virtual slsDetectorDefs {
* ************************************************/ * ************************************************/
// config parameters // config parameters
int numThreads;
detectorType myDetectorType; detectorType myDetectorType;
int numDet[MAX_DIMENSIONS]; int numDet[MAX_DIMENSIONS];
int numRx[MAX_DIMENSIONS];
int detID; int detID;
std::string detHostname; std::string detHostname;
bool silentMode; bool silentMode;
@ -251,9 +259,10 @@ class Implementation : private virtual slsDetectorDefs {
bool stoppedFlag; bool stoppedFlag;
// network configuration (UDP) // network configuration (UDP)
int interfaceId;
int numUDPInterfaces; int numUDPInterfaces;
std::vector <std::string> eth; std::string eth;
std::vector <uint32_t> udpPortNum; uint32_t udpPortNum;
int64_t udpSocketBufferSize; int64_t udpSocketBufferSize;
int64_t actualUDPSocketBufferSize; int64_t actualUDPSocketBufferSize;
@ -266,7 +275,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;
@ -300,8 +315,8 @@ class Implementation : private virtual slsDetectorDefs {
// class objects // class objects
GeneralData *generalData; GeneralData *generalData;
std::vector<std::unique_ptr<Listener>> listener; std::unique_ptr<Listener> listener;
std::vector<std::unique_ptr<DataProcessor>> dataProcessor; std::unique_ptr<DataProcessor> dataProcessor;
std::vector<std::unique_ptr<DataStreamer>> dataStreamer; std::unique_ptr<DataStreamer> dataStreamer;
std::vector<std::unique_ptr<Fifo>> fifo; std::unique_ptr<Fifo> fifo;
}; };

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;
@ -149,7 +112,7 @@ void Listener::SetGeneralData(GeneralData* g) {
} }
void Listener::CreateUDPSockets() { void Listener::CreateUDPSocket() {
if (!(*activated)) { if (!(*activated)) {
return; return;
} }
@ -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
@ -106,9 +83,9 @@ class Listener : private virtual slsDetectorDefs, public ThreadObject {
void SetGeneralData(GeneralData* g); void SetGeneralData(GeneralData* g);
/** /**
* Creates UDP Sockets * Creates UDP Socket
*/ */
void CreateUDPSockets(); void CreateUDPSocket();
/** /**
* Shuts down and deletes UDP Sockets * Shuts down and deletes UDP Sockets
@ -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

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

@ -26,10 +26,10 @@ struct zmqHeader {
uint32_t jsonversion{0}; uint32_t jsonversion{0};
uint32_t dynamicRange{0}; uint32_t dynamicRange{0};
uint64_t fileIndex{0}; uint64_t fileIndex{0};
/** number of detectors in x axis */ /** number of sockets in x axis */
uint32_t ndetx{0}; uint32_t nSocketX{0};
/** number of detectors in y axis */ /** number of sockets in y axis */
uint32_t ndety{0}; uint32_t nSocketY{0};
/** number of pixels/channels in x axis for this zmq socket */ /** number of pixels/channels in x axis for this zmq socket */
uint32_t npixelsx{0}; uint32_t npixelsx{0};
/** number of pixels/channels in y axis for this zmq socket */ /** number of pixels/channels in y axis for this zmq socket */
@ -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

@ -32,6 +32,7 @@
/** default ports */ /** default ports */
#define DEFAULT_PORTNO 1952 #define DEFAULT_PORTNO 1952
#define DEFAULT_RX_PORTNO 1954
#define DEFAULT_UDP_PORTNO 50001 #define DEFAULT_UDP_PORTNO 50001
#define DEFAULT_ZMQ_CL_PORTNO 30001 #define DEFAULT_ZMQ_CL_PORTNO 30001
#define DEFAULT_ZMQ_RX_PORTNO 30001 #define DEFAULT_ZMQ_RX_PORTNO 30001
@ -87,8 +88,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 +176,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 +204,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 +245,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 +449,8 @@ class slsDetectorDefs {
enum burstMode { enum burstMode {
BURST_OFF, BURST_OFF,
BURST_INTERNAL, BURST_INTERNAL,
BURST_EXTERNAL BURST_EXTERNAL,
NUM_BURST_MODES
}; };
/** /**
@ -459,6 +461,46 @@ class slsDetectorDefs {
TIMING_EXTERNAL TIMING_EXTERNAL
}; };
#ifdef __cplusplus
/**
* structure to udpate receiver
*/
struct rxParameters {
detectorType detType{GENERIC};
xy detectorSize;
int moduleId{0};
char hostname[MAX_STR_LENGTH];
int interfaceId{0};
uint32_t zmq_ip{0U};
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 +522,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 +532,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 +539,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 +546,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 +553,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 +560,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 +567,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 +574,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,20 +196,26 @@ 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) */
F_EXEC_RECEIVER_COMMAND, F_EXEC_RECEIVER_COMMAND,
F_EXIT_RECEIVER, F_EXIT_RECEIVER,
F_LOCK_RECEIVER, F_SET_LOCK_RECEIVER,
F_GET_LOCK_RECEIVER,
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,
@ -240,15 +245,16 @@ enum detFuncs{
F_GET_RECEIVER_OVERWRITE, F_GET_RECEIVER_OVERWRITE,
F_ENABLE_RECEIVER_TEN_GIGA, F_ENABLE_RECEIVER_TEN_GIGA,
F_SET_RECEIVER_FIFO_DEPTH, F_SET_RECEIVER_FIFO_DEPTH,
F_GET_RECEIVER_FIFO_DEPTH,
F_RECEIVER_ACTIVATE, F_RECEIVER_ACTIVATE,
F_SET_RECEIVER_STREAMING, F_SET_RECEIVER_STREAMING,
F_GET_RECEIVER_STREAMING, F_GET_RECEIVER_STREAMING,
F_RECEIVER_STREAMING_TIMER, F_SET_RECEIVER_STREAMING_TIMER,
F_GET_RECEIVER_STREAMING_TIMER,
F_SET_FLIPPED_DATA_RECEIVER, F_SET_FLIPPED_DATA_RECEIVER,
F_GET_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,
@ -258,8 +264,9 @@ enum detFuncs{
F_RESTREAM_STOP_FROM_RECEIVER, F_RESTREAM_STOP_FROM_RECEIVER,
F_SET_ADDITIONAL_JSON_HEADER, F_SET_ADDITIONAL_JSON_HEADER,
F_GET_ADDITIONAL_JSON_HEADER, F_GET_ADDITIONAL_JSON_HEADER,
F_RECEIVER_UDP_SOCK_BUF_SIZE, F_SET_RECEIVER_UDP_SOCK_BUF_SIZE,
F_RECEIVER_REAL_UDP_SOCK_BUF_SIZE, F_GET_RECEIVER_UDP_SOCK_BUF_SIZE,
F_GET_RECEIVER_REAL_UDP_SOCK_BUF_SIZE,
F_SET_RECEIVER_FRAMES_PER_FILE, F_SET_RECEIVER_FRAMES_PER_FILE,
F_GET_RECEIVER_FRAMES_PER_FILE, F_GET_RECEIVER_FRAMES_PER_FILE,
F_RECEIVER_CHECK_VERSION, F_RECEIVER_CHECK_VERSION,
@ -278,15 +285,16 @@ enum detFuncs{
F_SET_RECEIVER_QUAD, F_SET_RECEIVER_QUAD,
F_SET_RECEIVER_READ_N_LINES, F_SET_RECEIVER_READ_N_LINES,
F_SET_RECEIVER_UDP_IP, F_SET_RECEIVER_UDP_IP,
F_SET_RECEIVER_UDP_IP2,
F_SET_RECEIVER_UDP_PORT, F_SET_RECEIVER_UDP_PORT,
F_SET_RECEIVER_UDP_PORT2,
F_SET_RECEIVER_NUM_INTERFACES, F_SET_RECEIVER_NUM_INTERFACES,
F_RECEIVER_SET_ADC_MASK_10G, F_RECEIVER_SET_ADC_MASK_10G,
F_RECEIVER_SET_NUM_COUNTERS, F_RECEIVER_SET_NUM_COUNTERS,
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 +365,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,20 +487,27 @@ 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";
case F_EXEC_RECEIVER_COMMAND: return "F_EXEC_RECEIVER_COMMAND"; case F_EXEC_RECEIVER_COMMAND: return "F_EXEC_RECEIVER_COMMAND";
case F_EXIT_RECEIVER: return "F_EXIT_RECEIVER"; case F_EXIT_RECEIVER: return "F_EXIT_RECEIVER";
case F_LOCK_RECEIVER: return "F_LOCK_RECEIVER"; case F_SET_LOCK_RECEIVER: return "F_SET_LOCK_RECEIVER";
case F_GET_LOCK_RECEIVER: return "F_GET_LOCK_RECEIVER";
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";
@ -523,15 +537,16 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_GET_RECEIVER_OVERWRITE: return "F_GET_RECEIVER_OVERWRITE"; case F_GET_RECEIVER_OVERWRITE: return "F_GET_RECEIVER_OVERWRITE";
case F_ENABLE_RECEIVER_TEN_GIGA: return "F_ENABLE_RECEIVER_TEN_GIGA"; case F_ENABLE_RECEIVER_TEN_GIGA: return "F_ENABLE_RECEIVER_TEN_GIGA";
case F_SET_RECEIVER_FIFO_DEPTH: return "F_SET_RECEIVER_FIFO_DEPTH"; case F_SET_RECEIVER_FIFO_DEPTH: return "F_SET_RECEIVER_FIFO_DEPTH";
case F_GET_RECEIVER_FIFO_DEPTH: return "F_GET_RECEIVER_FIFO_DEPTH";
case F_RECEIVER_ACTIVATE: return "F_RECEIVER_ACTIVATE"; case F_RECEIVER_ACTIVATE: return "F_RECEIVER_ACTIVATE";
case F_SET_RECEIVER_STREAMING: return "F_SET_RECEIVER_STREAMING"; case F_SET_RECEIVER_STREAMING: return "F_SET_RECEIVER_STREAMING";
case F_GET_RECEIVER_STREAMING: return "F_GET_RECEIVER_STREAMING"; case F_GET_RECEIVER_STREAMING: return "F_GET_RECEIVER_STREAMING";
case F_RECEIVER_STREAMING_TIMER: return "F_RECEIVER_STREAMING_TIMER"; case F_SET_RECEIVER_STREAMING_TIMER: return "F_SET_RECEIVER_STREAMING_TIMER";
case F_GET_RECEIVER_STREAMING_TIMER: return "F_GET_RECEIVER_STREAMING_TIMER";
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_GET_FLIPPED_DATA_RECEIVER: return "F_GET_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";
@ -541,8 +556,9 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_RESTREAM_STOP_FROM_RECEIVER: return "F_RESTREAM_STOP_FROM_RECEIVER"; case F_RESTREAM_STOP_FROM_RECEIVER: return "F_RESTREAM_STOP_FROM_RECEIVER";
case F_SET_ADDITIONAL_JSON_HEADER: return "F_SET_ADDITIONAL_JSON_HEADER"; case F_SET_ADDITIONAL_JSON_HEADER: return "F_SET_ADDITIONAL_JSON_HEADER";
case F_GET_ADDITIONAL_JSON_HEADER: return "F_GET_ADDITIONAL_JSON_HEADER"; case F_GET_ADDITIONAL_JSON_HEADER: return "F_GET_ADDITIONAL_JSON_HEADER";
case F_RECEIVER_UDP_SOCK_BUF_SIZE: return "F_RECEIVER_UDP_SOCK_BUF_SIZE"; case F_SET_RECEIVER_UDP_SOCK_BUF_SIZE: return "F_SET_RECEIVER_UDP_SOCK_BUF_SIZE";
case F_RECEIVER_REAL_UDP_SOCK_BUF_SIZE: return "F_RECEIVER_REAL_UDP_SOCK_BUF_SIZE"; case F_GET_RECEIVER_UDP_SOCK_BUF_SIZE: return "F_GET_RECEIVER_UDP_SOCK_BUF_SIZE";
case F_GET_RECEIVER_REAL_UDP_SOCK_BUF_SIZE: return "F_GET_RECEIVER_REAL_UDP_SOCK_BUF_SIZE";
case F_SET_RECEIVER_FRAMES_PER_FILE: return "F_SET_RECEIVER_FRAMES_PER_FILE"; case F_SET_RECEIVER_FRAMES_PER_FILE: return "F_SET_RECEIVER_FRAMES_PER_FILE";
case F_GET_RECEIVER_FRAMES_PER_FILE: return "F_GET_RECEIVER_FRAMES_PER_FILE"; case F_GET_RECEIVER_FRAMES_PER_FILE: return "F_GET_RECEIVER_FRAMES_PER_FILE";
case F_RECEIVER_CHECK_VERSION: return "F_RECEIVER_CHECK_VERSION"; case F_RECEIVER_CHECK_VERSION: return "F_RECEIVER_CHECK_VERSION";
@ -561,15 +577,14 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_SET_RECEIVER_QUAD: return "F_SET_RECEIVER_QUAD"; case F_SET_RECEIVER_QUAD: return "F_SET_RECEIVER_QUAD";
case F_SET_RECEIVER_READ_N_LINES: return "F_SET_RECEIVER_READ_N_LINES"; case F_SET_RECEIVER_READ_N_LINES: return "F_SET_RECEIVER_READ_N_LINES";
case F_SET_RECEIVER_UDP_IP: return "F_SET_RECEIVER_UDP_IP"; case F_SET_RECEIVER_UDP_IP: return "F_SET_RECEIVER_UDP_IP";
case F_SET_RECEIVER_UDP_IP2: return "F_SET_RECEIVER_UDP_IP2";
case F_SET_RECEIVER_UDP_PORT: return "F_SET_RECEIVER_UDP_PORT"; case F_SET_RECEIVER_UDP_PORT: return "F_SET_RECEIVER_UDP_PORT";
case F_SET_RECEIVER_UDP_PORT2: return "F_SET_RECEIVER_UDP_PORT2";
case F_SET_RECEIVER_NUM_INTERFACES: return "F_SET_RECEIVER_NUM_INTERFACES"; case F_SET_RECEIVER_NUM_INTERFACES: return "F_SET_RECEIVER_NUM_INTERFACES";
case F_RECEIVER_SET_ADC_MASK_10G: return "F_RECEIVER_SET_ADC_MASK_10G"; case F_RECEIVER_SET_ADC_MASK_10G: return "F_RECEIVER_SET_ADC_MASK_10G";
case F_RECEIVER_SET_NUM_COUNTERS: return "F_RECEIVER_SET_NUM_COUNTERS"; case F_RECEIVER_SET_NUM_COUNTERS: return "F_RECEIVER_SET_NUM_COUNTERS";
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, "
@ -186,13 +187,14 @@ int ZmqSocket::SendHeader(
header.jsonversion, header.jsonversion,
header.dynamicRange, header.dynamicRange,
header.fileIndex, header.fileIndex,
header.ndetx, header.nSocketX,
header.ndety, header.nSocketY,
header.npixelsx, header.npixelsx,
header.npixelsy, header.npixelsy,
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,
@ -317,13 +319,14 @@ int ZmqSocket::ParseHeader(const int index, int length, char *buff,
zHeader.data = ((document["data"].GetUint()) == 0) ? false : true; zHeader.data = ((document["data"].GetUint()) == 0) ? false : true;
zHeader.dynamicRange = document["bitmode"].GetUint(); zHeader.dynamicRange = document["bitmode"].GetUint();
zHeader.fileIndex = document["fileIndex"].GetUint64(); zHeader.fileIndex = document["fileIndex"].GetUint64();
zHeader.ndetx = document["detshape"][0].GetUint(); zHeader.nSocketX = document["detshape"][0].GetUint();
zHeader.ndety = document["detshape"][1].GetUint(); zHeader.nSocketY = document["detshape"][1].GetUint();
zHeader.npixelsx = document["shape"][0].GetUint(); zHeader.npixelsx = document["shape"][0].GetUint();
zHeader.npixelsy = document["shape"][1].GetUint(); zHeader.npixelsy = document["shape"][1].GetUint();
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);
}