Counters (#71)

* mythen3: adding counters mask, firmware still takes only number of counters for now

* mythen3: checking if module attached before powering on chip

* bug fix: loop inital declaration not allowed in c

* fix scope eiger test

* mythen3: renamed setCounters to setCounterMask and getCounterMask in API

* mythen3 replacing counting bits with popcount

Co-authored-by: Erik Fröjdh <erik.frojdh@gmail.com>
This commit is contained in:
Dhanya Thattil
2020-01-14 17:40:46 +01:00
committed by Erik Fröjdh
parent 70c54f4315
commit de53747ddd
26 changed files with 742 additions and 759 deletions

View File

@ -82,7 +82,6 @@
/* Config RW regiseter */
#define CONFIG_REG (0x20 * REG_OFFSET + BASE_CONTROL)
#define CONFIG_COUNTER_ENA_OFST (0)
#define CONFIG_COUNTER_ENA_MSK (0x00000003 << CONFIG_COUNTER_ENA_OFST)
#define CONFIG_COUNTER_ENA_DEFAULT_VAL ((0x0 << CONFIG_COUNTER_ENA_OFST) & CONFIG_COUNTER_ENA_MSK)
@ -119,6 +118,8 @@
#define DTA_OFFSET_REG (0x24 * REG_OFFSET + BASE_CONTROL)
/* Pattern Control registers --------------------------------------------------*/
/* Pattern status Register*/

View File

@ -38,6 +38,7 @@ uint32_t clkFrequency[NUM_CLOCKS] = {0, 0, 0, 0, 0};
int highvoltage = 0;
int dacValues[NDAC] = {0};
int detPos[2] = {0, 0};
uint32_t countermask = 0; // will be removed later when in firmware converted to mask
int isInitCheckDone() {
return initCheckDone;
@ -364,8 +365,7 @@ void setupDetector() {
// dynamic range
setDynamicRange(DEFAULT_DYNAMIC_RANGE);
// enable all counters
bus_w(CONFIG_REG, bus_r(CONFIG_REG) & ~CONFIG_COUNTER_ENA_MSK);
bus_w(CONFIG_REG, bus_r(CONFIG_REG) | CONFIG_COUNTER_ENA_ALL_VAL);
setCounterMask(MAX_COUNTER_MSK);
// Initialization of acquistion parameters
@ -529,6 +529,66 @@ int64_t getPeriod() {
return get64BitReg(SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG)/ (1E-9 * FIXED_PLL_FREQUENCY);
}
void setCounterMask(uint32_t arg) {
if (arg == 0 || arg > MAX_COUNTER_MSK) {
return;
}
countermask = arg;
// convert mask into number of counters (until firmware converts to mask)
int ncounters = __builtin_popcount(countermask);
FILE_LOG(logINFO, ("Setting number of counters to %d\n", ncounters));
uint32_t val = 0;
switch (ncounters) {
case 1:
val = CONFIG_COUNTER_ENA_1_VAL;
break;
case 2:
val = CONFIG_COUNTER_ENA_2_VAL;
break;
default:
val = CONFIG_COUNTER_ENA_ALL_VAL;
break;
}
uint32_t addr = CONFIG_REG;
bus_w(addr, bus_r(addr) &~ CONFIG_COUNTER_ENA_MSK);
bus_w(addr, bus_r(addr) | val);
FILE_LOG(logDEBUG, ("Config Reg: 0x%x\n", bus_r(addr)));
}
uint32_t getCounterMask() {
uint32_t addr = CONFIG_REG;
uint32_t regval = (bus_r(addr) & CONFIG_COUNTER_ENA_MSK);
int ncounters = 0;
switch (regval) {
case CONFIG_COUNTER_ENA_1_VAL:
ncounters = 1;
break;
case CONFIG_COUNTER_ENA_2_VAL:
ncounters = 2;
break;
default:
ncounters = 3;
break;
}
// confirm ncounters work with mask saved in server (until firmware converts to mask)
int nc = __builtin_popcount(countermask);
// if not equal, make a mask of what is in register (will change once firmware changes)
if (nc != ncounters) {
switch (ncounters) {
case 1:
countermask = 0x1;
break;
case 2:
countermask = 0x3;
break;
default:
countermask = 0x7;
break;
}
}
return countermask;
}
int setDelayAfterTrigger(int64_t val) {
if (val < 0) {
FILE_LOG(logERROR, ("Invalid delay after trigger: %lld ns\n", (long long int)val));
@ -992,6 +1052,33 @@ void setPatternLoop(int level, int *startAddr, int *stopAddr, int *nLoop) {
}
}
int checkDetectorType() {
FILE_LOG(logINFO, ("Checking type of module\n"));
FILE* fd = fopen(TYPE_FILE_NAME, "r");
if (fd == NULL) {
FILE_LOG(logERROR, ("Could not open file %s to get type of the module attached\n", TYPE_FILE_NAME));
return -1;
}
char buffer[MAX_STR_LENGTH];
memset(buffer, 0, sizeof(buffer));
fread (buffer, MAX_STR_LENGTH, sizeof(char), fd);
if (strlen(buffer) == 0) {
FILE_LOG(logERROR, ("Could not read file %s to get type of the module attached\n", TYPE_FILE_NAME));
return -1;
}
int type = atoi(buffer);
if (type > TYPE_TOLERANCE) {
FILE_LOG(logERROR, ("No Module attached! Expected %d for Mythen, got %d\n", TYPE_MYTHEN3_MODULE_VAL, type));
return -2;
}
if (abs(type - TYPE_MYTHEN3_MODULE_VAL) > TYPE_TOLERANCE) {
FILE_LOG(logERROR, ("Wrong Module attached! Expected %d for Mythen, got %d\n", TYPE_MYTHEN3_MODULE_VAL, type));
return FAIL;
}
return OK;
}
int powerChip (int on){
if(on != -1){
if(on){

View File

@ -7,14 +7,21 @@
#define CTRL_SRVR_INIT_TIME_US (300 * 1000)
/* Hardware Definitions */
#define NCHAN (128 * 3)
#define NCOUNTERS (3)
#define MAX_COUNTER_MSK (0x7)
#define NCHAN (128 * NCOUNTERS)
#define NCHIP (10)
#define NDAC (16)
#define HV_SOFT_MAX_VOLTAGE (200)
#define HV_HARD_MAX_VOLTAGE (530)
#define HV_DRIVER_FILE_NAME ("/etc/devlinks/hvdac")
#define DAC_DRIVER_FILE_NAME ("/etc/devlinks/dac")
#define DAC_DRIVER_FILE_NAME ("/etc/devlinks/dac")
#define TYPE_FILE_NAME ("/etc/devlinks/type")
#define DAC_MAX_MV (2048)
#define TYPE_MYTHEN3_MODULE_VAL (93)
#define TYPE_TOLERANCE (10)
#define TYPE_NO_MODULE_STARTING_VAL (800)
/** Default Parameters */
#define DEFAULT_DYNAMIC_RANGE (24)

View File

@ -198,6 +198,10 @@ int getNumAnalogSamples();
int setNumDigitalSamples(int val);
int getNumDigitalSamples();
#endif
#ifdef MYTHEN3D
void setCounterMask(uint32_t arg);
uint32_t getCounterMask();
#endif
#if defined(JUNGFRAUD) || defined(GOTTHARDD) || defined(CHIPTESTBOARDD) || defined(MOENCHD) || defined(MYTHEN3D)
int setDelayAfterTrigger(int64_t val);
@ -221,6 +225,7 @@ int64_t getMeasurementTime();
#endif
// parameters - module, settings
#if (!defined(CHIPTESTBOARDD)) && (!defined(MOENCHD)) && (!defined(MYTHEN3D)) && (!defined(GOTTHARD2D))
int setModule(sls_detector_module myMod, char* mess);
@ -424,6 +429,7 @@ uint64_t writePatternWord(int addr, uint64_t word);
int setPatternWaitAddress(int level, int addr);
uint64_t setPatternWaitTime(int level, uint64_t t);
void setPatternLoop(int level, int *startAddr, int *stopAddr, int *nLoop);
int checkDetectorType();
int powerChip (int on);
int setPhase(enum CLKINDEX ind, int val, int degrees);
int getPhase(enum CLKINDEX ind, int degrees);

View File

@ -203,4 +203,6 @@ int set_veto_refernce(int);
int get_burst_mode(int);
int set_burst_mode(int);
int set_adc_enable_mask_10g(int);
int get_adc_enable_mask_10g(int);
int get_adc_enable_mask_10g(int);
int set_counter_mask(int);
int get_counter_mask(int);

View File

@ -305,6 +305,8 @@ const char* getFunctionName(enum detFuncs func) {
case F_SET_BURST_MODE: return "F_SET_BURST_MODE";
case F_SET_ADC_ENABLE_MASK_10G: return "F_SET_ADC_ENABLE_MASK_10G";
case F_GET_ADC_ENABLE_MASK_10G: return "F_GET_ADC_ENABLE_MASK_10G";
case F_SET_COUNTER_MASK: return "F_SET_COUNTER_MASK";
case F_GET_COUNTER_MASK: return "F_GET_COUNTER_MASK";
default: return "Unknown Function";
}
@ -487,6 +489,8 @@ void function_table() {
flist[F_SET_BURST_MODE] = &set_burst_mode;
flist[F_SET_ADC_ENABLE_MASK_10G] = &set_adc_enable_mask_10g;
flist[F_GET_ADC_ENABLE_MASK_10G] = &get_adc_enable_mask_10g;
flist[F_SET_COUNTER_MASK] = &set_counter_mask;
flist[F_GET_COUNTER_MASK] = &get_counter_mask;
// check
if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) {
@ -3837,8 +3841,29 @@ int power_chip(int file_des) {
#else
// set & get
if ((arg == -1) || (Server_VerifyLock() == OK)) {
retval = powerChip(arg);
FILE_LOG(logDEBUG1, ("Power chip: %d\n", retval));
#ifdef MYTHEN3D
// check only when powering on
if (arg != -1 && arg != 0) {
int type_ret = checkDetectorType();
if (type_ret == -1) {
ret = FAIL;
sprintf(mess, "Could not power on chip. Could not open file to get type of module attached.\n");
FILE_LOG(logERROR,(mess));
} else if (type_ret == -2) {
ret = FAIL;
sprintf(mess, "Could not power on chip. No module attached!\n");
FILE_LOG(logERROR,(mess));
} else if (type_ret == FAIL) {
ret = FAIL;
sprintf(mess, "Could not power on chip. Wrong module attached!\n");
FILE_LOG(logERROR,(mess));
}
}
#endif
if (ret == OK) {
retval = powerChip(arg);
FILE_LOG(logDEBUG1, ("Power chip: %d\n", retval));
}
validate(arg, retval, "power on/off chip", DEC);
#ifdef JUNGFRAUD
// narrow down error when powering on
@ -5715,7 +5740,7 @@ int get_clock_frequency(int file_des) {
#endif
default:
#if defined(GOTTHARD2D) || defined(MYTHEN3D)
if (c < NUM_CLOCKS) {
if (arg < NUM_CLOCKS) {
c = (enum CLKINDEX)arg;
break;
}
@ -6499,4 +6524,60 @@ int get_burst_mode(int file_des) {
FILE_LOG(logDEBUG1, ("Get burst mode:%d\n", retval));
#endif
return Server_SendResult(file_des, INT32, UPDATE, &retval, sizeof(retval));
}
int set_counter_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(logINFO, ("Setting Counter mask:0x%x\n", arg));
#ifndef MYTHEN3D
functionNotImplemented();
#else
// only set
if (Server_VerifyLock() == OK) {
if (arg == 0) {
ret = FAIL;
sprintf(mess, "Could not set counter mask. Cannot set it to 0.\n");
FILE_LOG(logERROR, (mess));
} else if (arg > MAX_COUNTER_MSK) {
ret = FAIL;
sprintf(mess, "Could not set counter mask. Invalid counter bit enabled. Max number of counters: %d\n", NCOUNTERS);
FILE_LOG(logERROR, (mess));
} else {
setCounterMask(arg);
uint32_t retval = getCounterMask();
FILE_LOG(logDEBUG, ("counter mask retval: 0x%x\n", retval));
if (retval != arg) {
ret = FAIL;
sprintf(mess, "Could not set counter mask. Set 0x%x mask, got 0x%x mask\n", arg, retval);
FILE_LOG(logERROR, (mess));
}
}
}
#endif
return Server_SendResult(file_des, INT32, UPDATE, NULL, 0);
}
int get_counter_mask(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
uint32_t retval = -1;
FILE_LOG(logDEBUG1, ("Getting counter mask\n"));
#ifndef MYTHEN3D
functionNotImplemented();
#else
// get only
retval = getCounterMask();
FILE_LOG(logDEBUG, ("counter mask retval: 0x%x\n", retval));
#endif
return Server_SendResult(file_des, INT32, UPDATE, &retval, sizeof(retval));
}