mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-04-22 14:38:14 +02:00
fix merge
This commit is contained in:
commit
33efd42bdc
Binary file not shown.
@ -50,9 +50,7 @@ int dacValues[NDAC] = {0};
|
||||
int vLimit = 0;
|
||||
|
||||
int highvoltage = 0;
|
||||
ROI rois[MAX_ROIS];
|
||||
int nROI = 0;
|
||||
uint32_t adcDisableMask = 0;
|
||||
uint32_t adcEnableMask = 0;
|
||||
int analogEnable = 1;
|
||||
int digitalEnable = 0;
|
||||
int nSamples = 1;
|
||||
@ -474,8 +472,7 @@ void setupDetector() {
|
||||
}
|
||||
vLimit = DEFAULT_VLIMIT;
|
||||
highvoltage = 0;
|
||||
nROI = 0;
|
||||
adcDisableMask = 0;
|
||||
adcEnableMask = BIT_32_MSK;
|
||||
analogEnable = 1;
|
||||
digitalEnable = 0;
|
||||
nSamples = 1;
|
||||
@ -550,11 +547,8 @@ void setupDetector() {
|
||||
setTiming(DEFAULT_TIMING_MODE);
|
||||
setReadOutFlags(NORMAL_READOUT);
|
||||
|
||||
// clear roi
|
||||
{
|
||||
int ret = OK, retvalsize = 0;
|
||||
setROI(0, rois, &retvalsize, &ret);
|
||||
}
|
||||
// enable all ADC channels
|
||||
setADCEnableMask(BIT_32_MSK);
|
||||
}
|
||||
|
||||
int allocateRAM() {
|
||||
@ -606,12 +600,14 @@ int getChannels() {
|
||||
int nchans = 0;
|
||||
|
||||
if (analogEnable) {
|
||||
nchans += NCHAN_ANALOG;
|
||||
// remove the channels disabled
|
||||
if (adcEnableMask == BIT_32_MSK)
|
||||
nchans = 32;
|
||||
else {
|
||||
int ichan = 0;
|
||||
for (ichan = 0; ichan < NCHAN_ANALOG; ++ichan) {
|
||||
if (adcDisableMask & (1 << ichan))
|
||||
--nchans;
|
||||
if (adcEnableMask & (1 << ichan))
|
||||
++nchans;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (digitalEnable)
|
||||
@ -651,130 +647,31 @@ void resetPeripheral() {
|
||||
}
|
||||
|
||||
|
||||
/* set parameters - dr, roi */
|
||||
/* set parameters - dr, adcenablemask */
|
||||
|
||||
int setDynamicRange(int dr){
|
||||
return DYNAMIC_RANGE;
|
||||
}
|
||||
|
||||
ROI* setROI(int n, ROI arg[], int *retvalsize, int *ret) {
|
||||
uint32_t addr = ADC_DISABLE_REG;
|
||||
int setADCEnableMask(uint32_t mask) {
|
||||
FILE_LOG(logINFO, ("Setting adcEnableMask to 0x%08x\n", mask));
|
||||
adcEnableMask = mask;
|
||||
|
||||
// set ROI
|
||||
if(n >= 0) {
|
||||
// clear roi
|
||||
if (!n) {
|
||||
FILE_LOG(logINFO, ("Clearing ROI\n"));
|
||||
adcDisableMask = 0;
|
||||
}
|
||||
// set roi
|
||||
else {
|
||||
FILE_LOG(logINFO, ("Setting ROI:\n"));
|
||||
adcDisableMask = 0xffffffff;
|
||||
int iroi = 0;
|
||||
// for every roi
|
||||
for (iroi = 0; iroi < n; ++iroi) {
|
||||
FILE_LOG(logINFO, ("\t%d: (%d, %d)\n", iroi, arg[iroi].xmin, arg[iroi].xmax));
|
||||
// swap if xmin > xmax
|
||||
if (arg[iroi].xmin > arg[iroi].xmax) {
|
||||
int temp = arg[iroi].xmin;
|
||||
arg[iroi].xmin = arg[iroi].xmax;
|
||||
arg[iroi].xmax = temp;
|
||||
FILE_LOG(logINFORED, ("\tCorrected %d: (%d, %d)\n", iroi, arg[iroi].xmin, arg[iroi].xmax));
|
||||
}
|
||||
int ich = 0;
|
||||
// for the roi specified
|
||||
for (ich = arg[iroi].xmin; ich <= arg[iroi].xmax; ++ich) {
|
||||
// valid channel (disable)
|
||||
if (ich >= 0 && ich < NCHAN_ANALOG)
|
||||
adcDisableMask &= ~(1 << ich);
|
||||
// get disable mask
|
||||
mask ^= BIT_32_MSK;
|
||||
bus_w(ADC_DISABLE_REG, mask);
|
||||
|
||||
FILE_LOG(logDEBUG1, ("%d: ich:%d adcDisableMask:0x%08x\n",
|
||||
iroi, ich, adcDisableMask));
|
||||
}
|
||||
}
|
||||
}
|
||||
FILE_LOG(logINFO, ("\tSetting adcDisableMask to 0x%08x\n", adcDisableMask));
|
||||
bus_w(addr, adcDisableMask);
|
||||
}
|
||||
// update databytes and allocate ram
|
||||
return allocateRAM();
|
||||
}
|
||||
|
||||
// get roi
|
||||
adcDisableMask = bus_r(addr);
|
||||
FILE_LOG(logDEBUG1, ("Getting adcDisableMask: 0x%08x\n", adcDisableMask));
|
||||
uint32_t getADCEnableMask() {
|
||||
uint32_t retval = bus_r(ADC_DISABLE_REG);
|
||||
|
||||
nROI = 0;
|
||||
if (adcDisableMask) {
|
||||
int ich = 0;
|
||||
// loop through channels
|
||||
for (ich = 0; ich < NCHAN_ANALOG; ++ich) {
|
||||
// channel disabled
|
||||
if ((~adcDisableMask) & (1 << ich)) {
|
||||
// first channel
|
||||
if (ich == 0) {
|
||||
++nROI;
|
||||
rois[nROI - 1].xmin = ich;
|
||||
rois[nROI - 1].xmax = ich;
|
||||
rois[nROI - 1].ymin = -1;
|
||||
rois[nROI - 1].ymax = -1;
|
||||
}
|
||||
// not first channel
|
||||
else {
|
||||
// previous channel enabled (so increase roi)
|
||||
if ((adcDisableMask) & (1 << (ich - 1))) {
|
||||
++nROI;
|
||||
// max roi level
|
||||
if (nROI > MAX_ROIS) {
|
||||
nROI = -1;
|
||||
*ret = FAIL;
|
||||
FILE_LOG(logERROR, ("Max ROI reached!\n"));
|
||||
break;
|
||||
}
|
||||
rois[nROI - 1].xmin = ich;
|
||||
rois[nROI - 1].ymin = -1;
|
||||
rois[nROI - 1].ymax = -1;
|
||||
}
|
||||
// set max as current one each time
|
||||
rois[nROI - 1].xmax = ich;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// print
|
||||
if (!nROI) {
|
||||
FILE_LOG(logINFO, ("\tROI: None\n"));
|
||||
} else {
|
||||
FILE_LOG(logINFO, ("ROI:\n"));
|
||||
int i = 0;
|
||||
for (i = 0; i < nROI; ++i) {
|
||||
FILE_LOG(logINFO, ("\t%d: (%d, %d)\n", i, rois[i].xmin, rois[i].xmax));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// validate and update databytes
|
||||
if (n >= 0) {
|
||||
// validate
|
||||
if((n != 0) && ((arg[0].xmin != rois[0].xmin)||
|
||||
(arg[0].xmax != rois[0].xmax)||
|
||||
(arg[0].ymin != rois[0].ymin)||
|
||||
(arg[0].ymax != rois[0].ymax))) {
|
||||
*ret = FAIL;
|
||||
FILE_LOG(logERROR, ("\tCould not set given ROI\n"));
|
||||
}
|
||||
if(n != nROI) {
|
||||
*ret = FAIL;
|
||||
FILE_LOG(logERROR, ("\tCould not set or clear ROIs\n"));
|
||||
}
|
||||
// update databytes (now that mask is up to date from fpga) and allocate ram
|
||||
if (allocateRAM() == FAIL) {
|
||||
*ret = FAIL;
|
||||
nROI = -2;
|
||||
}
|
||||
}
|
||||
|
||||
*retvalsize = nROI;
|
||||
return rois;
|
||||
// get enable mask
|
||||
retval ^= BIT_32_MSK;
|
||||
adcEnableMask = retval;
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
@ -2369,8 +2266,8 @@ void readSample(int ns) {
|
||||
int ich = 0;
|
||||
for (ich = 0; ich < NCHAN_ANALOG; ++ich) {
|
||||
|
||||
// if channel is in ROI
|
||||
if ((1 << ich) & ~(adcDisableMask)) {
|
||||
// if channel is in enable mask
|
||||
if ((1 << ich) & (adcEnableMask)) {
|
||||
|
||||
// unselect channel
|
||||
bus_w(addr, bus_r(addr) & ~(DUMMY_FIFO_CHNNL_SLCT_MSK));
|
||||
|
@ -110,9 +110,13 @@ void resetPeripheral();
|
||||
|
||||
// parameters - dr, roi
|
||||
int setDynamicRange(int dr);
|
||||
#if defined(GOTTHARDD) || defined(CHIPTESTBOARDD) || defined(MOENCHD)
|
||||
#ifdef GOTTHARDD
|
||||
ROI* setROI(int n, ROI arg[], int *retvalsize, int *ret);
|
||||
#endif
|
||||
#if defined(CHIPTESTBOARDD) || defined(MOENCHD)
|
||||
int setADCEnableMask(uint32_t mask);
|
||||
uint32_t getADCEnableMask();
|
||||
#endif
|
||||
|
||||
// parameters - readout
|
||||
#if defined(CHIPTESTBOARDD) || defined(MOENCHD) || defined(JUNGFRAUD)
|
||||
|
@ -235,6 +235,8 @@ const char* getFunctionName(enum detFuncs func) {
|
||||
case F_DIGITAL_IO_DELAY: return "F_DIGITAL_IO_DELAY";
|
||||
case F_COPY_DET_SERVER: return "F_COPY_DET_SERVER";
|
||||
case F_REBOOT_CONTROLLER: return "F_REBOOT_CONTROLLER";
|
||||
case F_SET_ADC_ENABLE_MASK: return "F_SET_ADC_ENABLE_MASK";
|
||||
case F_GET_ADC_ENABLE_MASK: return "F_GET_ADC_ENABLE_MASK";
|
||||
|
||||
default: return "Unknown Function";
|
||||
}
|
||||
@ -312,6 +314,8 @@ void function_table() {
|
||||
flist[F_DIGITAL_IO_DELAY] = &digital_io_delay;
|
||||
flist[F_COPY_DET_SERVER] = ©_detector_server;
|
||||
flist[F_REBOOT_CONTROLLER] = &reboot_controller;
|
||||
flist[F_SET_ADC_ENABLE_MASK] = &set_adc_enable_mask;
|
||||
flist[F_GET_ADC_ENABLE_MASK] = &get_adc_enable_mask;
|
||||
|
||||
// check
|
||||
if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) {
|
||||
@ -1890,7 +1894,7 @@ int set_roi(int file_des) {
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(JUNGFRAUD) || defined(EIGERD)
|
||||
#ifndef GOTTHARDD
|
||||
functionNotImplemented();
|
||||
#else
|
||||
// set & get
|
||||
@ -2236,13 +2240,8 @@ int send_update(int file_des) {
|
||||
if (n < 0) return printSocketReadError();
|
||||
#endif
|
||||
|
||||
// #samples, roi
|
||||
#if defined(CHIPTESTBOARDD) || defined(MOENCHD) || defined(GOTTHARDD)
|
||||
i64 = setTimer(SAMPLES,GET_FLAG);
|
||||
n = sendData(file_des,&i64,sizeof(i64),INT64);
|
||||
if (n < 0) return printSocketReadError();
|
||||
|
||||
// roi
|
||||
#if defined(GOTTHARDD)
|
||||
ROI* retval = NULL;
|
||||
ROI arg[1];
|
||||
int ret = OK, nretval = 0;
|
||||
@ -2257,12 +2256,21 @@ int send_update(int file_des) {
|
||||
sendData(file_des, &retval[iloop].ymin, sizeof(int), INT32);
|
||||
sendData(file_des, &retval[iloop].ymax, sizeof(int), INT32);
|
||||
}
|
||||
#endif
|
||||
|
||||
// #samples, adcmask
|
||||
#if defined(CHIPTESTBOARDD) || defined(MOENCHD)
|
||||
i64 = setTimer(SAMPLES,GET_FLAG);
|
||||
n = sendData(file_des,&i64,sizeof(i64),INT64);
|
||||
if (n < 0) return printSocketReadError();
|
||||
|
||||
i32 = getADCEnableMask();
|
||||
n = sendData(file_des,&i32,sizeof(i32),INT32);
|
||||
if (n < 0) return printSocketReadError();
|
||||
#endif
|
||||
|
||||
if (lockStatus == 0) {
|
||||
strcpy(lastClientIP,thisClientIP);
|
||||
strcpy(lastClientIP, thisClientIP);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -3837,3 +3845,53 @@ int reboot_controller(int file_des) {
|
||||
return REBOOT;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int set_adc_enable_mask(int file_des) {
|
||||
ret = OK;
|
||||
memset(mess, 0, sizeof(mess));
|
||||
uint32_t arg = 0;
|
||||
|
||||
if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0)
|
||||
return printSocketReadError();
|
||||
FILE_LOG(logDEBUG1, ("Seting ADC Enable Mask to %u\n", arg));
|
||||
|
||||
#if (!defined(MOENCHD)) && (!defined(CHIPTESTBOARDD))
|
||||
functionNotImplemented();
|
||||
#else
|
||||
// only set
|
||||
if (Server_VerifyLock() == OK) {
|
||||
ret = setADCEnableMask(arg);
|
||||
if (ret == FAIL) {
|
||||
sprintf(mess, "Could not set ADC Enable mask to 0x%x. Could not allocate ram\n", arg);
|
||||
FILE_LOG(logERROR,(mess));
|
||||
} else {
|
||||
uint32_t retval = getADCEnableMask();
|
||||
if (arg != retval) {
|
||||
ret = FAIL;
|
||||
sprintf(mess, "Could not set ADC Enable mask. Set 0x%x, but read 0x%x\n", arg, retval);
|
||||
FILE_LOG(logERROR,(mess));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT32, UPDATE, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
int get_adc_enable_mask(int file_des) {
|
||||
ret = OK;
|
||||
memset(mess, 0, sizeof(mess));
|
||||
uint32_t retval = -1;
|
||||
|
||||
FILE_LOG(logDEBUG1, ("Getting ADC Enable Mask \n"));
|
||||
|
||||
#if (!defined(MOENCHD)) && (!defined(CHIPTESTBOARDD))
|
||||
functionNotImplemented();
|
||||
#else
|
||||
// get
|
||||
retval = getADCEnableMask();
|
||||
FILE_LOG(logDEBUG1, ("ADC Enable Mask retval: %u\n", retval));
|
||||
#endif
|
||||
return Server_SendResult(file_des, INT32, UPDATE, &retval, sizeof(retval));
|
||||
}
|
||||
|
@ -97,4 +97,6 @@ int led(int);
|
||||
int digital_io_delay(int);
|
||||
int copy_detector_server(int);
|
||||
int reboot_controller(int);
|
||||
int set_adc_enable_mask(int);
|
||||
int get_adc_enable_mask(int);
|
||||
|
||||
|
@ -172,7 +172,7 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
|
||||
/**
|
||||
* Decodes which detector and the corresponding channel numbers for it
|
||||
* Mainly useful in a multi detector setROI (Gotthard, Mythen?)
|
||||
* Mainly useful in a multi detector setROI (Gotthard)
|
||||
* @param offsetX channel number or total channel offset in x direction
|
||||
* @param offsetY channel number or total channel offset in y direction
|
||||
* @param channelX channel number from detector offset in x direction
|
||||
@ -1291,6 +1291,20 @@ class multiSlsDetector : public virtual slsDetectorDefs {
|
||||
*/
|
||||
const ROI *getROI(int &n, int detPos = -1);
|
||||
|
||||
/**
|
||||
* Set ADC Enable Mask (CTB, Moench)
|
||||
* @param mask ADC Enable mask
|
||||
* @param detPos -1 for all detectors in list or specific detector position
|
||||
*/
|
||||
void setADCEnableMask(uint32_t mask, int detPos = -1);
|
||||
|
||||
/**
|
||||
* Get ADC Enable Mask (CTB, Moench)
|
||||
* @param detPos -1 for all detectors in list or specific detector position
|
||||
* @returns ADC Enable mask
|
||||
*/
|
||||
uint32_t getADCEnableMask(int detPos = -1);
|
||||
|
||||
/**
|
||||
* Write to ADC register (Gotthard, Jungfrau, ChipTestBoard). For expert
|
||||
* users
|
||||
|
@ -16,7 +16,7 @@ class multiSlsDetector;
|
||||
class ServerInterface;
|
||||
class MySocketTCP;
|
||||
|
||||
#define SLS_SHMVERSION 0x190412
|
||||
#define SLS_SHMVERSION 0x190426
|
||||
#define NCHIPSMAX 10
|
||||
#define NCHANSMAX 65536
|
||||
#define NDACSMAX 16
|
||||
@ -97,6 +97,9 @@ struct sharedSlsDetector {
|
||||
/** list of rois */
|
||||
slsDetectorDefs::ROI roiLimits[MAX_ROIS];
|
||||
|
||||
/** adc enable mask */
|
||||
uint32_t adcEnableMask;
|
||||
|
||||
/** readout flags */
|
||||
slsDetectorDefs::readOutFlags roFlags;
|
||||
|
||||
@ -239,6 +242,7 @@ struct sharedSlsDetector {
|
||||
|
||||
/** overwriteenable */
|
||||
bool rxFileOverWrite;
|
||||
|
||||
};
|
||||
|
||||
class slsDetector : public virtual slsDetectorDefs{
|
||||
@ -1141,12 +1145,6 @@ class slsDetector : public virtual slsDetectorDefs{
|
||||
*/
|
||||
int setCounterBit(int cb = -1);
|
||||
|
||||
/**
|
||||
* send ROI to processor (moench only)
|
||||
* @returns OK or FAIL
|
||||
*/
|
||||
int sendROIToProcessor();
|
||||
|
||||
/**
|
||||
* Set ROI (Gotthard)
|
||||
* At the moment only one set allowed
|
||||
@ -1178,6 +1176,18 @@ class slsDetector : public virtual slsDetectorDefs{
|
||||
*/
|
||||
int sendROI(int n = -1, ROI roiLimits[] = nullptr);
|
||||
|
||||
/**
|
||||
* Set ADC Enable Mask (CTB, Moench)
|
||||
* @param mask ADC Enable mask
|
||||
*/
|
||||
void setADCEnableMask(uint32_t mask);
|
||||
|
||||
/**
|
||||
* Get ADC Enable Mask (CTB, Moench)
|
||||
* @returns ADC Enable mask
|
||||
*/
|
||||
uint32_t getADCEnableMask();
|
||||
|
||||
/**
|
||||
* Write to ADC register (Gotthard, Jungfrau, ChipTestBoard). For expert users
|
||||
* @param addr address of adc register
|
||||
|
@ -2448,6 +2448,32 @@ const slsDetectorDefs::ROI *multiSlsDetector::getROI(int &n, int detPos) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
void multiSlsDetector::setADCEnableMask(uint32_t mask, int detPos) {
|
||||
// single
|
||||
if (detPos >= 0) {
|
||||
detectors[detPos]->setADCEnableMask(mask);
|
||||
}
|
||||
|
||||
// multi
|
||||
parallelCall(&slsDetector::setADCEnableMask, mask);
|
||||
}
|
||||
|
||||
uint32_t multiSlsDetector::getADCEnableMask(int detPos) {
|
||||
// single
|
||||
if (detPos >= 0) {
|
||||
return detectors[detPos]->getADCEnableMask();
|
||||
}
|
||||
|
||||
// multi
|
||||
auto r = parallelCall(&slsDetector::getADCEnableMask);
|
||||
if (sls::allEqual(r)) {
|
||||
return r.front();
|
||||
}
|
||||
|
||||
// can't have different values
|
||||
throw RuntimeError("Error: Different Values for function getADCEnableMask");
|
||||
}
|
||||
|
||||
int multiSlsDetector::writeAdcRegister(uint32_t addr, uint32_t val, int detPos) {
|
||||
// single
|
||||
if (detPos >= 0) {
|
||||
|
@ -484,15 +484,16 @@ void slsDetector::updateTotalNumberOfChannels() {
|
||||
if (shm()->myDetectorType == CHIPTESTBOARD ||
|
||||
shm()->myDetectorType == MOENCH) {
|
||||
|
||||
// default number of channels
|
||||
shm()->nChan[X] = 32;
|
||||
|
||||
// if roi, recalculate #nchanX
|
||||
if (shm()->nROI > 0) {
|
||||
shm()->nChan[X] = 0;
|
||||
for (int iroi = 0; iroi < shm()->nROI; ++iroi) {
|
||||
shm()->nChan[X] += (shm()->roiLimits[iroi].xmax -
|
||||
shm()->roiLimits[iroi].xmin + 1);
|
||||
int nchans = 0;
|
||||
// calculate analog channels
|
||||
uint32_t mask = shm()->adcEnableMask;
|
||||
if (mask == BIT32_MASK) {
|
||||
nchans = 32;
|
||||
} else {
|
||||
nchans = 0;
|
||||
for (int ich = 0; ich < 32; ++ich) {
|
||||
if (mask & (1 << ich))
|
||||
++nchans;
|
||||
}
|
||||
}
|
||||
|
||||
@ -502,6 +503,7 @@ void slsDetector::updateTotalNumberOfChannels() {
|
||||
((shm()->roFlags & ANALOG_AND_DIGITAL) != 0))) {
|
||||
shm()->nChan[X] += 4;
|
||||
}
|
||||
shm()->nChan[X] = nchans;
|
||||
|
||||
// recalculate derived parameters chans and databytes
|
||||
shm()->nChans = shm()->nChan[X];
|
||||
@ -786,10 +788,10 @@ int slsDetector::updateDetectorNoWait(sls::ClientSocket &client) {
|
||||
n += client.receiveData(&i32, sizeof(i32));
|
||||
shm()->roiLimits[i].xmax = i32;
|
||||
}
|
||||
// moench (send to processor)
|
||||
if (shm()->myDetectorType == MOENCH) {
|
||||
sendROIToProcessor();
|
||||
}
|
||||
// // moench (send to processor)
|
||||
// if (shm()->myDetectorType == MOENCH) {
|
||||
// sendROIToProcessor();
|
||||
// }
|
||||
}
|
||||
|
||||
// update #nchans and databytes, as it depends on #samples, roi,
|
||||
@ -2491,17 +2493,17 @@ int slsDetector::setCounterBit(int cb) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
int slsDetector::sendROIToProcessor() {
|
||||
std::ostringstream os;
|
||||
os << "[" << shm()->roiLimits[0].xmin << ", " << shm()->roiLimits[0].xmax
|
||||
<< ", " << shm()->roiLimits[0].ymin << ", " << shm()->roiLimits[0].ymax
|
||||
<< "]";
|
||||
std::string sroi = os.str();
|
||||
std::string result = setAdditionalJsonParameter("roi", sroi);
|
||||
if (result == sroi)
|
||||
return OK;
|
||||
return FAIL;
|
||||
}
|
||||
// int slsDetector::sendROIToProcessor() {
|
||||
// std::ostringstream os;
|
||||
// os << "[" << shm()->roiLimits[0].xmin << ", " << shm()->roiLimits[0].xmax
|
||||
// << ", " << shm()->roiLimits[0].ymin << ", " << shm()->roiLimits[0].ymax
|
||||
// << "]";
|
||||
// std::string sroi = os.str();
|
||||
// std::string result = setAdditionalJsonParameter("roi", sroi);
|
||||
// if (result == sroi)
|
||||
// return OK;
|
||||
// return FAIL;
|
||||
// }
|
||||
|
||||
int slsDetector::setROI(int n, ROI roiLimits[]) {
|
||||
std::sort(roiLimits, roiLimits + n,
|
||||
@ -2509,7 +2511,7 @@ int slsDetector::setROI(int n, ROI roiLimits[]) {
|
||||
|
||||
int ret = sendROI(n, roiLimits);
|
||||
if (shm()->myDetectorType == MOENCH) {
|
||||
sendROIToProcessor();
|
||||
// sendROIToProcessor();
|
||||
}
|
||||
// update #nchans and databytes, as it depends on #samples, roi,
|
||||
if (shm()->myDetectorType == CHIPTESTBOARD ||
|
||||
@ -2639,6 +2641,42 @@ int slsDetector::sendROI(int n, ROI roiLimits[]) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void slsDetector::setADCEnableMask(uint32_t mask) {
|
||||
uint32_t arg = mask;
|
||||
FILE_LOG(logDEBUG1) << "Setting ADC Enable mask to 0x" << std::hex << arg << std::dec;
|
||||
if (shm()->onlineFlag == ONLINE_FLAG) {
|
||||
sendToDetector(F_SET_ADC_ENABLE_MASK, &arg, sizeof(arg), nullptr, 0);
|
||||
shm()->adcEnableMask = mask;
|
||||
|
||||
// update #nchans and databytes, as it depends on #samples, adcmask, readoutflags
|
||||
updateTotalNumberOfChannels();
|
||||
|
||||
// send to processor
|
||||
if (shm()->myDetectorType == MOENCH)
|
||||
setAdditionalJsonParameter("adcmask", std::to_string(shm()->adcEnableMask));
|
||||
|
||||
if (shm()->rxOnlineFlag == ONLINE_FLAG) {
|
||||
int fnum = F_RECEIVER_SET_ADC_MASK;
|
||||
int retval = -1;
|
||||
mask = shm()->adcEnableMask;
|
||||
FILE_LOG(logDEBUG1)
|
||||
<< "Setting ADC Enable mask to 0x" << std:: hex << mask << std::dec << " in receiver";
|
||||
sendToReceiver(fnum, &mask, sizeof(mask), &retval, sizeof(retval));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t slsDetector::getADCEnableMask() {
|
||||
uint32_t retval = -1;
|
||||
FILE_LOG(logDEBUG1) << "Getting ADC Enable mask";
|
||||
if (shm()->onlineFlag == ONLINE_FLAG) {
|
||||
sendToDetector(F_GET_ADC_ENABLE_MASK, nullptr, 0, &retval, sizeof(retval));
|
||||
shm()->adcEnableMask = retval;
|
||||
FILE_LOG(logDEBUG1) << "ADC Enable Mask: 0x" << std::hex << retval << std::dec;
|
||||
}
|
||||
return shm()->adcEnableMask;
|
||||
}
|
||||
|
||||
int slsDetector::writeAdcRegister(uint32_t addr, uint32_t val) {
|
||||
uint32_t args[]{addr, val};
|
||||
FILE_LOG(logDEBUG1) << "Writing to ADC register 0x" << std::hex << addr
|
||||
|
@ -5554,74 +5554,22 @@ std::string slsDetectorCommand::cmdPattern(int narg, char *args[], int action, i
|
||||
os << std::hex << myDet->readRegister(123, detPos) << std::dec ; //0x7b
|
||||
} else if (cmd == "adcdisable") {
|
||||
|
||||
int nroi = 0;
|
||||
ROI roiLimits[MAX_ROIS];
|
||||
|
||||
if (action == PUT_ACTION) {
|
||||
|
||||
if (sscanf(args[1], "%x", &addr))
|
||||
uint32_t adcEnableMask = 0;
|
||||
if (sscanf(args[1], "%x", &adcEnableMask))
|
||||
;
|
||||
else
|
||||
return std::string("Could not scan adcdisable reg ") + std::string(args[1]);
|
||||
|
||||
/******USE ROI?!?!?!?*********/
|
||||
// roiLimits[i].xmin;roiLimits[i].xmax;roiLimits[i].ymin;roiLimits[i].ymin;roiLimits[i].ymax
|
||||
//int mask=1;
|
||||
int ii = 0;
|
||||
while (ii < 32) {
|
||||
++nroi;
|
||||
roiLimits[nroi - 1].xmin = ii;
|
||||
roiLimits[nroi - 1].ymin = 0;
|
||||
roiLimits[nroi - 1].ymax = 0;
|
||||
while ((addr & (1 << ii))) {
|
||||
++ii;
|
||||
if (ii >= 32)
|
||||
break;
|
||||
}
|
||||
if (ii >= 32) {
|
||||
break;
|
||||
std::cout << "ROI " << nroi << " xmin " << roiLimits[nroi - 1].xmin << " xmax " << roiLimits[nroi - 1].xmax << std::endl;
|
||||
roiLimits[nroi - 1].xmax = 31;
|
||||
break;
|
||||
}
|
||||
roiLimits[nroi - 1].xmin = ii;
|
||||
while ((addr & (1 << ii)) == 0) {
|
||||
++ii;
|
||||
if (ii >= 32)
|
||||
break;
|
||||
}
|
||||
roiLimits[nroi - 1].xmax = ii - 1;
|
||||
if (ii >= 32) {
|
||||
std::cout << "ROI " << nroi << " xmin " << roiLimits[nroi - 1].xmin << " xmax " << roiLimits[nroi - 1].xmax << std::endl;
|
||||
++nroi;
|
||||
break;
|
||||
}
|
||||
std::cout << "ROI " << nroi << " xmin " << roiLimits[nroi - 1].xmin << " xmax " << roiLimits[nroi - 1].xmax << std::endl;
|
||||
}
|
||||
std::cout << "********ROI " << nroi << std::endl;
|
||||
myDet->setROI(nroi - 1, roiLimits, detPos);
|
||||
// myDet->writeRegister(94,addr, detPos);
|
||||
// myDet->writeRegister(120,addr, detPos);
|
||||
// get enable mask from enable mask
|
||||
adcEnableMask ^= 0xFFFFFFFF;
|
||||
myDet->setADCEnableMask(adcEnableMask, detPos);
|
||||
}
|
||||
|
||||
const ROI *aa = myDet->getROI(nroi, detPos);
|
||||
|
||||
int reg = 0xffffffff;
|
||||
if (nroi < 1)
|
||||
reg = 0;
|
||||
else {
|
||||
for (int iroi = 0; iroi < nroi; ++iroi) {
|
||||
std::cout << iroi << " xmin " << (aa + iroi)->xmin << " xmax " << (aa + iroi)->xmax << std::endl;
|
||||
for (int ich = (aa + iroi)->xmin; ich <= (aa + iroi)->xmax; ++ich) {
|
||||
reg &= ~(1 << ich);
|
||||
}
|
||||
}
|
||||
}
|
||||
os << std::hex << reg << std::dec ;
|
||||
if (aa != NULL)
|
||||
delete [] aa;
|
||||
//os <<" "<< std::hex << myDet->readRegister(120, detPos) << std::dec ;
|
||||
|
||||
uint32_t retval = myDet->getADCEnableMask(detPos);
|
||||
// get disable mask
|
||||
retval ^= 0xFFFFFFFF;
|
||||
os << std::hex << retval << std::dec;
|
||||
}
|
||||
|
||||
else
|
||||
|
@ -212,12 +212,12 @@ public:
|
||||
|
||||
/**
|
||||
* Set databytes (ctb, moench)
|
||||
* @param f readout flags
|
||||
* @param r roi
|
||||
* @param a adc enable mask
|
||||
* @param s number of samples
|
||||
* @param t tengiga enable
|
||||
* @param f readout flags
|
||||
*/
|
||||
virtual void setImageSize(std::vector<slsDetectorDefs::ROI> r, int s, bool t, slsDetectorDefs::readOutFlags f = slsDetectorDefs::GET_READOUT_FLAGS) {
|
||||
virtual void setImageSize(uint32_t a, int s, bool t, slsDetectorDefs::readOutFlags f = slsDetectorDefs::GET_READOUT_FLAGS) {
|
||||
cprintf(RED,"setImageSize is a generic function that should be overloaded by a derived class\n");
|
||||
};
|
||||
|
||||
@ -586,22 +586,22 @@ public:
|
||||
|
||||
/**
|
||||
* Set databytes (ctb, moench)
|
||||
* @param f readout flags
|
||||
* @param r roi
|
||||
* @param a adc enable mask
|
||||
* @param s number of samples
|
||||
* @param t tengiga enable
|
||||
* @param f readout flags
|
||||
*/
|
||||
void setImageSize(std::vector<slsDetectorDefs::ROI> r, int s, bool t, slsDetectorDefs::readOutFlags f = slsDetectorDefs::GET_READOUT_FLAGS) {
|
||||
void setImageSize(uint32_t a, int s, bool t, slsDetectorDefs::readOutFlags f = slsDetectorDefs::GET_READOUT_FLAGS) {
|
||||
int nchans = 0;
|
||||
if (f != slsDetectorDefs::GET_READOUT_FLAGS) {
|
||||
// analog channels
|
||||
if (f == slsDetectorDefs::NORMAL_READOUT || f & slsDetectorDefs::ANALOG_AND_DIGITAL) {
|
||||
nchans += NCHAN_ANALOG;
|
||||
// if roi
|
||||
if (r.size()) {
|
||||
nchans = 0;
|
||||
for (auto &roi : r) {
|
||||
nchans += (roi.xmax - roi.xmin + 1);
|
||||
if (a == BIT32_MASK) {
|
||||
nchans = 32;
|
||||
} else {
|
||||
for (int ich = 0; ich < 32; ++ich) {
|
||||
if (a & (1 << ich))
|
||||
++nchans;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -688,19 +688,19 @@ public:
|
||||
|
||||
/**
|
||||
* Set databytes (ctb, moench)
|
||||
* @param f readout flags
|
||||
* @param r roi
|
||||
* @param a adc enable mask
|
||||
* @param s number of samples
|
||||
* @param t tengiga enable
|
||||
* @param f readout flags
|
||||
*/
|
||||
void setImageSize(std::vector<slsDetectorDefs::ROI> r, int s, bool t,
|
||||
slsDetectorDefs::readOutFlags f = slsDetectorDefs::GET_READOUT_FLAGS) {
|
||||
void setImageSize(uint32_t a, int s, bool t, slsDetectorDefs::readOutFlags f = slsDetectorDefs::GET_READOUT_FLAGS) {
|
||||
int nchans = 32;
|
||||
// if roi
|
||||
if (r.size()) {
|
||||
nchans = 0;
|
||||
for (auto &roi : r) {
|
||||
nchans += abs(roi.xmax - roi.xmin) + 1;
|
||||
if (a == BIT32_MASK) {
|
||||
nchans = 32;
|
||||
} else {
|
||||
for (int ich = 0; ich < 32; ++ich) {
|
||||
if (a & (1 << ich))
|
||||
++nchans;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,6 +194,12 @@ class slsReceiverImplementation: private virtual slsDetectorDefs {
|
||||
*/
|
||||
std::vector<ROI> getROI() const;
|
||||
|
||||
/**
|
||||
* Get ADC Enable Mask
|
||||
* @return ADC Enable Mask
|
||||
*/
|
||||
uint32_t getADCEnableMask() const;
|
||||
|
||||
/**
|
||||
* Get the streaming frequency
|
||||
* @return 0 for timer, n for nth frame frequency
|
||||
@ -474,6 +480,13 @@ class slsReceiverImplementation: private virtual slsDetectorDefs {
|
||||
*/
|
||||
int setROI(const std::vector<ROI> new_roi);
|
||||
|
||||
/**
|
||||
* Set ADC Enable Mask
|
||||
* @param mask ADC Enable Mask
|
||||
* @return OK or FAIL
|
||||
*/
|
||||
int setADCEnableMask(const uint32_t mask);
|
||||
|
||||
/**
|
||||
* Set the streaming frequency
|
||||
* @param freq 0 for timer, n for nth frame frequency
|
||||
@ -855,6 +868,8 @@ private:
|
||||
//***acquisition parameters***
|
||||
/* ROI */
|
||||
std::vector<ROI> roi;
|
||||
/** ADC Enable Mask */
|
||||
uint32_t adcEnableMask;
|
||||
/** streaming frequency */
|
||||
uint32_t streamingFrequency;
|
||||
/** Streaming timer when frequency is 0 */
|
||||
|
@ -282,6 +282,9 @@ class slsReceiverTCPIPInterface : private virtual slsDetectorDefs {
|
||||
/** set readout flags */
|
||||
int set_readout_flags();
|
||||
|
||||
/** set adc mask */
|
||||
int set_adc_mask();
|
||||
|
||||
|
||||
/** detector type */
|
||||
detectorType myDetectorType;
|
||||
|
@ -100,6 +100,7 @@ void slsReceiverImplementation::InitializeMembers() {
|
||||
|
||||
//***acquisition parameters***
|
||||
roi.clear();
|
||||
adcEnableMask = BIT32_MASK;
|
||||
streamingFrequency = 0;
|
||||
streamingTimerInMs = DEFAULT_STREAMING_TIMER_IN_MS;
|
||||
dataStreamEnable = false;
|
||||
@ -289,6 +290,11 @@ std::vector<slsDetectorDefs::ROI> slsReceiverImplementation::getROI() const{
|
||||
return roi;
|
||||
}
|
||||
|
||||
uint32_t slsReceiverImplementation::getADCEnableMask() const{
|
||||
FILE_LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
||||
return adcEnableMask;
|
||||
}
|
||||
|
||||
uint32_t slsReceiverImplementation::getStreamingFrequency() const{
|
||||
FILE_LOG(logDEBUG3) << __SHORT_AT__ << " called";
|
||||
return streamingFrequency;
|
||||
@ -463,7 +469,7 @@ int slsReceiverImplementation::setReadOutFlags(const readOutFlags f) {
|
||||
|
||||
// side effects
|
||||
if (myDetectorType == CHIPTESTBOARD) {
|
||||
generalData->setImageSize(roi, numberOfSamples, tengigaEnable, readoutFlags);
|
||||
generalData->setImageSize(adcEnableMask, numberOfSamples, tengigaEnable, readoutFlags);
|
||||
for (const auto& it : dataProcessor)
|
||||
it->SetPixelDimension();
|
||||
if (SetupFifoStructure() == FAIL)
|
||||
@ -770,13 +776,6 @@ int slsReceiverImplementation::setROI(const std::vector<slsDetectorDefs::ROI> ne
|
||||
generalData->SetROI(new_roi);
|
||||
framesPerFile = generalData->maxFramesPerFile;
|
||||
break;
|
||||
case MOENCH:
|
||||
generalData->setImageSize(roi, numberOfSamples, tengigaEnable);
|
||||
break;
|
||||
case CHIPTESTBOARD:
|
||||
generalData->setImageSize(roi, numberOfSamples, tengigaEnable,
|
||||
readoutFlags);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -806,6 +805,32 @@ int slsReceiverImplementation::setROI(const std::vector<slsDetectorDefs::ROI> ne
|
||||
return OK;
|
||||
}
|
||||
|
||||
int slsReceiverImplementation::setADCEnableMask(uint32_t mask) {
|
||||
if (adcEnableMask != mask) {
|
||||
adcEnableMask = mask;
|
||||
|
||||
switch (myDetectorType) {
|
||||
case MOENCH:
|
||||
generalData->setImageSize(mask, numberOfSamples, tengigaEnable);
|
||||
break;
|
||||
case CHIPTESTBOARD:
|
||||
generalData->setImageSize(mask, numberOfSamples, tengigaEnable, readoutFlags);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (const auto& it : dataProcessor)
|
||||
it->SetPixelDimension();
|
||||
if (SetupFifoStructure() == FAIL)
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
FILE_LOG(logINFO) << "ADC Enable Mask: 0x" << std::hex << adcEnableMask << std::dec;
|
||||
FILE_LOG (logINFO) << "Packets per Frame: " << (generalData->packetsPerFrame);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
int slsReceiverImplementation::setStreamingFrequency(const uint32_t freq) {
|
||||
if (streamingFrequency != freq) {
|
||||
@ -921,9 +946,9 @@ int slsReceiverImplementation::setNumberofSamples(const uint64_t i) {
|
||||
numberOfSamples = i;
|
||||
|
||||
if(myDetectorType == MOENCH) {
|
||||
generalData->setImageSize(roi, numberOfSamples, tengigaEnable);
|
||||
generalData->setImageSize(adcEnableMask, numberOfSamples, tengigaEnable);
|
||||
} else if(myDetectorType == CHIPTESTBOARD) {
|
||||
generalData->setImageSize(roi, numberOfSamples, tengigaEnable, readoutFlags);
|
||||
generalData->setImageSize(adcEnableMask, numberOfSamples, tengigaEnable, readoutFlags);
|
||||
}
|
||||
for (const auto& it : dataProcessor)
|
||||
it->SetPixelDimension();
|
||||
@ -962,10 +987,10 @@ int slsReceiverImplementation::setTenGigaEnable(const bool b) {
|
||||
generalData->SetTenGigaEnable(b,dynamicRange);
|
||||
break;
|
||||
case MOENCH:
|
||||
generalData->setImageSize(roi, numberOfSamples, tengigaEnable);
|
||||
generalData->setImageSize(adcEnableMask, numberOfSamples, tengigaEnable);
|
||||
break;
|
||||
case CHIPTESTBOARD:
|
||||
generalData->setImageSize(roi, numberOfSamples, tengigaEnable, readoutFlags);
|
||||
generalData->setImageSize(adcEnableMask, numberOfSamples, tengigaEnable, readoutFlags);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -227,6 +227,7 @@ int slsReceiverTCPIPInterface::function_table(){
|
||||
flist[F_RECEIVER_PADDING_ENABLE] = &slsReceiverTCPIPInterface::set_padding_enable;
|
||||
flist[F_RECEIVER_DEACTIVATED_PADDING_ENABLE] = &slsReceiverTCPIPInterface::set_deactivated_receiver_padding_enable;
|
||||
flist[F_RECEIVER_SET_READOUT_FLAGS] = &slsReceiverTCPIPInterface::set_readout_flags;
|
||||
flist[F_RECEIVER_SET_ADC_MASK] = &slsReceiverTCPIPInterface::set_adc_mask;
|
||||
|
||||
for (int i = NUM_DET_FUNCTIONS + 1; i < NUM_REC_FUNCTIONS ; i++) {
|
||||
FILE_LOG(logDEBUG1) << "function fnum: " << i << " (" <<
|
||||
@ -2034,3 +2035,36 @@ int slsReceiverTCPIPInterface::set_readout_flags() {
|
||||
}
|
||||
return interface->Server_SendResult(true, ret, &retval, sizeof(retval), mess);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int slsReceiverTCPIPInterface::set_adc_mask() {
|
||||
ret = OK;
|
||||
memset(mess, 0, sizeof(mess));
|
||||
uint32_t arg = -1;
|
||||
uint32_t retval = -1;
|
||||
|
||||
// get args, return if socket crashed, ret is fail if receiver is not null
|
||||
if (interface->Server_ReceiveArg(ret, mess, &arg, sizeof(arg), true, receiver) == FAIL)
|
||||
return FAIL;
|
||||
|
||||
// base object not null
|
||||
else if (ret == OK) {
|
||||
// set
|
||||
// verify if receiver is unlocked and idle
|
||||
if (interface->Server_VerifyLockAndIdle(ret, mess, lockStatus, receiver->getStatus(), fnum) == OK) {
|
||||
FILE_LOG(logDEBUG1) << "Setting ADC enable mask: " << arg;
|
||||
receiver->setADCEnableMask(arg);
|
||||
}
|
||||
|
||||
// get
|
||||
retval = receiver->getADCEnableMask();
|
||||
if (ret == OK && retval != arg) {
|
||||
ret = FAIL;
|
||||
sprintf(mess, "Could not ADC enable mask. Set 0x%x, but read 0x%x\n", arg, retval);
|
||||
FILE_LOG(logERROR) << mess;
|
||||
}
|
||||
FILE_LOG(logDEBUG1) << "ADC enable mask retval: " << retval;
|
||||
}
|
||||
return interface->Server_SendResult(false, ret, &retval, sizeof(retval), mess);
|
||||
}
|
@ -23,6 +23,8 @@
|
||||
#endif
|
||||
#include "ansi.h"
|
||||
|
||||
#define BIT32_MASK 0xFFFFFFFF
|
||||
|
||||
/** default ports */
|
||||
#define DEFAULT_PORTNO 1952
|
||||
#define DEFAULT_UDP_PORTNO 50001
|
||||
|
@ -81,6 +81,8 @@ enum detFuncs{
|
||||
F_DIGITAL_IO_DELAY, /** < digital IO delay */
|
||||
F_COPY_DET_SERVER, /** < copy detector server & respawn */
|
||||
F_REBOOT_CONTROLLER, /** < reboot detector controller (blackfin/ powerpc) */
|
||||
F_SET_ADC_ENABLE_MASK, /** < setting ADC enable mask */
|
||||
F_GET_ADC_ENABLE_MASK, /** < setting ADC enable mask */
|
||||
NUM_DET_FUNCTIONS,
|
||||
|
||||
RECEIVER_ENUM_START = 128, /**< detector function should not exceed this (detector server should not compile anyway) */
|
||||
@ -133,6 +135,7 @@ enum detFuncs{
|
||||
F_RECEIVER_PADDING_ENABLE, /** < partial frames padding enable */
|
||||
F_RECEIVER_DEACTIVATED_PADDING_ENABLE, /** < deactivated receiver padding enable */
|
||||
F_RECEIVER_SET_READOUT_FLAGS, /**< set/get receiver readout flags */
|
||||
F_RECEIVER_SET_ADC_MASK, /**< set adc mask */
|
||||
NUM_REC_FUNCTIONS
|
||||
};
|
||||
|
||||
@ -210,6 +213,8 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) {
|
||||
case F_DIGITAL_IO_DELAY: return "F_DIGITAL_IO_DELAY";
|
||||
case F_COPY_DET_SERVER: return "F_COPY_DET_SERVER";
|
||||
case F_REBOOT_CONTROLLER: return "F_REBOOT_CONTROLLER";
|
||||
case F_SET_ADC_ENABLE_MASK: return "F_SET_ADC_ENABLE_MASK";
|
||||
case F_GET_ADC_ENABLE_MASK: return "F_GET_ADC_ENABLE_MASK";
|
||||
|
||||
case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS";
|
||||
case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START";
|
||||
@ -263,6 +268,7 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) {
|
||||
case F_RECEIVER_PADDING_ENABLE: return "F_RECEIVER_PADDING_ENABLE";
|
||||
case F_RECEIVER_DEACTIVATED_PADDING_ENABLE: return "F_RECEIVER_DEACTIVATED_PADDING_ENABLE";
|
||||
case F_RECEIVER_SET_READOUT_FLAGS: return "F_RECEIVER_SET_READOUT_FLAGS";
|
||||
case F_RECEIVER_SET_ADC_MASK: return "F_RECEIVER_SET_ADC_MASK";
|
||||
case NUM_REC_FUNCTIONS: return "NUM_REC_FUNCTIONS";
|
||||
default: return "Unknown Function";
|
||||
}
|
||||
|
@ -7,4 +7,4 @@
|
||||
#define APIRECEIVER 0x190405
|
||||
#define APIGUI 0x190405
|
||||
#define APIEIGER 0x190418
|
||||
#define APICTB 0x190423
|
||||
#define APICTB 0x190426
|
||||
|
Loading…
x
Reference in New Issue
Block a user