mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-04-26 16:20:03 +02:00
maybe fixed 16 bit rate corr eiger
This commit is contained in:
parent
1b61e10e36
commit
5f4a4b0d90
@ -61,6 +61,7 @@ using namespace std;
|
|||||||
#define DETECTOR_NETWORK_PARAMETER 0x0000000000400000ULL
|
#define DETECTOR_NETWORK_PARAMETER 0x0000000000400000ULL
|
||||||
#define RATE_CORRECTION_NOT_32or16BIT 0x0000000000800000ULL
|
#define RATE_CORRECTION_NOT_32or16BIT 0x0000000000800000ULL
|
||||||
#define RATE_CORRECTION_NO_TAU_PROVIDED 0x0000000001000000ULL
|
#define RATE_CORRECTION_NO_TAU_PROVIDED 0x0000000001000000ULL
|
||||||
|
#define PROGRAMMING_ERROR 0x0000000002000000ULL
|
||||||
|
|
||||||
// 0x00000000FFFFFFFFULL
|
// 0x00000000FFFFFFFFULL
|
||||||
/** @short class returning all error messages for error mask */
|
/** @short class returning all error messages for error mask */
|
||||||
@ -198,6 +199,8 @@ public:
|
|||||||
if(slsErrorMask&RATE_CORRECTION_NO_TAU_PROVIDED)
|
if(slsErrorMask&RATE_CORRECTION_NO_TAU_PROVIDED)
|
||||||
retval.append("Rate correction Deactivated. No default tau provided in file\n");
|
retval.append("Rate correction Deactivated. No default tau provided in file\n");
|
||||||
|
|
||||||
|
if(slsErrorMask&PROGRAMMING_ERROR)
|
||||||
|
retval.append("Could not program FPGA\n");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -50,8 +50,7 @@ int64_t Feb_Control_subframe_exposure_time_in_10nsec;
|
|||||||
double Feb_Control_exposure_period_in_sec;
|
double Feb_Control_exposure_period_in_sec;
|
||||||
|
|
||||||
int64_t Feb_Control_RateTable_Tau_in_nsec = -1;
|
int64_t Feb_Control_RateTable_Tau_in_nsec = -1;
|
||||||
int64_t Feb_Control_RateTable_Subexptime_in_nsec = -1;
|
int64_t Feb_Control_RateTable_Period_in_nsec = -1;
|
||||||
int64_t Feb_Control_RateTable_Exptime_in_nsec = -1;
|
|
||||||
|
|
||||||
unsigned int Feb_Control_trimbit_size;
|
unsigned int Feb_Control_trimbit_size;
|
||||||
unsigned int* Feb_Control_last_downloaded_trimbits;
|
unsigned int* Feb_Control_last_downloaded_trimbits;
|
||||||
@ -1791,35 +1790,33 @@ int Feb_Control_PulseChip(int npulses){
|
|||||||
|
|
||||||
|
|
||||||
int64_t Feb_Control_Get_RateTable_Tau_in_nsec(){ return Feb_Control_RateTable_Tau_in_nsec;}
|
int64_t Feb_Control_Get_RateTable_Tau_in_nsec(){ return Feb_Control_RateTable_Tau_in_nsec;}
|
||||||
int64_t Feb_Control_Get_RateTable_Subexptime_in_nsec(){ return Feb_Control_RateTable_Subexptime_in_nsec;}
|
int64_t Feb_Control_Get_RateTable_Period_in_nsec(){ return Feb_Control_RateTable_Period_in_nsec;}
|
||||||
int64_t Feb_Control_Get_RateTable_Exptime_in_nsec(){ return Feb_Control_RateTable_Exptime_in_nsec;}
|
|
||||||
|
|
||||||
//returns -1 if slope is too high
|
//returns -1 if slope is too high
|
||||||
int Feb_Control_SetRateCorrectionTau(int64_t tau_in_Nsec){
|
int Feb_Control_SetRateCorrectionTau(int64_t tau_in_Nsec){
|
||||||
|
|
||||||
double exptime_in_sec = Feb_Control_GetExposureTime();
|
//period = exptime if 16bit, period = subexptime if 32 bit
|
||||||
double sub_expure_time_in_sec = (double)(Feb_Control_GetSubFrameExposureTime())/(double)1e9;
|
|
||||||
|
|
||||||
|
|
||||||
int dr = Feb_Control_GetDynamicRange();
|
int dr = Feb_Control_GetDynamicRange();
|
||||||
double period_in_sec = sub_expure_time_in_sec;
|
double period_in_sec = (double)(Feb_Control_GetSubFrameExposureTime())/(double)1e9;
|
||||||
if(dr == 16)
|
if(dr == 16)
|
||||||
period_in_sec = exptime_in_sec;
|
period_in_sec = Feb_Control_GetExposureTime();
|
||||||
|
|
||||||
|
|
||||||
double tau_in_sec = (double)tau_in_Nsec/(double)1e9;
|
double tau_in_sec = (double)tau_in_Nsec/(double)1e9;
|
||||||
unsigned int np = 16384; //max slope 16 * 1024
|
unsigned int np = 16384; //max slope 16 * 1024
|
||||||
double b0[1024];
|
double b0[1024];
|
||||||
double m[1024];
|
double m[1024];
|
||||||
|
|
||||||
|
|
||||||
if(tau_in_sec<0||period_in_sec<0){
|
if(tau_in_sec<0||period_in_sec<0){
|
||||||
if(dr == 32)
|
if(dr == 32)
|
||||||
printf("Error tau %f and sub_exposure_time %f must be greater than 0.\n", tau_in_sec, sub_expure_time_in_sec);
|
printf("Error tau %f and sub_exposure_time %f must be greater than 0.\n", tau_in_sec, period_in_sec);
|
||||||
else
|
else
|
||||||
printf("Error tau %f and exposure_time %f must be greater than 0.\n", tau_in_sec, exptime_in_sec);
|
printf("Error tau %f and exposure_time %f must be greater than 0.\n", tau_in_sec, period_in_sec);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cprintf(BLUE, "Changing Rate Correction Table tau:%f sec, period:%f sec",tau_in_sec,period_in_sec);
|
||||||
|
|
||||||
printf("\tCalculating table for tau of %lld ns.\n", tau_in_Nsec);
|
printf("\tCalculating table for tau of %lld ns.\n", tau_in_Nsec);
|
||||||
int i;
|
int i;
|
||||||
for(i=0;i<np;i++)
|
for(i=0;i<np;i++)
|
||||||
@ -1902,18 +1899,11 @@ int Feb_Control_SetRateCorrectionTau(int64_t tau_in_Nsec){
|
|||||||
|
|
||||||
if(Feb_Control_SetRateCorrectionTable(Feb_Control_rate_correction_table)){
|
if(Feb_Control_SetRateCorrectionTable(Feb_Control_rate_correction_table)){
|
||||||
Feb_Control_RateTable_Tau_in_nsec = tau_in_Nsec;
|
Feb_Control_RateTable_Tau_in_nsec = tau_in_Nsec;
|
||||||
if(dr == 32){
|
Feb_Control_RateTable_Period_in_nsec = period_in_sec;
|
||||||
Feb_Control_RateTable_Subexptime_in_nsec = Feb_Control_GetSubFrameExposureTime();
|
|
||||||
Feb_Control_RateTable_Exptime_in_nsec = -1;
|
|
||||||
}else{
|
|
||||||
Feb_Control_RateTable_Exptime_in_nsec = Feb_Control_GetExposureTime_in_nsec();
|
|
||||||
Feb_Control_RateTable_Subexptime_in_nsec = -1;
|
|
||||||
}
|
|
||||||
return 1;
|
return 1;
|
||||||
}else{
|
}else{
|
||||||
Feb_Control_RateTable_Tau_in_nsec = -1;
|
Feb_Control_RateTable_Tau_in_nsec = -1;
|
||||||
Feb_Control_RateTable_Subexptime_in_nsec = -1;
|
Feb_Control_RateTable_Period_in_nsec = -1;
|
||||||
Feb_Control_RateTable_Exptime_in_nsec = -1;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1966,7 +1956,7 @@ int Feb_Control_GetRateCorrectionVariable(){ return (Feb_Control_subFrameMode&DA
|
|||||||
void Feb_Control_SetRateCorrectionVariable(int activate_rate_correction){
|
void Feb_Control_SetRateCorrectionVariable(int activate_rate_correction){
|
||||||
if(activate_rate_correction){
|
if(activate_rate_correction){
|
||||||
Feb_Control_subFrameMode |= DAQ_NEXPOSURERS_ACTIVATE_RATE_CORRECTION;
|
Feb_Control_subFrameMode |= DAQ_NEXPOSURERS_ACTIVATE_RATE_CORRECTION;
|
||||||
printf("Rate correction activated. Note: the rate correction applied only when run in auto summing mode.\n");
|
printf("Rate correction activated.\n");
|
||||||
}else{
|
}else{
|
||||||
Feb_Control_subFrameMode &= ~DAQ_NEXPOSURERS_ACTIVATE_RATE_CORRECTION;
|
Feb_Control_subFrameMode &= ~DAQ_NEXPOSURERS_ACTIVATE_RATE_CORRECTION;
|
||||||
printf("Rate correction deactivated.\n");
|
printf("Rate correction deactivated.\n");
|
||||||
|
@ -186,8 +186,7 @@ int Feb_Control_GetModuleNumber();
|
|||||||
int Feb_Control_PulseChip(int npulses);
|
int Feb_Control_PulseChip(int npulses);
|
||||||
|
|
||||||
int64_t Feb_Control_Get_RateTable_Tau_in_nsec();
|
int64_t Feb_Control_Get_RateTable_Tau_in_nsec();
|
||||||
int64_t Feb_Control_Get_RateTable_Subexptime_in_nsec();
|
int64_t Feb_Control_Get_RateTable_Period_in_nsec();
|
||||||
int64_t Feb_Control_Get_RateTable_Exptime_in_nsec();
|
|
||||||
int Feb_Control_SetRateCorrectionTau(int64_t tau_in_Nsec);
|
int Feb_Control_SetRateCorrectionTau(int64_t tau_in_Nsec);
|
||||||
int Feb_Control_SetRateCorrectionTable(unsigned int *table);
|
int Feb_Control_SetRateCorrectionTable(unsigned int *table);
|
||||||
int Feb_Control_GetRateCorrectionVariable();
|
int Feb_Control_GetRateCorrectionVariable();
|
||||||
|
Binary file not shown.
@ -537,16 +537,16 @@ int64_t setRateCorrection(int64_t custom_tau_in_nsec){//in nanosec (will never b
|
|||||||
else if(custom_tau_in_nsec == -1)
|
else if(custom_tau_in_nsec == -1)
|
||||||
custom_tau_in_nsec = Feb_Control_Get_RateTable_Tau_in_nsec();
|
custom_tau_in_nsec = Feb_Control_Get_RateTable_Tau_in_nsec();
|
||||||
|
|
||||||
int64_t tau_in_nsec = Feb_Control_Get_RateTable_Tau_in_nsec();
|
|
||||||
int dr = Feb_Control_GetDynamicRange();
|
int dr = Feb_Control_GetDynamicRange();
|
||||||
//default for 32 bit
|
//get period = subexptime if 32bit , else period = exptime if 16 bit
|
||||||
int64_t ratetable_period_in_nsec = Feb_Control_Get_RateTable_Subexptime_in_nsec();
|
|
||||||
int64_t actual_period = Feb_Control_GetSubFrameExposureTime(); //already in nsec
|
int64_t actual_period = Feb_Control_GetSubFrameExposureTime(); //already in nsec
|
||||||
//16 bit mode
|
if(dr == 16)
|
||||||
if(dr == 16){
|
|
||||||
ratetable_period_in_nsec = Feb_Control_Get_RateTable_Exptime_in_nsec();
|
|
||||||
actual_period = Feb_Control_GetExposureTime_in_nsec();
|
actual_period = Feb_Control_GetExposureTime_in_nsec();
|
||||||
}
|
|
||||||
|
int64_t ratetable_period_in_nsec = Feb_Control_Get_RateTable_Period_in_nsec();
|
||||||
|
int64_t tau_in_nsec = Feb_Control_Get_RateTable_Tau_in_nsec();
|
||||||
|
|
||||||
|
|
||||||
//same setting
|
//same setting
|
||||||
if((tau_in_nsec == custom_tau_in_nsec) && (ratetable_period_in_nsec == actual_period)){
|
if((tau_in_nsec == custom_tau_in_nsec) && (ratetable_period_in_nsec == actual_period)){
|
||||||
|
@ -3949,6 +3949,21 @@ int multiSlsDetector::executeTrimming(trimMode mode, int par1, int par2, int imo
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int multiSlsDetector::programFPGA(string fname){
|
||||||
|
int ret=OK, ret1=OK;
|
||||||
|
|
||||||
|
for (int i=0; i<thisMultiDetector->numberOfDetectors; i++) {
|
||||||
|
if (detectors[i]) {
|
||||||
|
ret=detectors[i]->programFPGA(fname);
|
||||||
|
if(detectors[i]->getErrorMask())
|
||||||
|
setErrorMask(getErrorMask()|(1<<i));
|
||||||
|
if (ret!=OK)
|
||||||
|
ret1=FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int multiSlsDetector::loadSettingsFile(string fname, int imod) {
|
int multiSlsDetector::loadSettingsFile(string fname, int imod) {
|
||||||
|
@ -488,6 +488,11 @@ class multiSlsDetector : public slsDetectorUtils {
|
|||||||
|
|
||||||
int decodeNMod(int i, int &idet, int &imod);
|
int decodeNMod(int i, int &idet, int &imod);
|
||||||
|
|
||||||
|
/** programs FPGA with pof file
|
||||||
|
\param fname file name
|
||||||
|
\returns OK or FAIL
|
||||||
|
*/
|
||||||
|
int programFPGA(string fname);
|
||||||
|
|
||||||
/** loads the modules settings/trimbits reading from a file - file name extension is automatically generated! */
|
/** loads the modules settings/trimbits reading from a file - file name extension is automatically generated! */
|
||||||
int loadSettingsFile(string fname, int nmod=0);
|
int loadSettingsFile(string fname, int nmod=0);
|
||||||
|
@ -6382,6 +6382,70 @@ int slsDetector::writeSettingsFile(string fname, int imod, int* iodelay){
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int slsDetector::programFPGA(string fname){
|
||||||
|
|
||||||
|
if(thisDetector->myDetectorType != EIGER){/**jungfrau*/
|
||||||
|
std::cout << "Not implemented for this detector" << std::endl;
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//check if it exists
|
||||||
|
struct stat st;
|
||||||
|
if(stat(fname.c_str(),&st)){
|
||||||
|
std::cout << "Programming file does not exist" << endl;
|
||||||
|
setErrorMask((getErrorMask())|(PROGRAMMING_ERROR));
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//convert it to rawbin
|
||||||
|
string destfname = fname;
|
||||||
|
destfname.replace(destfname.end()-4,destfname.end(),".rawbin"); //replace .pof with .rawbin
|
||||||
|
//#ifdef VERBOSE
|
||||||
|
std::cout << "Converting " << fname << " to " << destfname << std::endl;
|
||||||
|
//#endif
|
||||||
|
int filepos,x,y,i;
|
||||||
|
FILE* src = fopen(fname.c_str(),"rb");
|
||||||
|
FILE* dst = fopen(destfname.c_str(),"wb");
|
||||||
|
// Remove header (0...11C)
|
||||||
|
for (filepos=0; filepos < 0x11C; filepos++)
|
||||||
|
fgetc(src);
|
||||||
|
// Write 0x80 times 0xFF (0...7F)
|
||||||
|
for (filepos=0; filepos < 0x80; filepos++)
|
||||||
|
fputc(0xFF,dst);
|
||||||
|
// Swap bits and write to file
|
||||||
|
for (filepos=0x80; filepos < 0x1000000; filepos++) {
|
||||||
|
x = fgetc(src);
|
||||||
|
if (x < 0) break;
|
||||||
|
|
||||||
|
y=0;
|
||||||
|
for (i=0; i < 8; i++)
|
||||||
|
y=y| ( (( x & (1<<i) ) >> i) << (7-i) ); // This swaps the bits
|
||||||
|
|
||||||
|
fputc(y,dst);
|
||||||
|
}
|
||||||
|
if (filepos < 0x1000000){
|
||||||
|
std::cout << "ERROR: EOF before end of flash" << std::endl;
|
||||||
|
setErrorMask((getErrorMask())|(PROGRAMMING_ERROR));
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
//#ifdef VERBOSE
|
||||||
|
std::cout << "File has been converted to " << destfname << ". Sending it to /tftpboot" << std::endl;
|
||||||
|
//#endif
|
||||||
|
string onlyfilename = destfname;
|
||||||
|
size_t foundSlash = onlyfilename.rfind('/');
|
||||||
|
if(foundSlash != string::npos)
|
||||||
|
onlyfilename.erase(onlyfilename.begin(),onlyfilename.begin()+foundSlash+1);
|
||||||
|
cout<<"\nonly file name:"<<onlyfilename<<endl;
|
||||||
|
|
||||||
|
//string message = "cp " + destfname
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int slsDetector::loadSettingsFile(string fname, int imod) {
|
int slsDetector::loadSettingsFile(string fname, int imod) {
|
||||||
|
|
||||||
sls_detector_module *myMod=NULL;
|
sls_detector_module *myMod=NULL;
|
||||||
|
@ -522,6 +522,11 @@ class slsDetector : public slsDetectorUtils, public energyConversion {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** programs FPGA with pof file
|
||||||
|
\param fname file name
|
||||||
|
\returns OK or FAIL
|
||||||
|
*/
|
||||||
|
int programFPGA(string fname);
|
||||||
|
|
||||||
/** loads the modules settings/trimbits reading from a file
|
/** loads the modules settings/trimbits reading from a file
|
||||||
\param fname file name . If not specified, extension is automatically generated!
|
\param fname file name . If not specified, extension is automatically generated!
|
||||||
|
@ -441,6 +441,10 @@ slsDetectorCommand::slsDetectorCommand(slsDetectorUtils *det) {
|
|||||||
descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdAdvanced;
|
descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdAdvanced;
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
|
descrToFuncMap[i].m_pFuncName="programfpga";
|
||||||
|
descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdAdvanced;
|
||||||
|
i++;
|
||||||
|
|
||||||
/* versions/ serial numbers getId */
|
/* versions/ serial numbers getId */
|
||||||
|
|
||||||
descrToFuncMap[i].m_pFuncName="moduleversion"; //
|
descrToFuncMap[i].m_pFuncName="moduleversion"; //
|
||||||
@ -4259,8 +4263,8 @@ string slsDetectorCommand::helpSpeed(int narg, char *args[], int action) {
|
|||||||
|
|
||||||
string slsDetectorCommand::cmdAdvanced(int narg, char *args[], int action) {
|
string slsDetectorCommand::cmdAdvanced(int narg, char *args[], int action) {
|
||||||
|
|
||||||
int retval;
|
int retval;
|
||||||
char answer[1000]="";
|
char answer[1000]="";
|
||||||
|
|
||||||
if (action==HELP_ACTION)
|
if (action==HELP_ACTION)
|
||||||
return helpAdvanced(narg, args, action);
|
return helpAdvanced(narg, args, action);
|
||||||
@ -4331,7 +4335,24 @@ char answer[1000]="";
|
|||||||
|
|
||||||
return myDet->externalSignalType(myDet->setExternalSignalFlags(flag,is));
|
return myDet->externalSignalType(myDet->setExternalSignalFlags(flag,is));
|
||||||
|
|
||||||
} else
|
} else if (cmd=="programfpga") {
|
||||||
|
if (action==GET_ACTION)
|
||||||
|
return string("cannot get");
|
||||||
|
|
||||||
|
if (narg<2)
|
||||||
|
return string("wrong usage: should specify programming file");
|
||||||
|
if(strstr(args[1],".pof")==NULL)
|
||||||
|
return string("wrong usage: should specify programming file with .pof extension");
|
||||||
|
|
||||||
|
string sval=string(args[1]);
|
||||||
|
#ifdef VERBOSE
|
||||||
|
std::cout<< " programming file " << sval << std::endl;
|
||||||
|
#endif
|
||||||
|
if(myDet->programFPGA(sval) == OK)
|
||||||
|
return string("programming successful");
|
||||||
|
return string("programming unsuccessful");
|
||||||
|
}
|
||||||
|
else
|
||||||
return string("could not decode flag ")+cmd;
|
return string("could not decode flag ")+cmd;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -4344,6 +4365,7 @@ string slsDetectorCommand::helpAdvanced(int narg, char *args[], int action) {
|
|||||||
|
|
||||||
os << "extsig:i mode \t sets the mode of the external signal i. can be \n \t \t \t off, \n \t \t \t gate_in_active_high, \n \t \t \t gate_in_active_low, \n \t \t \t trigger_in_rising_edge, \n \t \t \t trigger_in_falling_edge, \n \t \t \t ro_trigger_in_rising_edge, \n \t \t \t ro_trigger_in_falling_edge, \n \t \t \t gate_out_active_high, \n \t \t \t gate_out_active_low, \n \t \t \t trigger_out_rising_edge, \n \t \t \t trigger_out_falling_edge, \n \t \t \t ro_trigger_out_rising_edge, \n \t \t \t ro_trigger_out_falling_edge" << std::endl;
|
os << "extsig:i mode \t sets the mode of the external signal i. can be \n \t \t \t off, \n \t \t \t gate_in_active_high, \n \t \t \t gate_in_active_low, \n \t \t \t trigger_in_rising_edge, \n \t \t \t trigger_in_falling_edge, \n \t \t \t ro_trigger_in_rising_edge, \n \t \t \t ro_trigger_in_falling_edge, \n \t \t \t gate_out_active_high, \n \t \t \t gate_out_active_low, \n \t \t \t trigger_out_rising_edge, \n \t \t \t trigger_out_falling_edge, \n \t \t \t ro_trigger_out_rising_edge, \n \t \t \t ro_trigger_out_falling_edge" << std::endl;
|
||||||
os << "flags mode \t sets the readout flags to mode. can be none, storeinram, tot, continous, parallel, nonparallel, safe, unknown" << std::endl;
|
os << "flags mode \t sets the readout flags to mode. can be none, storeinram, tot, continous, parallel, nonparallel, safe, unknown" << std::endl;
|
||||||
|
os << "programfpga f \t programs the fpga with file f with .pof" << std::endl;
|
||||||
|
|
||||||
}
|
}
|
||||||
if (action==GET_ACTION || action==HELP_ACTION) {
|
if (action==GET_ACTION || action==HELP_ACTION) {
|
||||||
|
@ -491,6 +491,12 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing {
|
|||||||
*/
|
*/
|
||||||
virtual int loadSettingsFile(string fname, int imod=-1)=0;
|
virtual int loadSettingsFile(string fname, int imod=-1)=0;
|
||||||
|
|
||||||
|
/** programs FPGA with pof file
|
||||||
|
\param fname file name
|
||||||
|
\returns OK or FAIL
|
||||||
|
*/
|
||||||
|
virtual int programFPGA(string fname)=0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** saves the modules settings/trimbits writing to a file
|
/** saves the modules settings/trimbits writing to a file
|
||||||
|
Loading…
x
Reference in New Issue
Block a user