mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-04-21 03:10:02 +02:00
gotthard and jungfrau servers do not need to send whole module for sending settings anymore
This commit is contained in:
parent
3f61206289
commit
bdf9373e0d
Binary file not shown.
@ -303,13 +303,14 @@ void setMasterSlaveConfiguration(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
cprintf(BLUE, "masterflags: %d\n"
|
cprintf(BLUE,
|
||||||
|
"masterflags: %d\n"
|
||||||
"masterdefaultdelay:%d\n"
|
"masterdefaultdelay:%d\n"
|
||||||
"patternphase:%d\n"
|
"patternphase:%d\n"
|
||||||
"adcphase:%d\n"
|
"adcphase:%d\n"
|
||||||
"slavepatternphase:%d\n"
|
"slavepatternphase:%d\n"
|
||||||
"slaveadcphase:%d\n"
|
"slaveadcphase:%d\n"
|
||||||
"rsttosw1delay:%d\n",
|
"rsttosw1delay:%d\n"
|
||||||
"startacqdelay:%d\n",
|
"startacqdelay:%d\n",
|
||||||
masterflags,
|
masterflags,
|
||||||
masterdefaultdelay,
|
masterdefaultdelay,
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
Path: slsDetectorsPackage/slsDetectorSoftware/gotthardDetectorServer
|
Path: slsDetectorsPackage/slsDetectorSoftware/gotthardDetectorServer
|
||||||
URL: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git
|
URL: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git
|
||||||
Repository Root: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git
|
Repository Root: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git
|
||||||
Repsitory UUID: 675d69392a6497d42b23057c7c8783c8dad768d0
|
Repsitory UUID: 3f6120628938fb0820908fb82574418039a3b352
|
||||||
Revision: 223
|
Revision: 230
|
||||||
Branch: 3.1.0-rc
|
Branch: developer
|
||||||
Last Changed Author: Dhanya_Thattil
|
Last Changed Author: Dhanya_Thattil
|
||||||
Last Changed Rev: 3447
|
Last Changed Rev: 3829
|
||||||
Last Changed Date: 2018-02-27 14:04:08.000000002 +0100 ./server_funcs.c
|
Last Changed Date: 2018-05-22 13:58:08.000000002 +0200 ./mcb_funcs.c
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#define GITURL "git@github.com:slsdetectorgroup/slsDetectorPackage.git"
|
#define GITURL "git@github.com:slsdetectorgroup/slsDetectorPackage.git"
|
||||||
#define GITREPUUID "675d69392a6497d42b23057c7c8783c8dad768d0"
|
#define GITREPUUID "3f6120628938fb0820908fb82574418039a3b352"
|
||||||
#define GITAUTH "Dhanya_Thattil"
|
#define GITAUTH "Dhanya_Thattil"
|
||||||
#define GITREV 0x3447
|
#define GITREV 0x3829
|
||||||
#define GITDATE 0x20180227
|
#define GITDATE 0x20180522
|
||||||
#define GITBRANCH "3.1.0-rc"
|
#define GITBRANCH "developer"
|
||||||
|
Binary file not shown.
@ -114,6 +114,28 @@ int initDetector() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int setDefaultDacs() {
|
||||||
|
printf("Setting Default Dac values\n");
|
||||||
|
|
||||||
|
int ret = OK;
|
||||||
|
int i = 0;
|
||||||
|
int retval[2]={-1,-1};
|
||||||
|
const int defaultvals[NDAC] = DEFAULT_DAC_VALS;
|
||||||
|
|
||||||
|
for(i = 0; i < NDAC; ++i) {
|
||||||
|
// if not already default, set it to default
|
||||||
|
if (setDACRegister(i, -1, -1) != defaultvals[i]) {
|
||||||
|
initDACbyIndexDACU(i, defaultvals[i], 0, 0, retval);
|
||||||
|
if (abs(retval[0] - defaultvals[i])<=3) {
|
||||||
|
cprintf(RED, "Warning: Setting dac %d failed, wrote %d, read %d\n",i ,defaultvals[i], retval[0]);
|
||||||
|
ret = FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int copyChannel(sls_detector_channel *destChan, sls_detector_channel *srcChan) {
|
int copyChannel(sls_detector_channel *destChan, sls_detector_channel *srcChan) {
|
||||||
|
@ -18,6 +18,16 @@
|
|||||||
|
|
||||||
// DAC definitions
|
// DAC definitions
|
||||||
enum dacsVal{VREF_DS, VCASCN_PB, VCASCP_PB, VOUT_CM, VCASC_OUT, VIN_CM, VREF_COMP, IB_TESTC,HIGH_VOLTAGE, CONFGAIN};
|
enum dacsVal{VREF_DS, VCASCN_PB, VCASCP_PB, VOUT_CM, VCASC_OUT, VIN_CM, VREF_COMP, IB_TESTC,HIGH_VOLTAGE, CONFGAIN};
|
||||||
|
#define DEFAULT_DAC_VALS { \
|
||||||
|
660, /* VREF_DS */ \
|
||||||
|
650, /* VCASCN_PB */ \
|
||||||
|
1480, /* VCASCP_PB */ \
|
||||||
|
1520, /* VOUT_CM */ \
|
||||||
|
1320, /* VCASC_OUT */ \
|
||||||
|
1350, /* VIN_CM */ \
|
||||||
|
350, /* VREF_COMP */ \
|
||||||
|
2001 /* IB_TESTC */ \
|
||||||
|
};
|
||||||
|
|
||||||
/* DAC adresses */
|
/* DAC adresses */
|
||||||
#define DACCS {0,0,1,1,2,2,3,3,4,4,5,5,6,6}
|
#define DACCS {0,0,1,1,2,2,3,3,4,4,5,5,6,6}
|
||||||
@ -84,6 +94,7 @@ enum adcVals{TEMP_FPGA, TEMP_ADC};
|
|||||||
void showbits(int h);
|
void showbits(int h);
|
||||||
|
|
||||||
int initDetector();
|
int initDetector();
|
||||||
|
int setDefaultDacs();
|
||||||
int copyChannel(sls_detector_channel *destChan, sls_detector_channel *srcChan);
|
int copyChannel(sls_detector_channel *destChan, sls_detector_channel *srcChan);
|
||||||
int copyChip(sls_detector_chip *destChip, sls_detector_chip *srcChip);
|
int copyChip(sls_detector_chip *destChip, sls_detector_chip *srcChip);
|
||||||
int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod);
|
int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod);
|
||||||
|
@ -87,9 +87,10 @@ int init_detector( int b) {
|
|||||||
setPhaseShiftOnce();
|
setPhaseShiftOnce();
|
||||||
configureADC();
|
configureADC();
|
||||||
setADC(-1); //already does setdaqreg and clean fifo
|
setADC(-1); //already does setdaqreg and clean fifo
|
||||||
setSettings(GET_SETTINGS,-1);
|
setSettings(DYNAMICGAIN,-1);
|
||||||
|
setDefaultDacs();
|
||||||
|
|
||||||
//Initialization
|
//Initialization
|
||||||
setFrames(1);
|
setFrames(1);
|
||||||
setTrains(1);
|
setTrains(1);
|
||||||
setExposureTime(1e6);
|
setExposureTime(1e6);
|
||||||
@ -1660,19 +1661,43 @@ int set_settings(int file_des) {
|
|||||||
sprintf(mess,"Detector locked by %s\n",lastClientIP);
|
sprintf(mess,"Detector locked by %s\n",lastClientIP);
|
||||||
} else {
|
} else {
|
||||||
#ifdef MCB_FUNCS
|
#ifdef MCB_FUNCS
|
||||||
retval=setSettings(arg[0],imod);
|
switch(isett) {
|
||||||
#endif
|
case GET_SETTINGS:
|
||||||
|
case UNINITIALIZED:
|
||||||
|
case DYNAMICGAIN:
|
||||||
|
case HIGHGAIN:
|
||||||
|
case LOWGAIN:
|
||||||
|
case MEDIUMGAIN:
|
||||||
|
case VERYHIGHGAIN:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret = FAIL;
|
||||||
|
sprintf(mess,"Setting (%d) is not implemented for this detector.\n"
|
||||||
|
"Options are dynamicgain, highgain, lowgain, mediumgain and "
|
||||||
|
"veryhighgain.\n", isett);
|
||||||
|
cprintf(RED, "Warning: %s", mess);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ret != FAIL) {
|
||||||
|
retval=setSettings(isett,imod);
|
||||||
#ifdef VERBOSE
|
#ifdef VERBOSE
|
||||||
printf("Settings changed to %d\n",retval);
|
printf("Settings changed to %d\n",retval);
|
||||||
#endif
|
#endif
|
||||||
|
if (retval != isett && isett >= 0) {
|
||||||
|
ret=FAIL;
|
||||||
|
sprintf(mess, "Changing settings of module %d: wrote %d but read %d\n", imod, isett, retval);
|
||||||
|
printf("Warning: %s",mess);
|
||||||
|
}
|
||||||
|
|
||||||
if (retval==isett || isett<0) {
|
else {
|
||||||
ret=OK;
|
ret = setDefaultDacs();
|
||||||
} else {
|
if (ret == FAIL) {
|
||||||
ret=FAIL;
|
strcpy(mess,"Could change settings, but could not set to default dacs\n");
|
||||||
printf("Changing settings of module %d: wrote %d but read %d\n", imod, isett, retval);
|
cprintf(RED, "Warning: %s", mess);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (ret==OK && differentClients==1)
|
if (ret==OK && differentClients==1)
|
||||||
ret=FORCE_UPDATE;
|
ret=FORCE_UPDATE;
|
||||||
|
Binary file not shown.
@ -1,9 +1,9 @@
|
|||||||
Path: slsDetectorsPackage/slsDetectorSoftware/jungfrauDetectorServer
|
Path: slsDetectorsPackage/slsDetectorSoftware/jungfrauDetectorServer
|
||||||
URL: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git
|
URL: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git
|
||||||
Repository Root: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git
|
Repository Root: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git
|
||||||
Repsitory UUID: 5b01b4cbd808a3c43f1ec97032a1020c8f2ce37a
|
Repsitory UUID: 3f6120628938fb0820908fb82574418039a3b352
|
||||||
Revision: 144
|
Revision: 150
|
||||||
Branch: developer
|
Branch: developer
|
||||||
Last Changed Author: Dhanya_Thattil
|
Last Changed Author: Dhanya_Thattil
|
||||||
Last Changed Rev: 3807
|
Last Changed Rev: 3829
|
||||||
Last Changed Date: 2018-05-02 17:42:08.000000002 +0200 ./RegisterDefs.h
|
Last Changed Date: 2018-05-15 13:48:54.000000002 +0200 ./RegisterDefs.h
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#define GITURL "git@github.com:slsdetectorgroup/slsDetectorPackage.git"
|
#define GITURL "git@github.com:slsdetectorgroup/slsDetectorPackage.git"
|
||||||
#define GITREPUUID "5b01b4cbd808a3c43f1ec97032a1020c8f2ce37a"
|
#define GITREPUUID "3f6120628938fb0820908fb82574418039a3b352"
|
||||||
#define GITAUTH "Dhanya_Thattil"
|
#define GITAUTH "Dhanya_Thattil"
|
||||||
#define GITREV 0x3807
|
#define GITREV 0x3829
|
||||||
#define GITDATE 0x20180502
|
#define GITDATE 0x20180515
|
||||||
#define GITBRANCH "developer"
|
#define GITBRANCH "developer"
|
||||||
|
@ -356,6 +356,13 @@ void allocateDetectorStructureMemory(){
|
|||||||
(detectorModules)->offset=0;
|
(detectorModules)->offset=0;
|
||||||
(detectorModules)->reg=0;
|
(detectorModules)->reg=0;
|
||||||
thisSettings = UNINITIALIZED;
|
thisSettings = UNINITIALIZED;
|
||||||
|
|
||||||
|
{ // initialize to -1
|
||||||
|
int i = 0;
|
||||||
|
for (i = 0; i < NDAC; ++i) {
|
||||||
|
dacValues[i] = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -377,17 +384,7 @@ void setupDetector() {
|
|||||||
initDac(8); //only for old board compatibility
|
initDac(8); //only for old board compatibility
|
||||||
|
|
||||||
//set dacs
|
//set dacs
|
||||||
printf("Setting Default Dac values\n");
|
setDefaultDacs();
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
int retval[2]={-1,-1};
|
|
||||||
const int defaultvals[NDAC] = DEFAULT_DAC_VALS;
|
|
||||||
for(i = 0; i < NDAC; ++i) {
|
|
||||||
setDAC((enum DACINDEX)i,defaultvals[i],0,0,retval);
|
|
||||||
if (retval[0] != defaultvals[i])
|
|
||||||
cprintf(RED, "Warning: Setting dac %d failed, wrote %d, read %d\n",i ,defaultvals[i], retval[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bus_w(DAQ_REG, 0x0); /* Only once at server startup */
|
bus_w(DAQ_REG, 0x0); /* Only once at server startup */
|
||||||
|
|
||||||
@ -422,7 +419,26 @@ void setupDetector() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int setDefaultDacs() {
|
||||||
|
int ret = OK;
|
||||||
|
printf("Setting Default Dac values\n");
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
int retval[2]={-1,-1};
|
||||||
|
const int defaultvals[NDAC] = DEFAULT_DAC_VALS;
|
||||||
|
for(i = 0; i < NDAC; ++i) {
|
||||||
|
// if not already default, set it to default
|
||||||
|
if (dacValues[i] != defaultvals[i]) {
|
||||||
|
setDAC((enum DACINDEX)i,defaultvals[i],0,0,retval);
|
||||||
|
if (retval[0] != defaultvals[i]) {
|
||||||
|
cprintf(RED, "Warning: Setting dac %d failed, wrote %d, read %d\n",i ,defaultvals[i], retval[0]);
|
||||||
|
ret = FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -3757,50 +3757,22 @@ int slsDetector::setThresholdEnergyAndSettings(int e_eV, detectorSettings isetti
|
|||||||
*/
|
*/
|
||||||
slsDetectorDefs::detectorSettings slsDetector::getSettings(int imod){
|
slsDetectorDefs::detectorSettings slsDetector::getSettings(int imod){
|
||||||
|
|
||||||
|
return sendSettingsOnly(GET_SETTINGS, imod);
|
||||||
int fnum=F_SET_SETTINGS;
|
}
|
||||||
int ret=FAIL;
|
|
||||||
char mess[MAX_STR_LENGTH]="";
|
|
||||||
int retval;
|
|
||||||
int arg[2];
|
|
||||||
arg[0]=GET_SETTINGS;
|
|
||||||
arg[1]=imod;
|
|
||||||
#ifdef VERBOSE
|
|
||||||
std::cout<< "Getting settings "<< std::endl;
|
|
||||||
#endif
|
|
||||||
if (thisDetector->onlineFlag==ONLINE_FLAG) {
|
|
||||||
if (connectControl() == OK){
|
|
||||||
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
|
|
||||||
controlSocket->SendDataOnly(arg,sizeof(arg));
|
|
||||||
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
|
|
||||||
if (ret==FAIL) {
|
|
||||||
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
|
|
||||||
std::cout<< "Detector returned error: " << mess << std::endl;
|
|
||||||
} else{
|
|
||||||
controlSocket->ReceiveDataOnly(&retval,sizeof(retval));
|
|
||||||
thisDetector->currentSettings=(detectorSettings)retval;
|
|
||||||
#ifdef VERBOSE
|
|
||||||
std::cout<< "Settings are "<< retval << std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
disconnectControl();
|
|
||||||
if (ret==FORCE_UPDATE)
|
|
||||||
updateDetector();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return thisDetector->currentSettings;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
slsDetectorDefs::detectorSettings slsDetector::setSettings( detectorSettings isettings, int imod){
|
slsDetectorDefs::detectorSettings slsDetector::setSettings( detectorSettings isettings, int imod){
|
||||||
#ifdef VERBOSE
|
#ifdef VERBOSE
|
||||||
std::cout<< "slsDetector setSettings "<< std::endl;
|
std::cout<< "slsDetector setSettings " << isettings << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//only set client shared memory variable for Eiger, settings threshold loads the module data (trimbits, dacs etc.)
|
detectorType detType = thisDetector->myDetectorType;
|
||||||
if (thisDetector->myDetectorType == EIGER) {
|
switch (detType) {
|
||||||
|
|
||||||
|
// eiger: only set client shared memory variable for Eiger,
|
||||||
|
// settings threshold loads the module data (trimbits, dacs etc.)
|
||||||
|
case EIGER:
|
||||||
switch(isettings) {
|
switch(isettings) {
|
||||||
case STANDARD:
|
case STANDARD:
|
||||||
case HIGHGAIN:
|
case HIGHGAIN:
|
||||||
@ -3815,8 +3787,24 @@ slsDetectorDefs::detectorSettings slsDetector::setSettings( detectorSettings ise
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return thisDetector->currentSettings;
|
return thisDetector->currentSettings;
|
||||||
|
|
||||||
|
// send only the settings, detector server will update dac values already in server
|
||||||
|
case GOTTHARD:
|
||||||
|
case PROPIX:
|
||||||
|
case JUNGFRAU:
|
||||||
|
case MOENCH:
|
||||||
|
return sendSettingsOnly(isettings);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// others send whole module to detector
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// MYTHEN ONLY (sends whole detector to module)
|
||||||
|
|
||||||
sls_detector_module *myMod=createModule();
|
sls_detector_module *myMod=createModule();
|
||||||
int modmi=imod, modma=imod+1, im=imod;
|
int modmi=imod, modma=imod+1, im=imod;
|
||||||
string settingsfname, calfname;
|
string settingsfname, calfname;
|
||||||
@ -3832,105 +3820,18 @@ slsDetectorDefs::detectorSettings slsDetector::setSettings( detectorSettings ise
|
|||||||
offsetval=new int[thisDetector->nOffset];
|
offsetval=new int[thisDetector->nOffset];
|
||||||
|
|
||||||
|
|
||||||
int ret=0;
|
|
||||||
|
|
||||||
|
|
||||||
switch (isettings) {
|
switch (isettings) {
|
||||||
case STANDARD:
|
case STANDARD:
|
||||||
if ( (thisDetector->myDetectorType == MYTHEN) ||
|
ssettings="/standard";
|
||||||
(thisDetector->myDetectorType == EIGER)) {
|
thisDetector->currentSettings=STANDARD;
|
||||||
ssettings="/standard";
|
|
||||||
thisDetector->currentSettings=STANDARD;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case FAST:
|
case FAST:
|
||||||
if (thisDetector->myDetectorType == MYTHEN) {
|
ssettings="/fast";
|
||||||
ssettings="/fast";
|
thisDetector->currentSettings=FAST;
|
||||||
thisDetector->currentSettings=FAST;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case HIGHGAIN:
|
case HIGHGAIN:
|
||||||
if ( (thisDetector->myDetectorType == MYTHEN) ||
|
ssettings="/highgain";
|
||||||
(thisDetector->myDetectorType == GOTTHARD) ||
|
thisDetector->currentSettings=HIGHGAIN;
|
||||||
(thisDetector->myDetectorType == PROPIX) ||
|
|
||||||
(thisDetector->myDetectorType == MOENCH) ||
|
|
||||||
(thisDetector->myDetectorType == EIGER)) {
|
|
||||||
ssettings="/highgain";
|
|
||||||
thisDetector->currentSettings=HIGHGAIN;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case DYNAMICGAIN:
|
|
||||||
if ((thisDetector->myDetectorType == GOTTHARD) ||
|
|
||||||
(thisDetector->myDetectorType == PROPIX) ||
|
|
||||||
(thisDetector->myDetectorType == JUNGFRAU) ||
|
|
||||||
(thisDetector->myDetectorType == MOENCH)) {
|
|
||||||
ssettings="/dynamicgain";
|
|
||||||
thisDetector->currentSettings=DYNAMICGAIN;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case LOWGAIN:
|
|
||||||
if ((thisDetector->myDetectorType == GOTTHARD) ||
|
|
||||||
(thisDetector->myDetectorType == PROPIX) ||
|
|
||||||
(thisDetector->myDetectorType == MOENCH) ||
|
|
||||||
(thisDetector->myDetectorType == EIGER) ) {
|
|
||||||
ssettings="/lowgain";
|
|
||||||
thisDetector->currentSettings=LOWGAIN;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MEDIUMGAIN:
|
|
||||||
if ((thisDetector->myDetectorType == GOTTHARD) ||
|
|
||||||
(thisDetector->myDetectorType == PROPIX) ||
|
|
||||||
(thisDetector->myDetectorType == MOENCH)) {
|
|
||||||
ssettings="/mediumgain";
|
|
||||||
thisDetector->currentSettings=MEDIUMGAIN;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case VERYHIGHGAIN:
|
|
||||||
if ((thisDetector->myDetectorType == GOTTHARD) ||
|
|
||||||
(thisDetector->myDetectorType == PROPIX) ||
|
|
||||||
(thisDetector->myDetectorType == MOENCH)||
|
|
||||||
(thisDetector->myDetectorType == EIGER)) {
|
|
||||||
ssettings="/veryhighgain";
|
|
||||||
thisDetector->currentSettings=VERYHIGHGAIN;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case LOWNOISE:
|
|
||||||
break;
|
|
||||||
case DYNAMICHG0:
|
|
||||||
if (thisDetector->myDetectorType == JUNGFRAU) {
|
|
||||||
ssettings="/dynamichg0";
|
|
||||||
thisDetector->currentSettings=DYNAMICHG0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FIXGAIN1:
|
|
||||||
if (thisDetector->myDetectorType == JUNGFRAU) {
|
|
||||||
ssettings="/fixgain1";
|
|
||||||
thisDetector->currentSettings=FIXGAIN1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FIXGAIN2:
|
|
||||||
if (thisDetector->myDetectorType == JUNGFRAU) {
|
|
||||||
ssettings="/fixgain2";
|
|
||||||
thisDetector->currentSettings=FIXGAIN2;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FORCESWITCHG1:
|
|
||||||
if (thisDetector->myDetectorType == JUNGFRAU) {
|
|
||||||
ssettings="/forceswitchg1";
|
|
||||||
thisDetector->currentSettings=FORCESWITCHG1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FORCESWITCHG2:
|
|
||||||
if (thisDetector->myDetectorType == JUNGFRAU) {
|
|
||||||
ssettings="/forceswitchg2";
|
|
||||||
thisDetector->currentSettings=FORCESWITCHG2;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case VERYLOWGAIN:
|
|
||||||
if (thisDetector->myDetectorType == EIGER) {
|
|
||||||
ssettings="/verylowgain";
|
|
||||||
thisDetector->currentSettings=VERYLOWGAIN;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -3954,30 +3855,8 @@ slsDetectorDefs::detectorSettings slsDetector::setSettings( detectorSettings ise
|
|||||||
std::cout << std::endl << "Loading settings for module:" << im << std::endl;
|
std::cout << std::endl << "Loading settings for module:" << im << std::endl;
|
||||||
|
|
||||||
//create file names
|
//create file names
|
||||||
switch(thisDetector->myDetectorType){
|
ostfn << thisDetector->settingsDir << ssettings <<"/noise.sn" << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im) << setbase(10);
|
||||||
case EIGER:
|
oscfn << thisDetector->calDir << ssettings << "/calibration.sn" << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im) << setbase(10);
|
||||||
//settings is saved in myMod.reg
|
|
||||||
myMod->reg=thisDetector->currentSettings;
|
|
||||||
ostfn << thisDetector->settingsDir << ssettings <<"/noise.sn" << setfill('0') << setw(3) << dec << getId(DETECTOR_SERIAL_NUMBER) << setbase(10);
|
|
||||||
oscfn << thisDetector->calDir << ssettings << "/calibration.sn" << setfill('0') << setw(3) << dec << getId(DETECTOR_SERIAL_NUMBER) << setbase(10);
|
|
||||||
#ifdef VERBOSE
|
|
||||||
std::cout<< thisDetector->settingsDir<<endl<< thisDetector->calDir <<endl;
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case MYTHEN:
|
|
||||||
ostfn << thisDetector->settingsDir << ssettings <<"/noise.sn" << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im) << setbase(10);
|
|
||||||
oscfn << thisDetector->calDir << ssettings << "/calibration.sn" << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im) << setbase(10);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
//settings is saved in myMod.reg
|
|
||||||
myMod->reg=thisDetector->currentSettings;
|
|
||||||
ostfn << thisDetector->settingsDir << ssettings <<"/settings.sn";// << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im) << setbase(10);
|
|
||||||
oscfn << thisDetector->calDir << ssettings << "/calibration.sn";// << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im) << setbase(10);
|
|
||||||
#ifdef VERBOSE
|
|
||||||
std::cout<< thisDetector->settingsDir<<endl<< thisDetector->calDir <<endl;
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//settings file****
|
//settings file****
|
||||||
@ -3985,23 +3864,15 @@ slsDetectorDefs::detectorSettings slsDetector::setSettings( detectorSettings ise
|
|||||||
#ifdef VERBOSE
|
#ifdef VERBOSE
|
||||||
cout << "the settings file name is "<<settingsfname << endl;
|
cout << "the settings file name is "<<settingsfname << endl;
|
||||||
#endif
|
#endif
|
||||||
if (NULL == readSettingsFile(settingsfname,thisDetector->myDetectorType, iodelay, tau, myMod)) {
|
if (NULL == readSettingsFile(settingsfname,detType, iodelay, tau, myMod)) {
|
||||||
//if it didnt open, try default settings file
|
//if it didnt open, try default settings file
|
||||||
ostringstream ostfn_default;
|
ostringstream ostfn_default;
|
||||||
switch(thisDetector->myDetectorType){
|
ostfn_default << thisDetector->settingsDir << ssettings << ssettings << ".trim";
|
||||||
case EIGER:
|
|
||||||
case MYTHEN:
|
|
||||||
ostfn_default << thisDetector->settingsDir << ssettings << ssettings << ".trim";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ostfn_default << thisDetector->settingsDir << ssettings << ssettings << ".settings";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
settingsfname=ostfn_default.str();
|
settingsfname=ostfn_default.str();
|
||||||
#ifdef VERBOSE
|
#ifdef VERBOSE
|
||||||
cout << settingsfname << endl;
|
cout << settingsfname << endl;
|
||||||
#endif
|
#endif
|
||||||
if (NULL == readSettingsFile(settingsfname,thisDetector->myDetectorType, iodelay, tau, myMod)) {
|
if (NULL == readSettingsFile(settingsfname,detType, iodelay, tau, myMod)) {
|
||||||
//if default doesnt work, return error
|
//if default doesnt work, return error
|
||||||
std::cout << "Could not open settings file" << endl;
|
std::cout << "Could not open settings file" << endl;
|
||||||
setErrorMask((getErrorMask())|(SETTINGS_FILE_NOT_OPEN));
|
setErrorMask((getErrorMask())|(SETTINGS_FILE_NOT_OPEN));
|
||||||
@ -4012,10 +3883,25 @@ slsDetectorDefs::detectorSettings slsDetector::setSettings( detectorSettings ise
|
|||||||
|
|
||||||
|
|
||||||
//calibration file****
|
//calibration file****
|
||||||
if(thisDetector->myDetectorType != EIGER) {
|
int ret=0;
|
||||||
calfname=oscfn.str();
|
calfname=oscfn.str();
|
||||||
#ifdef VERBOSE
|
#ifdef VERBOSE
|
||||||
cout << "Specific file:"<< calfname << endl;
|
cout << "Specific file:"<< calfname << endl;
|
||||||
|
#endif
|
||||||
|
//extra gain and offset
|
||||||
|
if(thisDetector->nGain)
|
||||||
|
ret = readCalibrationFile(calfname,gainval, offsetval);
|
||||||
|
//normal gain and offset inside sls_detector_module
|
||||||
|
else
|
||||||
|
ret = readCalibrationFile(calfname,myMod->gain, myMod->offset);
|
||||||
|
|
||||||
|
//if it didnt open, try default
|
||||||
|
if(ret != OK){
|
||||||
|
ostringstream oscfn_default;
|
||||||
|
oscfn_default << thisDetector->calDir << ssettings << ssettings << ".cal";
|
||||||
|
calfname=oscfn_default.str();
|
||||||
|
#ifdef VERBOSE
|
||||||
|
cout << "Default file:" << calfname << endl;
|
||||||
#endif
|
#endif
|
||||||
//extra gain and offset
|
//extra gain and offset
|
||||||
if(thisDetector->nGain)
|
if(thisDetector->nGain)
|
||||||
@ -4023,29 +3909,14 @@ slsDetectorDefs::detectorSettings slsDetector::setSettings( detectorSettings ise
|
|||||||
//normal gain and offset inside sls_detector_module
|
//normal gain and offset inside sls_detector_module
|
||||||
else
|
else
|
||||||
ret = readCalibrationFile(calfname,myMod->gain, myMod->offset);
|
ret = readCalibrationFile(calfname,myMod->gain, myMod->offset);
|
||||||
|
|
||||||
//if it didnt open, try default
|
|
||||||
if(ret != OK){
|
|
||||||
ostringstream oscfn_default;
|
|
||||||
oscfn_default << thisDetector->calDir << ssettings << ssettings << ".cal";
|
|
||||||
calfname=oscfn_default.str();
|
|
||||||
#ifdef VERBOSE
|
|
||||||
cout << "Default file:" << calfname << endl;
|
|
||||||
#endif
|
|
||||||
//extra gain and offset
|
|
||||||
if(thisDetector->nGain)
|
|
||||||
ret = readCalibrationFile(calfname,gainval, offsetval);
|
|
||||||
//normal gain and offset inside sls_detector_module
|
|
||||||
else
|
|
||||||
ret = readCalibrationFile(calfname,myMod->gain, myMod->offset);
|
|
||||||
}
|
|
||||||
//if default doesnt work, return error
|
|
||||||
if(ret != OK){
|
|
||||||
std::cout << "Could not open calibration file" << calfname << endl;
|
|
||||||
setErrorMask((getErrorMask())|(SETTINGS_FILE_NOT_OPEN));
|
|
||||||
return thisDetector->currentSettings;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
//if default doesnt work, return error
|
||||||
|
if(ret != OK){
|
||||||
|
std::cout << "Could not open calibration file" << calfname << endl;
|
||||||
|
setErrorMask((getErrorMask())|(SETTINGS_FILE_NOT_OPEN));
|
||||||
|
return thisDetector->currentSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//if everything worked, set module****
|
//if everything worked, set module****
|
||||||
setModule(*myMod,iodelay,tau,-1,gainval,offsetval);
|
setModule(*myMod,iodelay,tau,-1,gainval,offsetval);
|
||||||
@ -4058,7 +3929,6 @@ slsDetectorDefs::detectorSettings slsDetector::setSettings( detectorSettings ise
|
|||||||
if(gainval) delete [] gainval;
|
if(gainval) delete [] gainval;
|
||||||
if(offsetval) delete [] offsetval;
|
if(offsetval) delete [] offsetval;
|
||||||
|
|
||||||
if (thisDetector->myDetectorType==MYTHEN){
|
|
||||||
if (thisDetector->correctionMask&(1<<RATE_CORRECTION)) {
|
if (thisDetector->correctionMask&(1<<RATE_CORRECTION)) {
|
||||||
int isett=getSettings(imod);
|
int isett=getSettings(imod);
|
||||||
double t[]=defaultTDead;
|
double t[]=defaultTDead;
|
||||||
@ -4066,7 +3936,7 @@ slsDetectorDefs::detectorSettings slsDetector::setSettings( detectorSettings ise
|
|||||||
thisDetector->tDead=t[isett];
|
thisDetector->tDead=t[isett];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (getSettings(imod) != isettings){
|
if (getSettings(imod) != isettings){
|
||||||
std::cout << "Could not set settings" << endl;
|
std::cout << "Could not set settings" << endl;
|
||||||
@ -4074,7 +3944,7 @@ slsDetectorDefs::detectorSettings slsDetector::setSettings( detectorSettings ise
|
|||||||
}
|
}
|
||||||
|
|
||||||
return thisDetector->currentSettings;
|
return thisDetector->currentSettings;
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -4093,6 +3963,42 @@ int slsDetector::getChanRegs(double* retval,bool fromDetector){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
slsDetectorDefs::detectorSettings slsDetector::sendSettingsOnly(detectorSettings isettings, int imod) {
|
||||||
|
int fnum = F_SET_SETTINGS;
|
||||||
|
int ret = FAIL;
|
||||||
|
char mess[MAX_STR_LENGTH];
|
||||||
|
memset(mess, 0, MAX_STR_LENGTH);
|
||||||
|
int retval = -1;
|
||||||
|
int arg[2];
|
||||||
|
arg[0] = isettings;
|
||||||
|
arg[1] = imod;
|
||||||
|
#ifdef VERBOSE
|
||||||
|
std::cout<< "Setting settings of module " << arg[1] << " to " << arg[0] << std::endl;
|
||||||
|
#endif
|
||||||
|
if (thisDetector->onlineFlag==ONLINE_FLAG) {
|
||||||
|
if (connectControl() == OK){
|
||||||
|
controlSocket->SendDataOnly(&fnum,sizeof(fnum));
|
||||||
|
controlSocket->SendDataOnly(arg,sizeof(arg));
|
||||||
|
controlSocket->ReceiveDataOnly(&ret,sizeof(ret));
|
||||||
|
if (ret==FAIL) {
|
||||||
|
controlSocket->ReceiveDataOnly(mess,sizeof(mess));
|
||||||
|
std::cout<< "Detector returned error: " << mess << std::endl;
|
||||||
|
setErrorMask((getErrorMask())|(SETTINGS_NOT_SET));
|
||||||
|
} else{
|
||||||
|
controlSocket->ReceiveDataOnly(&retval,sizeof(retval));
|
||||||
|
thisDetector->currentSettings = (detectorSettings)retval;
|
||||||
|
#ifdef VERBOSE
|
||||||
|
std::cout<< "Settings are " << retval << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
disconnectControl();
|
||||||
|
if (ret==FORCE_UPDATE)
|
||||||
|
updateDetector();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return thisDetector->currentSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int slsDetector::updateDetectorNoWait() {
|
int slsDetector::updateDetectorNoWait() {
|
||||||
|
|
||||||
|
@ -1105,7 +1105,7 @@ class slsDetector : public slsDetectorUtils, public energyConversion {
|
|||||||
/**
|
/**
|
||||||
get detector settings
|
get detector settings
|
||||||
\param imod module number (-1 all)
|
\param imod module number (-1 all)
|
||||||
\returns current settings
|
\returns current settings detectorSettings sendSettingsOnly(detectorSettings isettings);
|
||||||
*/
|
*/
|
||||||
detectorSettings getSettings(int imod=-1);
|
detectorSettings getSettings(int imod=-1);
|
||||||
|
|
||||||
@ -1118,6 +1118,19 @@ class slsDetector : public slsDetectorUtils, public energyConversion {
|
|||||||
in this function trimbits/settings and calibration files are searched in the settingsDir and calDir directories and the detector is initialized
|
in this function trimbits/settings and calibration files are searched in the settingsDir and calDir directories and the detector is initialized
|
||||||
*/
|
*/
|
||||||
detectorSettings setSettings(detectorSettings isettings, int imod=-1);
|
detectorSettings setSettings(detectorSettings isettings, int imod=-1);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
send detector settings only (set only for Jungfrau, Gotthard, Moench, get for all)
|
||||||
|
\param isettings settings
|
||||||
|
\param imod module number (-1 all)
|
||||||
|
\returns current settings
|
||||||
|
|
||||||
|
in this function only the settings is sent to the detector, where it will initialize all the dacs already stored in the detector server.
|
||||||
|
*/
|
||||||
|
detectorSettings sendSettingsOnly(detectorSettings isettings, int imod=-1);
|
||||||
|
|
||||||
|
|
||||||
//virtual detectorSettings setSettings(detectorSettings isettings, int imod=-1);
|
//virtual detectorSettings setSettings(detectorSettings isettings, int imod=-1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4652,7 +4652,10 @@ string slsDetectorCommand::cmdSettings(int narg, char *args[], int action) {
|
|||||||
if (cmd=="settings") {
|
if (cmd=="settings") {
|
||||||
detectorSettings sett = GET_SETTINGS;
|
detectorSettings sett = GET_SETTINGS;
|
||||||
if (action==PUT_ACTION) {
|
if (action==PUT_ACTION) {
|
||||||
sett = myDet->setSettings(myDet->getDetectorSettings(string(args[1])));
|
sett = myDet->getDetectorSettings(string(args[1]));
|
||||||
|
if (sett == -1)
|
||||||
|
return string ("unknown settings scanned " + string(args[1]));
|
||||||
|
sett = myDet->setSettings(sett);
|
||||||
if (myDet->getDetectorsType() == EIGER) {
|
if (myDet->getDetectorsType() == EIGER) {
|
||||||
return myDet->getDetectorSettings(sett);
|
return myDet->getDetectorSettings(sett);
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,9 @@ void getModuleConfiguration();
|
|||||||
// set up detector
|
// set up detector
|
||||||
void allocateDetectorStructureMemory();
|
void allocateDetectorStructureMemory();
|
||||||
void setupDetector();
|
void setupDetector();
|
||||||
|
#ifdef JUNGFRAUD
|
||||||
|
int setDefaultDacs();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// advanced read/write reg
|
// advanced read/write reg
|
||||||
|
@ -2272,20 +2272,19 @@ int set_settings(int file_des) {
|
|||||||
sprintf(mess,"set settings failed\n");
|
sprintf(mess,"set settings failed\n");
|
||||||
|
|
||||||
#ifdef MYTHEN3D
|
#ifdef MYTHEN3D
|
||||||
//to receive any arguments
|
//to receive any arguments
|
||||||
while (n > 0)
|
while (n > 0)
|
||||||
n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER);
|
n = receiveData(file_des,mess,MAX_STR_LENGTH,OTHER);
|
||||||
ret = FAIL;
|
ret = FAIL;
|
||||||
sprintf(mess,"Function (Set Settings) is not implemented for this detector\n");
|
sprintf(mess,"Function (Set Settings) is not implemented for this detector\n");
|
||||||
cprintf(RED, "Warning: %s", mess);
|
cprintf(RED, "Warning: %s", mess);
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|
||||||
// receive arguments
|
// receive arguments
|
||||||
n = receiveData(file_des,&arg,sizeof(arg),INT32);
|
n = receiveData(file_des,&arg,sizeof(arg),INT32);
|
||||||
if (n < 0) return printSocketReadError();
|
if (n < 0) return printSocketReadError();
|
||||||
imod=arg[1];
|
|
||||||
isett=arg[0];
|
isett=arg[0];
|
||||||
|
imod=arg[1];
|
||||||
|
|
||||||
// execute action
|
// execute action
|
||||||
if (differentClients && lockStatus && isett!=GET_SETTINGS) {
|
if (differentClients && lockStatus && isett!=GET_SETTINGS) {
|
||||||
@ -2294,20 +2293,57 @@ int set_settings(int file_des) {
|
|||||||
cprintf(RED, "Warning: %s", mess);
|
cprintf(RED, "Warning: %s", mess);
|
||||||
}
|
}
|
||||||
#ifdef SLS_DETECTOR_FUNCTION_LIST
|
#ifdef SLS_DETECTOR_FUNCTION_LIST
|
||||||
else if (imod>=getTotalNumberOfModules()) {
|
|
||||||
|
#ifdef MYTHEND
|
||||||
|
if ( (ret != FAIL) && (imod>=getTotalNumberOfModules())) {
|
||||||
ret = FAIL;
|
ret = FAIL;
|
||||||
sprintf(mess,"Module number %d out of range\n",imod);
|
sprintf(mess,"Module number %d out of range\n",imod);
|
||||||
cprintf(RED, "Warning: %s", mess);
|
cprintf(RED, "Warning: %s", mess);
|
||||||
}
|
}
|
||||||
else {
|
#endif
|
||||||
|
switch(isett) {
|
||||||
|
case GET_SETTINGS:
|
||||||
|
case UNINITIALIZED:
|
||||||
|
#ifdef JUNGFRAUD
|
||||||
|
case DYNAMICGAIN:
|
||||||
|
case DYNAMICHG0:
|
||||||
|
case FIXGAIN1:
|
||||||
|
case FIXGAIN2:
|
||||||
|
case FORCESWITCHG1:
|
||||||
|
case FORCESWITCHG2:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret = FAIL;
|
||||||
|
sprintf(mess,"Setting (%d) is not implemented for this detector.\n"
|
||||||
|
"Options are dynamicgain, dynamichg0, fixgain1, fixgain2, "
|
||||||
|
"forceswitchg1 and forceswitchg2.\n", isett);
|
||||||
|
cprintf(RED, "Warning: %s", mess);
|
||||||
|
break;
|
||||||
|
// other detectors
|
||||||
|
// #elif GOTTHARDD, MOENCHD, PROPIXD
|
||||||
|
#else
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret = FAIL;
|
||||||
|
#ifdef EIGERD
|
||||||
|
sprintf(mess,"Cannot set settings via SET_SETTINGS, use SET_MODULE\n");
|
||||||
|
#else
|
||||||
|
sprintf(mess,"Setting (%d) is not implemented for this detector\n", isett);
|
||||||
|
#endif
|
||||||
|
cprintf(RED, "Warning: %s", mess);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret != FAIL) {
|
||||||
#ifdef VERBOSE
|
#ifdef VERBOSE
|
||||||
printf("Changing settings of module %d to %d\n", imod, isett);
|
printf("Changing settings of module %d to %d\n", imod, isett);
|
||||||
#endif
|
#endif
|
||||||
retval=setSettings(isett, imod);
|
retval=setSettings(isett, imod);
|
||||||
#ifdef VERBOSE
|
#ifdef VERBOSE
|
||||||
printf("Settings changed to %d\n", isett);
|
printf("Settings changed to %d\n", isett);
|
||||||
#endif
|
#endif
|
||||||
if (retval==isett || isett<0) {
|
if (retval == isett || isett < 0) {
|
||||||
ret=OK;
|
ret=OK;
|
||||||
} else {
|
} else {
|
||||||
ret = FAIL;
|
ret = FAIL;
|
||||||
@ -2315,6 +2351,17 @@ int set_settings(int file_des) {
|
|||||||
cprintf(RED, "Warning: %s", mess);
|
cprintf(RED, "Warning: %s", mess);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// set to default dacs,
|
||||||
|
//# also for #elif GOTTHARDD, MOENCHD, PROPIXD
|
||||||
|
#ifdef JUNGFRAUD
|
||||||
|
if (ret == OK && isett >= 0) {
|
||||||
|
ret = setDefaultDacs();
|
||||||
|
if (ret == FAIL) {
|
||||||
|
strcpy(mess,"Could change settings, but could not set to default dacs\n");
|
||||||
|
cprintf(RED, "Warning: %s", mess);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user