diff --git a/python/slsdet/detector.py b/python/slsdet/detector.py index c0c95cd26..2ea303d53 100755 --- a/python/slsdet/detector.py +++ b/python/slsdet/detector.py @@ -2738,7 +2738,7 @@ class Detector(CppDetectorApi): @element def chipversion(self): """ - [Jungfrau] Chip version of module. Can be 1.0 or 1.1. + [Jungfrau] Chip version of module. Can be 1.0, 1.1 or 1.2. Example ------- diff --git a/slsDetectorServers/jungfrauDetectorServer/RegisterDefs.h b/slsDetectorServers/jungfrauDetectorServer/RegisterDefs.h index f1f81d863..6ea71da55 100644 --- a/slsDetectorServers/jungfrauDetectorServer/RegisterDefs.h +++ b/slsDetectorServers/jungfrauDetectorServer/RegisterDefs.h @@ -108,6 +108,12 @@ #define CONFIG_V11_STATUS_FLTR_CLL_MSK (0x00000FFF << CONFIG_V11_STATUS_FLTR_CLL_OFST) #define CONFIG_V11_STATUS_STRG_CLL_OFST (12) #define CONFIG_V11_STATUS_STRG_CLL_MSK (0x0000000F << CONFIG_V11_STATUS_STRG_CLL_OFST) + +// replacing for v1.2 +#define CONFIG_V12_STATUS_STRG_CLL_OFST (0) +#define CONFIG_V12_STATUS_STRG_CLL_MSK (0x0000FFFF << CONFIG_V12_STATUS_STRG_CLL_OFST) + + // CSM mode = high current (100%), low current (16%) #define CONFIG_V11_STATUS_CRRNT_SRC_LOW_OFST (19) #define CONFIG_V11_STATUS_CRRNT_SRC_LOW_MSK (0x00000001 << CONFIG_V11_STATUS_CRRNT_SRC_LOW_OFST) @@ -236,8 +242,6 @@ #define CONTROL_ACQ_FIFO_CLR_MSK (0x00000001 << CONTROL_ACQ_FIFO_CLR_OFST) #define CONTROL_MASTER_OFST (15) #define CONTROL_MASTER_MSK (0x00000001 << CONTROL_MASTER_OFST) -#define CONTROL_STORAGE_CELL_NUM_OFST (16) -#define CONTROL_STORAGE_CELL_NUM_MSK (0x0000000F << CONTROL_STORAGE_CELL_NUM_OFST) #define CONTROL_RX_ADDTNL_ENDPTS_NUM_OFST (20) #define CONTROL_RX_ADDTNL_ENDPTS_NUM_MSK (0x0000003F << CONTROL_RX_ADDTNL_ENDPTS_NUM_OFST) #define CONTROL_RX_ENDPTS_START_OFST (26) @@ -261,6 +265,21 @@ #define PLL_CNTRL_ADDR_MSK (0x0000003F << PLL_CNTRL_ADDR_OFST) +/** Storage cell Register */ +#define STORAGE_CELL_REG (0x56 << MEM_MAP_SHIFT) + +#define STORAGE_CELL_START_OFST (0) +#define STORAGE_CELL_START_MSK (0x000000FF << STORAGE_CELL_START_OFST) +#define STORAGE_CELL_NUM_ADDTNL_OFST (8) +#define STORAGE_CELL_NUM_ADDTNL_MSK (0x000000FF << STORAGE_CELL_NUM_ADDTNL_OFST) +// tET = (ET + 1) * 25ns (increase timeout range between 2 consecutive storage +// cells) +#define STORAGE_CELL_EXPSRE_TMR_OFST (16) +#define STORAGE_CELL_EXPSRE_TMR_MSK (0x0000FFFF << STORAGE_CELL_EXPSRE_TMR_OFST) +#define STORAGE_CELL_EXPSRE_TMR_MAX_VAL (0x0000FFFF / (CLK_RUN * 1E-3)) + + + /* Pedestal Mode Regiser */ #define PEDESTAL_MODE_REG (0x57 << MEM_MAP_SHIFT) @@ -271,13 +290,18 @@ #define PEDESTAL_MODE_ENBLE_OFST (31) #define PEDESTAL_MODE_ENBLE_MSK (0x00000001 << PEDESTAL_MODE_ENBLE_OFST) -/* Config Register for chip 1.1 */ +/* Config Register for chip 1.1 and chip 1.2 */ #define CONFIG_V11_REG (0x58 << MEM_MAP_SHIFT) #define CONFIG_V11_FLTR_CLL_OFST (0) #define CONFIG_V11_FLTR_CLL_MSK (0x00000FFF << CONFIG_V11_FLTR_CLL_OFST) #define CONFIG_V11_STRG_CLL_OFST (12) #define CONFIG_V11_STRG_CLL_MSK (0x0000000F << CONFIG_V11_STRG_CLL_OFST) +// replacing for v1.2 +#define CONFIG_V12_STRG_CLL_OFST (0) +#define CONFIG_V12_STRG_CLL_MSK (0x0000FFFF << CONFIG_V12_STRG_CLL_OFST) + + // CSM mode = high current (100%), low current (16%) #define CONFIG_V11_CRRNT_SRC_LOW_OFST (19) #define CONFIG_V11_CRRNT_SRC_LOW_MSK (0x00000001 << CONFIG_V11_CRRNT_SRC_LOW_OFST) @@ -336,6 +360,7 @@ #define SAMPLE_DECMT_FACTOR_HALF_VAL ((0x1 << SAMPLE_DGTL_DECMT_FACTOR_OFST) & SAMPLE_DGTL_DECMT_FACTOR_MSK) #define SAMPLE_DECMT_FACTOR_QUARTER_VAL ((0x2 << SAMPLE_DGTL_DECMT_FACTOR_OFST) & SAMPLE_DGTL_DECMT_FACTOR_MSK) + /** Current Source Column 0 (0 - 31)) */ #define CRRNT_SRC_COL_LSB_REG (0x5A << MEM_MAP_SHIFT) @@ -366,10 +391,11 @@ #define DAQ_FIX_GAIN_STG_2_VAL ((0x3 << DAQ_FIX_GAIN_OFST) & DAQ_FIX_GAIN_MSK) #define DAQ_CMP_RST_OFST (4) #define DAQ_CMP_RST_MSK (0x00000001 << DAQ_CMP_RST_OFST) -#define DAQ_CHIP11_VRSN_OFST (7) -#define DAQ_CHIP11_VRSN_MSK (0x00000001 << DAQ_CHIP11_VRSN_OFST) -#define DAQ_STRG_CELL_SLCT_OFST (8) -#define DAQ_STRG_CELL_SLCT_MSK (0x0000000F << DAQ_STRG_CELL_SLCT_OFST) +#define DAQ_CHIP_VRSN_OFST (5) +#define DAQ_CHIP_VRSN_MSK (0x00000007 << DAQ_CHIP_VRSN_OFST) +#define DAQ_CHIP_VRSN_v1_0_VAL (0x0) +#define DAQ_CHIP_VRSN_v1_1_VAL (0x1) +#define DAQ_CHIP_VRSN_v1_2_VAL (0x2) #define DAQ_FRCE_SWTCH_GAIN_OFST (12) #define DAQ_FRCE_SWTCH_GAIN_MSK (0x00000003 << DAQ_FRCE_SWTCH_GAIN_OFST) #define DAQ_FRCE_GAIN_STG_0_VAL ((0x0 << DAQ_FRCE_SWTCH_GAIN_OFST) & DAQ_FRCE_SWTCH_GAIN_MSK) @@ -406,9 +432,7 @@ #define TEMP_CTRL_OVR_TMP_EVNT_OFST (31) #define TEMP_CTRL_OVR_TMP_EVNT_MSK (0x00000001 << TEMP_CTRL_OVR_TMP_EVNT_OFST) -/* Set Delay 64 bit register */ -#define SET_DELAY_LSB_REG (0x60 << MEM_MAP_SHIFT) // different kind of delay -#define SET_DELAY_MSB_REG (0x61 << MEM_MAP_SHIFT) // different kind of delay + /* Set Triggers 64 bit register */ #define SET_CYCLES_LSB_REG (0x62 << MEM_MAP_SHIFT) @@ -472,11 +496,6 @@ Time before end of exposure when comparator is disabled */ #define ASIC_CTRL_DS_TMR_MSK (0x000000FF << ASIC_CTRL_DS_TMR_OFST) #define ASIC_CTRL_DS_TMR_VAL ((0x1F << ASIC_CTRL_DS_TMR_OFST) & ASIC_CTRL_DS_TMR_MSK) #define ASIC_CTRL_DS_TMR_CHIP1_1_VAL ((0xFF << ASIC_CTRL_DS_TMR_OFST) & ASIC_CTRL_DS_TMR_MSK) -// tET = (ET + 1) * 25ns (increase timeout range between 2 consecutive storage -// cells) -#define ASIC_CTRL_EXPSRE_TMR_OFST (16) -#define ASIC_CTRL_EXPSRE_TMR_MSK (0x0000FFFF << ASIC_CTRL_EXPSRE_TMR_OFST) -#define ASIC_CTRL_EXPSRE_TMR_MAX_VAL (0x0000FFFF / (CLK_RUN * 1E-3)) /* ADC 0 Deserializer Control */ #define ADC_DSRLZR_0_REG (0xF0 << MEM_MAP_SHIFT) diff --git a/slsDetectorServers/jungfrauDetectorServer/bin/config_jungfrau.txt b/slsDetectorServers/jungfrauDetectorServer/bin/config_jungfrau.txt index 48fea871e..2e1997cb1 100755 --- a/slsDetectorServers/jungfrauDetectorServer/bin/config_jungfrau.txt +++ b/slsDetectorServers/jungfrauDetectorServer/bin/config_jungfrau.txt @@ -1,4 +1,9 @@ +#chipversion Options +#"v1.0" +#"v1.1" +#"v1.2 Normal" +#"v1.2 Low Noise" +#"v1.2 HDR" +#"v1.3 Burst Mode" - -#chip version version (multiplied by 10) -chipversion 11 +chipversion "v1.1" diff --git a/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer b/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer index 5223b4319..b03476a28 100755 Binary files a/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer and b/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer differ diff --git a/slsDetectorServers/jungfrauDetectorServer/config_jungfrau.txt b/slsDetectorServers/jungfrauDetectorServer/config_jungfrau.txt index 48fea871e..2e1997cb1 100755 --- a/slsDetectorServers/jungfrauDetectorServer/config_jungfrau.txt +++ b/slsDetectorServers/jungfrauDetectorServer/config_jungfrau.txt @@ -1,4 +1,9 @@ +#chipversion Options +#"v1.0" +#"v1.1" +#"v1.2 Normal" +#"v1.2 Low Noise" +#"v1.2 HDR" +#"v1.3 Burst Mode" - -#chip version version (multiplied by 10) -chipversion 11 +chipversion "v1.1" diff --git a/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c index 8d0d1379f..576b67f58 100644 --- a/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c @@ -46,6 +46,7 @@ int virtual_moduleid = 0; #endif enum detectorSettings thisSettings = UNINITIALIZED; +static enum CHIPINDEX chipIndex = v1_0; int highvoltage = 0; int dacValues[NDAC] = {}; int defaultDacValues[] = DEFAULT_DAC_VALS; @@ -53,11 +54,20 @@ int defaultDacValue_G0[] = SPECIAL_DEFAULT_DYNAMIC_GAIN_VALS; int defaultDacValue_HG0[] = SPECIAL_DEFAULT_DYNAMICHG0_GAIN_VALS; int32_t clkPhase[NUM_CLOCKS] = {}; int detPos[4] = {}; -int chipConfigured = 0; +bool chipConfigured = false; uint64_t normal_mode_frames = -1; uint64_t normal_mode_triggers = -1; +bool has_configure_chip = false; +bool has_storage_cells = false; +bool has_filter_resistor = false; +bool has_filter_cells = false; +bool has_current_src_normal = false; +bool has_current_src_64bit_selection = false; +bool has_current_src_reverse_bits_selection = false; +bool has_storage_start_in_chip_config = false; + int isInitCheckDone() { return initCheckDone; } int getInitResult(char **mess) { @@ -319,23 +329,160 @@ int isHardwareVersion_1_0() { return ((getHardwareVersionNumber() == hwNumberList[0]) ? 1 : 0); } -int getChipVersion() { - // chip v1.1 - if (bus_r(DAQ_REG) & DAQ_CHIP11_VRSN_MSK) { - return 11; +int getChipVersionInFPGA() { + const int vals[] = CHIP_VALS; + int val = ((bus_r(DAQ_REG) & DAQ_CHIP_VRSN_MSK) >> DAQ_CHIP_VRSN_OFST); + switch (val) { + case 0: + return vals[(int)v1_0]; + case 1: + return vals[(int)v1_1]; + case 2: + return vals[(int)v1_2_NORMAL] / 10; + default: + LOG(logERROR, + ("Read undefined value as chip version from FPGA: %d\n", val)); + return -1; } - // chip v1.0 - return 10; } -void setChipVersion(int version) { - LOG(logINFO, - ("Setting chip version to %0.1f in FPGA\n", (double)version / 10.0)); - if (version == 11) { - bus_w(DAQ_REG, bus_r(DAQ_REG) | DAQ_CHIP11_VRSN_MSK); - } else { - bus_w(DAQ_REG, bus_r(DAQ_REG) & ~DAQ_CHIP11_VRSN_MSK); +int findChipIndex(enum CHIPINDEX *ind, char *cval, char *mess) { + if (cval == NULL) { + sprintf(mess, "String value is NULL. Cannot find chip version.\n"); + LOG(logERROR, (mess)); + return FAIL; } + char *chip_names[] = {CHIP_NAMES}; + for (enum CHIPINDEX ichip = v1_0; ichip != NUM_CHIP_INDICES; ++ichip) { + if (strcmp(chip_names[ichip], cval) == 0) { + *ind = ichip; + return OK; + } + } + sprintf(mess, "Unknown chip version '%s'. Options: %s\n", cval, + CHIP_VALS_HELP); + LOG(logERROR, (mess)); + return FAIL; +} + +/** For backwards compatibility */ +int setChipVersionIntFromConfigFile(int val, char *mess) { + const int vals[] = CHIP_VALS; + if (val == vals[(int)v1_0]) + return setChipIndex(v1_0, mess); + else if (val == vals[(int)v1_1]) + return setChipIndex(v1_1, mess); + else { + sprintf(mess, "Invalid chip version %d. Options: %d and %d.\n", val, + vals[(int)v1_0], vals[(int)v1_1]); + LOG(logERROR, (mess)); + return FAIL; + } +} + +int setChipVersionStringFromConfigFile(char *cval, char *mess) { + enum CHIPINDEX ind = NUM_CHIP_INDICES; + if (findChipIndex(&ind, cval, mess) == FAIL) { + return FAIL; + } + return setChipIndex(ind, mess); +} + +int setChipIndex(enum CHIPINDEX ind, char *mess) { + if (validateChipIndex(ind, mess) == FAIL) { + return FAIL; + } + chipIndex = ind; + setChipIndexAllowedFeatures(); + return setChipVersionInFPGA(mess); +} + +int validateChipIndex(enum CHIPINDEX ind, char *mess) { + if (ind < 0 || ind >= NUM_CHIP_INDICES) { + sprintf(mess, "Invalid chip index %d. Options: %s\n", (int)ind, + CHIP_VALS_HELP); + LOG(logERROR, (mess)); + return FAIL; + } + + // chipversion > 1.0 and HW 1.0 is incompatible + if (ind > v1_0 && isHardwareVersion_1_0()) { + char *chip_names[] = {CHIP_NAMES}; + sprintf(mess, + "Chip index %d (%s) is incompatible with hardware version " + "v1.0. Please update board or correct chip index.\n", + (int)ind, chip_names[ind]); + return FAIL; + } + return OK; +} + +void setChipIndexAllowedFeatures() { + switch (chipIndex) { + case v1_0: + has_configure_chip = false; + has_storage_cells = true; + has_filter_resistor = false; + has_filter_cells = false; + has_current_src_normal = false; + has_current_src_64bit_selection = false; + has_current_src_reverse_bits_selection = false; + has_storage_start_in_chip_config = false; + break; + case v1_1: + has_configure_chip = true; + has_storage_cells = false; + has_filter_resistor = true; + has_filter_cells = true; + has_current_src_normal = true; + has_current_src_64bit_selection = true; + has_current_src_reverse_bits_selection = true; + has_storage_start_in_chip_config = true; + break; + case v1_2_NORMAL: + case v1_2_LOW_NOISE: + case v1_2_HDR: + has_configure_chip = true; + has_storage_cells = true; + has_filter_resistor = true; + has_filter_cells = false; + has_current_src_normal = true; + has_current_src_64bit_selection = true; + has_current_src_reverse_bits_selection = false; + has_storage_start_in_chip_config = true; + break; + default: + LOG(logERROR, ("Unknown chip index %d\n", (int)chipIndex)); + } +} + +int setChipVersionInFPGA(char *mess) { + uint32_t val = 0; + switch (chipIndex) { + case v1_0: + LOG(logINFO, ("Setting Chip Version 1.0 in FPGA\n")); + val = DAQ_CHIP_VRSN_v1_0_VAL; + break; + case v1_1: + LOG(logINFO, ("Setting Chip Version 1.1 in FPGA\n")); + val = DAQ_CHIP_VRSN_v1_1_VAL; + break; + case v1_2_NORMAL: + case v1_2_LOW_NOISE: + case v1_2_HDR: + LOG(logINFO, ("Setting Chip Version 1.2 in FPGA\n")); + val = DAQ_CHIP_VRSN_v1_2_VAL; + break; + default: + sprintf(mess, "Unknown chip index %d\n", (int)chipIndex); + LOG(logERROR, (mess)); + return FAIL; + } + + bus_w(DAQ_REG, bus_r(DAQ_REG) & ~DAQ_CHIP_VRSN_MSK); + bus_w(DAQ_REG, + bus_r(DAQ_REG) | ((val << DAQ_CHIP_VRSN_OFST) & DAQ_CHIP_VRSN_MSK)); + return OK; } u_int32_t getDetectorNumber() { @@ -460,7 +607,7 @@ void setupDetector() { for (int i = 0; i < NUM_CLOCKS; ++i) { clkPhase[i] = 0; } - chipConfigured = 0; + chipConfigured = false; #ifdef VIRTUAL if (isControlServer) { sharedMemory_setStatus(IDLE); @@ -549,14 +696,6 @@ void setupDetector() { setExpTime(DEFAULT_EXPTIME); setPeriod(DEFAULT_PERIOD); setDelayAfterTrigger(DEFAULT_DELAY); - if (getChipVersion() == 11) { - selectStoragecellStart(DEFAULT_STRG_CLL_STRT_CHIP11); - } else { - setNumAdditionalStorageCells(DEFAULT_NUM_STRG_CLLS); - selectStoragecellStart(DEFAULT_STRG_CLL_STRT); - // not applicable for chipv1.1 - setStorageCellDelay(DEFAULT_STRG_CLL_DLY); - } setTiming(DEFAULT_TIMING_MODE); setNextFrameNumber(DEFAULT_STARTING_FRAME_NUMBER); @@ -564,10 +703,20 @@ void setupDetector() { setTemperatureControl(DEFAULT_TMP_CNTRL); setThresholdTemperature(DEFAULT_TMP_THRSHLD); setTemperatureEvent(0); - if (getChipVersion() == 11) { - setFilterResistor(DEFAULT_FILTER_RESISTOR); - setNumberOfFilterCells(DEFAULT_FILTER_CELL); + + // chip specific features + if (hasStorageCellsFeature()) { + setNumAdditionalStorageCells(DEFAULT_NUM_STRG_CLLS); + setStorageCellDelay(DEFAULT_STRG_CLL_DLY); + setStorageCellStart(DEFAULT_STRG_CLL_STRT); + } else { + setStorageCellStart(DEFAULT_STRG_CLL_STRT_CHIP11); } + if (hasFilterResistorFeature()) + setFilterResistor(DEFAULT_FILTER_RESISTOR); + if (hasFilterCellsFeature()) + setNumberOfFilterCells(DEFAULT_FILTER_CELL); + if (!isHardwareVersion_1_0()) { setFlipRows(DEFAULT_FLIP_ROWS); setReadNRows(MAX_ROWS_PER_READOUT); @@ -793,35 +942,41 @@ int readConfigFile() { // chipversion command if (!strncmp(line, "chipversion", strlen("chipversion"))) { - int version = 0; + int val = 0; + char chipversion[SHORT_STR_LENGTH] = {0}; - // cannot scan values - if (sscanf(line, "%s %d", command, &version) != 2) { - sprintf( - initErrorMessage, - "Could not scan chipversion commands from on-board server " - "config file. Line:[%s].\n", - line); - break; + // backward compatibility: takes an int + if (sscanf(line, "%s %d", command, &val) == 2) { + if (setChipVersionIntFromConfigFile(val, initErrorMessage) == + FAIL) { + strcat(initErrorMessage, + "Could not set chip version from on-board server " + "config " + "file. For higher chip versions, use string " + "arguments from example server config file. " + "Line:[%s].\n"); + break; + } } - // validations - if (version != 10 && version != 11) { + + // updated argument takes a string without quotes + else if (sscanf(line, "%s \"%[^\"]\"", command, chipversion) == 2) { + if (setChipVersionStringFromConfigFile( + chipversion, initErrorMessage) == FAIL) { + strcat(initErrorMessage, + "Could not set chip version from on-board server " + "config file. Line:[%s].\n"); + break; + } + } + + else { sprintf(initErrorMessage, - "Could not set chip version from on-board server " - "config file. Invalid chip version %d. Line:[%s].\n", - version, line); + "Could not scan chipversion command from on-board " + "server config file. Line:[%s].\n", + line); break; } - // chipversion 1.1 and HW 1.0 is incompatible - if (version == 11 && isHardwareVersion_1_0()) { - strcpy(initErrorMessage, - "Chip version 1.1 (from on-board config file) is " - "incompatible with hardware version v1.0. Please update " - "board or correct on-board config file.\n"); - break; - } - - setChipVersion(version); } // other commands @@ -910,65 +1065,97 @@ uint32_t getADCInvertRegister() { } /* parameters - timer */ -int selectStoragecellStart(int pos) { - int value = pos; - uint32_t addr = DAQ_REG; - uint32_t mask = DAQ_STRG_CELL_SLCT_MSK; - int offset = DAQ_STRG_CELL_SLCT_OFST; - if (getChipVersion() == 11) { - // set the bit - value = 1 << pos; - addr = CONFIG_V11_REG; - mask = CONFIG_V11_STRG_CLL_MSK; - offset = CONFIG_V11_STRG_CLL_OFST; - } - if (pos >= 0) { - LOG(logINFO, ("Setting storage cell start: %d\n", pos)); - bus_w(addr, bus_r(addr) & ~mask); - bus_w(addr, bus_r(addr) | ((value << offset) & mask)); - // should not do a get to verify (status register does not update - // immediately during acquisition) - if (getChipVersion() == 11) { - return pos; - } - } - - // read value back - // chipv1.1, writing and reading registers are different -#ifndef VIRTUAL - if (getChipVersion() == 11) { - addr = CONFIG_V11_STATUS_REG; - mask = CONFIG_V11_STATUS_STRG_CLL_MSK; - offset = CONFIG_V11_STATUS_STRG_CLL_OFST; - } -#endif - uint32_t regval = bus_r(addr); -#ifndef VIRTUAL - // flip all contents of register //TODO FIRMWARE FIX - if (getChipVersion() == 11) { - regval ^= BIT32_MASK; - } -#endif - uint32_t retval = ((regval & mask) >> offset); - if (getChipVersion() == 11) { - // get which bit - int max = getMaxStoragecellStart(); - for (int i = 0; i != max + 1; ++i) { - if (retval & (1 << i)) { - return i; - } - } - } - // chip v1.0 - return retval; +int getStorageCellStartFromStorageCellReg() { + return ((bus_r(STORAGE_CELL_REG) & STORAGE_CELL_START_MSK) >> + STORAGE_CELL_START_OFST); } -int getMaxStoragecellStart() { - if (getChipVersion() == 11) { - return MAX_STORAGE_CELL_CHIP11_VAL; - } else { - return MAX_STORAGE_CELL_VAL; +void setStorageCellStartFromStorageCellReg(int pos) { + bus_w(STORAGE_CELL_REG, bus_r(STORAGE_CELL_REG) & ~STORAGE_CELL_START_MSK); + bus_w(STORAGE_CELL_REG, + bus_r(STORAGE_CELL_REG) | + ((pos << STORAGE_CELL_START_OFST) & STORAGE_CELL_START_MSK)); +} + +int getStorageCellStartFromChipConfig() { + // read from config status reg + uint32_t addr = CONFIG_V11_STATUS_REG; + uint32_t mask = CONFIG_V11_STATUS_STRG_CLL_MSK; + int offset = CONFIG_V11_STATUS_STRG_CLL_OFST; + if (chipIndex > v1_1) { + offset = CONFIG_V12_STATUS_STRG_CLL_OFST; + mask = CONFIG_V12_STATUS_STRG_CLL_MSK; } + + // get which bit + uint32_t regval = bus_r(addr); + // firmware fix: flip all contents of reg + regval ^= BIT32_MASK; // TODO for chipv1.2?? + uint32_t retval = ((regval & mask) >> offset); + int max = getMaxStorageCellStart(); + for (int i = 0; i != max + 1; ++i) { + if (retval & (1 << i)) { + return i; + } + } + LOG(logERROR, ("Could not read storage cell start from config status reg. " + "Read 0x%x, returning -1\n", + regval)); + return -1; +} + +void setStorageCellStartFromChipConfig(int pos) { + // write to chip config reg, which will later update status reg + uint32_t addr = CONFIG_V11_REG; + uint32_t mask = CONFIG_V11_STRG_CLL_MSK; + int offset = CONFIG_V11_STRG_CLL_OFST; + int value = 1 << pos; + + if (chipIndex > v1_1) { + offset = CONFIG_V12_STRG_CLL_OFST; + mask = CONFIG_V12_STRG_CLL_MSK; + } + + uint32_t regval = bus_r(addr); + bus_w(addr, regval & ~mask); + bus_w(addr, bus_r(addr) | ((value << offset) & mask)); +} + +int getStorageCellStart() { + bool using_chip_config = hasStorageCellStartInChipConfig(); +#ifdef VIRTUAL + using_chip_config = false; +#endif + if (using_chip_config) { + return getStorageCellStartFromChipConfig(); + } + return getStorageCellStartFromStorageCellReg(); +} + +int setStorageCellStart(int pos) { + LOG(logINFO, ("Setting storage cell start: %d\n", pos)); + setStorageCellStartFromStorageCellReg(pos); + + int retval = getStorageCellStartFromStorageCellReg(); + if (retval != pos) { + LOG(logERROR, ("Could not set storage cell start! Wrote %d, read %d\n", + pos, retval)); + return FAIL; + } + + if (!hasStorageCellStartInChipConfig()) + return OK; + + setStorageCellStartFromChipConfig(pos); + // not validating because the status register might not update during + return OK; +} + +int getMaxStorageCellStart() { + if (hasStorageCellsFeature()) + return MAX_STORAGE_CELL_VAL; + else + return MAX_STORAGE_CELL_CHIP11_VAL; } int setNextFrameNumber(uint64_t value) { @@ -1101,18 +1288,21 @@ int64_t getDelayAfterTrigger() { } void setNumAdditionalStorageCells(int val) { - if (val >= 0) { - LOG(logINFO, ("Setting number of addl. storage cells %d\n", val)); - bus_w(CONTROL_REG, - (bus_r(CONTROL_REG) & ~CONTROL_STORAGE_CELL_NUM_MSK) | - ((val << CONTROL_STORAGE_CELL_NUM_OFST) & - CONTROL_STORAGE_CELL_NUM_MSK)); + if (val < 0) { + LOG(logERROR, ("Invalid number of addl. storage cells %d\n", val)); + return; } + + LOG(logINFO, ("Setting number of addl. storage cells %d\n", val)); + bus_w(STORAGE_CELL_REG, + (bus_r(STORAGE_CELL_REG) & ~STORAGE_CELL_NUM_ADDTNL_MSK) | + ((val << STORAGE_CELL_NUM_ADDTNL_OFST) & + STORAGE_CELL_NUM_ADDTNL_MSK)); } int getNumAdditionalStorageCells() { - return ((bus_r(CONTROL_REG) & CONTROL_STORAGE_CELL_NUM_MSK) >> - CONTROL_STORAGE_CELL_NUM_OFST); + return ((bus_r(STORAGE_CELL_REG) & STORAGE_CELL_NUM_ADDTNL_MSK) >> + STORAGE_CELL_NUM_ADDTNL_OFST); } int setStorageCellDelay(int64_t val) { @@ -1123,9 +1313,10 @@ int setStorageCellDelay(int64_t val) { } LOG(logINFO, ("Setting storage cell delay %lld ns\n", (long long int)val)); val *= (1E-3 * CLK_RUN); - bus_w(ASIC_CTRL_REG, - (bus_r(ASIC_CTRL_REG) & ~ASIC_CTRL_EXPSRE_TMR_MSK) | - ((val << ASIC_CTRL_EXPSRE_TMR_OFST) & ASIC_CTRL_EXPSRE_TMR_MSK)); + bus_w(STORAGE_CELL_REG, + (bus_r(STORAGE_CELL_REG) & ~STORAGE_CELL_EXPSRE_TMR_MSK) | + ((val << STORAGE_CELL_EXPSRE_TMR_OFST) & + STORAGE_CELL_EXPSRE_TMR_MSK)); // validate for tolerance int64_t retval = getStorageCellDelay(); @@ -1137,9 +1328,10 @@ int setStorageCellDelay(int64_t val) { } int64_t getStorageCellDelay() { - return (((int64_t)((bus_r(ASIC_CTRL_REG) & ASIC_CTRL_EXPSRE_TMR_MSK) >> - ASIC_CTRL_EXPSRE_TMR_OFST)) / - (1E-3 * CLK_RUN)); + return ( + ((int64_t)((bus_r(STORAGE_CELL_REG) & STORAGE_CELL_EXPSRE_TMR_MSK) >> + STORAGE_CELL_EXPSRE_TMR_OFST)) / + (1E-3 * CLK_RUN)); } int64_t getNumFramesLeft() { @@ -1229,7 +1421,6 @@ int setSettings(enum detectorSettings sett, char *mess) { return FAIL; } - // if chipv1.1 and powered on configureChip(); return OK; @@ -1992,7 +2183,7 @@ int powerChip(int on) { bus_w(CHIP_POWER_REG, bus_r(CHIP_POWER_REG) & ~CHIP_POWER_ENABLE_MSK); - chipConfigured = 0; + chipConfigured = false; } } #ifdef VIRTUAL @@ -2003,11 +2194,32 @@ int powerChip(int on) { CHIP_POWER_STATUS_OFST); } -int isChipConfigured() { return chipConfigured; } +bool requireChipConfiguration() { return has_configure_chip; } + +bool hasStorageCellsFeature() { return has_storage_cells; } + +bool hasFilterResistorFeature() { return has_filter_resistor; } + +bool hasFilterCellsFeature() { return has_filter_cells; } + +bool hasCurrentSourceNormalFeature() { return has_current_src_normal; } + +bool hasCurrentSource64BitSelectionFeature() { + return has_current_src_64bit_selection; +} + +bool hasCurrentSourceReverseBitsSelectionFeature() { + return has_current_src_reverse_bits_selection; +} + +bool hasStorageCellStartInChipConfig() { + return has_storage_start_in_chip_config; +} + +bool isChipConfigured() { return chipConfigured; } void configureChip() { - // only for chipv1.1 and chip is powered on - if (getChipVersion() == 11 && powerChip(-1)) { + if (requireChipConfiguration() && powerChip(-1)) { LOG(logINFOBLUE, ("\tConfiguring chip\n")); // waiting 500 ms before configuring selection @@ -2026,7 +2238,7 @@ void configureChip() { bus_w(CONFIG_V11_REG, bus_r(CONFIG_V11_REG)); LOG(logINFOBLUE, ("\tChip configured\n")); - chipConfigured = 1; + chipConfigured = true; } } @@ -2074,9 +2286,10 @@ void configureASICTimer() { bus_w(ASIC_CTRL_REG, (bus_r(ASIC_CTRL_REG) & ~ASIC_CTRL_PRCHRG_TMR_MSK) | ASIC_CTRL_PRCHRG_TMR_VAL); - uint32_t val = ASIC_CTRL_DS_TMR_VAL; - if (getChipVersion() == 11) { - val = ASIC_CTRL_DS_TMR_CHIP1_1_VAL; + uint32_t val = ASIC_CTRL_DS_TMR_CHIP1_1_VAL; + // TODO: value of chipindex v1_2 value to be decided. + if (chipIndex == v1_0) { + val = ASIC_CTRL_DS_TMR_VAL; } bus_w(ASIC_CTRL_REG, (bus_r(ASIC_CTRL_REG) & ~ASIC_CTRL_DS_TMR_MSK) | val); LOG(logINFO, ("Configured ASIC Timer [0x%x]\n", bus_r(ASIC_CTRL_REG))); @@ -2095,14 +2308,14 @@ int setReadoutSpeed(int val) { uint32_t config = CONFIG_FULL_SPEED_40MHZ_VAL; switch (val) { - + // tODO: calculate values for chip v1.2 case FULL_SPEED: if (isHardwareVersion_1_0()) { LOG(logERROR, ("Cannot set full speed. Should not be here\n")); return FAIL; } LOG(logINFO, ("Setting Full Speed (40 MHz):\n")); - if (getChipVersion() == 10) { + if (chipIndex == v1_0) { sampleAdcSpeed = SAMPLE_ADC_FULL_SPEED_CHIP10; adcPhase = ADC_PHASE_FULL_SPEED_CHIP10; dbitPhase = DBIT_PHASE_FULL_SPEED_CHIP10; @@ -2123,7 +2336,7 @@ int setReadoutSpeed(int val) { sampleAdcSpeed = SAMPLE_ADC_HALF_SPEED_BOARD2; adcPhase = ADC_PHASE_HALF_SPEED_BOARD2; dbitPhase = DBIT_PHASE_HALF_SPEED_BOARD2; - } else if (getChipVersion() == 10) { + } else if (chipIndex == v1_0) { adcOfst = ADC_OFST_HALF_SPEED_VAL_CHIP10; sampleAdcSpeed = SAMPLE_ADC_HALF_SPEED_CHIP10; adcPhase = ADC_PHASE_HALF_SPEED_CHIP10; @@ -2144,7 +2357,7 @@ int setReadoutSpeed(int val) { sampleAdcSpeed = SAMPLE_ADC_QUARTER_SPEED_BOARD2; adcPhase = ADC_PHASE_QUARTER_SPEED_BOARD2; dbitPhase = DBIT_PHASE_QUARTER_SPEED_BOARD2; - } else if (getChipVersion() == 10) { + } else if (chipIndex == v1_0) { adcOfst = ADC_OFST_QUARTER_SPEED_VAL_CHIP10; sampleAdcSpeed = SAMPLE_ADC_QUARTER_SPEED_CHIP10; adcPhase = ADC_PHASE_QUARTER_SPEED_CHIP10; @@ -2490,7 +2703,7 @@ void disableCurrentSource() { LOG(logINFO, ("Disabling Current Source\n")); // set default values for current source first - if (getChipVersion() == 11) { + if (hasCurrentSource64BitSelectionFeature()) { LOG(logINFO, ("\tSetting default values for selection\n")) bus_w(CRRNT_SRC_COL_LSB_REG, BIT32_MASK); bus_w(CRRNT_SRC_COL_MSB_REG, BIT32_MASK); @@ -2504,15 +2717,8 @@ void disableCurrentSource() { void enableCurrentSource(int fix, uint64_t select, int normal) { disableCurrentSource(); - - if (getChipVersion() == 11) { - LOG(logINFO, ("Enabling current source [fix:%d, select:0x%lx]\n", fix, - (long unsigned int)select)); - } else { - LOG(logINFO, - ("Enabling current source [fix:%d, select:%ld, normal:%d]\n", fix, - (long int)select, normal)); - } + LOG(logINFO, ("Enabling current source [fix:%d, select:0x%lx, normal:%d]\n", + fix, (long unsigned int)select, normal)); // fix if (fix) { LOG(logINFO, ("\tEnabling fix\n")); @@ -2521,29 +2727,39 @@ void enableCurrentSource(int fix, uint64_t select, int normal) { LOG(logINFO, ("\tDisabling fix\n")); bus_w(DAQ_REG, bus_r(DAQ_REG) & ~DAQ_CRRNT_SRC_CLMN_FIX_MSK); } - if (getChipVersion() == 10) { - // select + + // select (not 64 bits) + if (!hasCurrentSource64BitSelectionFeature()) { LOG(logINFO, ("\tSetting selection to %ld\n", (long int)select)); bus_w(DAQ_REG, bus_r(DAQ_REG) & ~DAQ_CRRNT_SRC_CLMN_SLCT_MSK); bus_w(DAQ_REG, bus_r(DAQ_REG) | ((select << DAQ_CRRNT_SRC_CLMN_SLCT_OFST) & DAQ_CRRNT_SRC_CLMN_SLCT_MSK)); - } else { - // select - // invert select first - uint64_t tmp = select; - uint64_t inverted = 0; - for (int i = 0; i != 64; ++i) { - // get each bit from LSB side - uint64_t bit = (tmp >> i) & 0x1; - // push the bit into MSB side - inverted |= (bit << (63 - i)); - } - LOG(logINFO, ("\tSetting selection to 0x%lx (inverted from 0x%lx)\n", - (long unsigned int)inverted, (long unsigned int)select)); - set64BitReg(inverted, CRRNT_SRC_COL_LSB_REG, CRRNT_SRC_COL_MSB_REG); + } + // select (64 bits) + else { + uint64_t retval = 0; + // reverse bits select first + if (hasCurrentSourceReverseBitsSelectionFeature()) { + uint64_t tmp = select; + for (int i = 0; i != 64; ++i) { + // get each bit from LSB side + uint64_t bit = (tmp >> i) & 0x1; + // push the bit into MSB side + retval |= (bit << (63 - i)); + } + } else { + retval = select; + } + + LOG(logINFO, ("\tSetting selection to 0x%lx (inverted from 0x%lx)\n", + (long unsigned int)retval, (long unsigned int)select)); + set64BitReg(retval, CRRNT_SRC_COL_LSB_REG, CRRNT_SRC_COL_MSB_REG); + } + + if (hasCurrentSourceNormalFeature()) { // normal if (normal) { LOG(logINFO, ("\tEnabling normal\n")) @@ -2555,6 +2771,7 @@ void enableCurrentSource(int fix, uint64_t select, int normal) { bus_r(CONFIG_V11_REG) | CONFIG_V11_CRRNT_SRC_LOW_MSK); } } + // validating before enabling current source if (getFixCurrentSource() != fix || getSelectCurrentSource() != select) { LOG(logERROR, @@ -2582,7 +2799,7 @@ int getFixCurrentSource() { } int getNormalCurrentSource() { - if (getChipVersion() == 11) { + if (hasCurrentSourceNormalFeature()) { int low = ((bus_r(CONFIG_V11_STATUS_REG) & CONFIG_V11_STATUS_CRRNT_SRC_LOW_MSK) >> CONFIG_V11_STATUS_CRRNT_SRC_LOW_OFST); @@ -2592,23 +2809,27 @@ int getNormalCurrentSource() { } uint64_t getSelectCurrentSource() { - if (getChipVersion() == 10) { + if (!hasCurrentSourceNormalFeature()) { return ((bus_r(DAQ_REG) & DAQ_CRRNT_SRC_CLMN_SLCT_MSK) >> DAQ_CRRNT_SRC_CLMN_SLCT_OFST); } else { // invert the select - uint64_t retval = + uint64_t regval = get64BitReg(CRRNT_SRC_COL_LSB_REG, CRRNT_SRC_COL_MSB_REG); - uint64_t tmp = retval; - uint64_t inverted = 0; - for (int i = 0; i != 64; ++i) { - // get each bit from LSB side - uint64_t bit = (tmp >> i) & 0x1; - // push the bit into MSB side - inverted |= (bit << (63 - i)); + uint64_t retval = regval; + if (hasCurrentSourceReverseBitsSelectionFeature()) { + uint64_t tmp = regval; + uint64_t inverted = 0; + for (int i = 0; i != 64; ++i) { + // get each bit from LSB side + uint64_t bit = (tmp >> i) & 0x1; + // push the bit into MSB side + inverted |= (bit << (63 - i)); + } + retval = inverted; } - return inverted; + return retval; } } diff --git a/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.h b/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.h index b775ff0e1..4bf1e385d 100644 --- a/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.h +++ b/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.h @@ -57,8 +57,15 @@ void getHardwareVersion(char *version); u_int16_t getHardwareVersionNumber(); u_int16_t getHardwareSerialNumber(); int isHardwareVersion_1_0(); -int getChipVersion(); -void setChipVersion(int version); +int getChipVersionInFPGA(); +int findChipIndex(enum CHIPINDEX *ind, char *cval, char *mess); +int setChipVersionIntFromConfigFile(int val, + char *mess); // for backward compatibility +int setChipVersionStringFromConfigFile(char *cval, char *mess); +int setChipIndex(enum CHIPINDEX ind, char *mess); +int validateChipIndex(enum CHIPINDEX ind, char *mess); +void setChipIndexAllowedFeatures(); +int setChipVersionInFPGA(char *mess); u_int32_t getDetectorNumber(); int getModuleId(int *ret, char *mess); int updateModuleId(); @@ -89,8 +96,13 @@ void setADCInvertRegister(uint32_t val); uint32_t getADCInvertRegister(); // parameters - timer -int selectStoragecellStart(int pos); -int getMaxStoragecellStart(); +int getStorageCellStartFromStorageCellReg(); +void setStorageCellStartFromStorageCellReg(int pos); +int getStorageCellStartFromChipConfig(); +void setStorageCellStartFromChipConfig(int pos); +int getStorageCellStart(); +int setStorageCellStart(int pos); +int getMaxStorageCellStart(); int setNextFrameNumber(uint64_t value); int getNextFrameNumber(uint64_t *value); void setNumFrames(int64_t val); @@ -169,7 +181,15 @@ int setReadNRows(int value); int getReadNRows(); void initReadoutConfiguration(); int powerChip(int on); -int isChipConfigured(); +bool requireChipConfiguration(); +bool hasStorageCellsFeature(); +bool hasFilterResistorFeature(); +bool hasFilterCellsFeature(); +bool hasCurrentSourceNormalFeature(); +bool hasCurrentSource64BitSelectionFeature(); +bool hasCurrentSourceReverseBitsSelectionFeature(); +bool hasStorageCellStartInChipConfig(); +bool isChipConfigured(); void configureChip(); int autoCompDisable(int on); int setComparatorDisableTime(int64_t val); diff --git a/slsDetectorServers/jungfrauDetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/jungfrauDetectorServer/slsDetectorServer_defs.h index cc2b0928b..580e3d295 100644 --- a/slsDetectorServers/jungfrauDetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/jungfrauDetectorServer/slsDetectorServer_defs.h @@ -5,8 +5,8 @@ #include "sls/sls_detector_defs.h" #define MIN_REQRD_VRSN_T_RD_API 0x171220 -#define REQRD_FRMWRE_VRSN_BOARD2 0x250209 // 1.0 pcb (version = 010) -#define REQRD_FRMWRE_VRSN 0x250208 // 2.0 pcb (version = 011) +#define REQRD_FRMWRE_VRSN_BOARD2 0x260814 // 1.0 pcb (version = 010) +#define REQRD_FRMWRE_VRSN 0x260813 // 2.0 pcb (version = 011) #define NUM_HARDWARE_VERSIONS (2) #define HARDWARE_VERSION_NUMBERS \ @@ -78,7 +78,7 @@ #define MAX_THRESHOLD_TEMP_VAL (127999) // millidegrees #define MAX_STORAGE_CELL_VAL (15) // 0xF #define MAX_STORAGE_CELL_CHIP11_VAL (3) -#define MAX_STORAGE_CELL_DLY_NS_VAL (ASIC_CTRL_EXPSRE_TMR_MAX_VAL) +#define MAX_STORAGE_CELL_DLY_NS_VAL (STORAGE_CELL_EXPSRE_TMR_MAX_VAL) #define ACQ_TIME_MIN_CLOCK (2) #define ASIC_FILTER_MAX_RES_VALUE (1) #define MAX_SELECT_CHIP10_VAL (63) @@ -211,6 +211,22 @@ enum DACINDEX { 420 /* J_VREF_COMP */ \ }; +enum CHIPINDEX { + v1_0, + v1_1, + v1_2_NORMAL, + v1_2_LOW_NOISE, + v1_2_HDR, + v1_3_BURST_MODE, + NUM_CHIP_INDICES +}; + +#define CHIP_VALS {10, 11, 120, 121, 122, 13}; +#define CHIP_VALS_HELP "10, 11, 120, 121, 122, 13" +#define CHIP_NAMES \ + "v1.0", "v1.1", "v1.2 Normal", "v1.2 Low Noise", "v1.2 HDR", \ + "v1.3 Burst Mode" + enum MASTERINDEX { MASTER_HARDWARE, OW_MASTER, OW_SLAVE }; #define MASTER_NAMES "hardware", "master", "slave" diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 7e5521aed..5f8617afa 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -1859,108 +1859,103 @@ int acquire(int blocking, int file_des) { else #endif #if defined(JUNGFRAUD) - // chipv1.1 has to be configured before acquisition - if (getChipVersion() == 11 && !isChipConfigured()) { - ret = FAIL; - strcpy(mess, - "Could not start acquisition. Chip is not configured. " - "Power it on to configure it.\n"); - LOG(logERROR, (mess)); - } else + if (requireChipConfiguration() && !isChipConfigured()) { + ret = FAIL; + strcpy(mess, "Could not start acquisition. Chip is not configured. " + "Power it on to configure it.\n"); + LOG(logERROR, (mess)); + } else #endif #if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD) - if ((getReadoutMode() == ANALOG_AND_DIGITAL || - getReadoutMode() == ANALOG_ONLY) && - (getNumAnalogSamples() <= 0)) { - ret = FAIL; - sprintf(mess, - "Could not start acquisition. Invalid number of analog " - "samples: %d.\n", - getNumAnalogSamples()); - LOG(logERROR, (mess)); - } else if ((getReadoutMode() == ANALOG_AND_DIGITAL || - getReadoutMode() == DIGITAL_ONLY || - getReadoutMode() == DIGITAL_AND_TRANSCEIVER) && - (getNumDigitalSamples() <= 0)) { - ret = FAIL; - sprintf( - mess, + if ((getReadoutMode() == ANALOG_AND_DIGITAL || + getReadoutMode() == ANALOG_ONLY) && + (getNumAnalogSamples() <= 0)) { + ret = FAIL; + sprintf(mess, + "Could not start acquisition. Invalid number of analog " + "samples: %d.\n", + getNumAnalogSamples()); + LOG(logERROR, (mess)); + } else if ((getReadoutMode() == ANALOG_AND_DIGITAL || + getReadoutMode() == DIGITAL_ONLY || + getReadoutMode() == DIGITAL_AND_TRANSCEIVER) && + (getNumDigitalSamples() <= 0)) { + ret = FAIL; + sprintf(mess, "Could not start acquisition. Invalid number of digital " "samples: %d.\n", getNumDigitalSamples()); - LOG(logERROR, (mess)); - } else if ((getReadoutMode() == TRANSCEIVER_ONLY || - getReadoutMode() == DIGITAL_AND_TRANSCEIVER) && - (getNumTransceiverSamples() <= 0)) { - ret = FAIL; - sprintf(mess, - "Could not start acquisition. Invalid number of " - "transceiver " - "samples: %d.\n", - getNumTransceiverSamples()); - LOG(logERROR, (mess)); - } else + LOG(logERROR, (mess)); + } else if ((getReadoutMode() == TRANSCEIVER_ONLY || + getReadoutMode() == DIGITAL_AND_TRANSCEIVER) && + (getNumTransceiverSamples() <= 0)) { + ret = FAIL; + sprintf(mess, + "Could not start acquisition. Invalid number of " + "transceiver " + "samples: %d.\n", + getNumTransceiverSamples()); + LOG(logERROR, (mess)); + } else #endif #ifdef EIGERD - // check for hardware mac and hardware ip - if (udpDetails[0].srcmac != getDetectorMAC()) { - ret = FAIL; - uint64_t sourcemac = getDetectorMAC(); - char src_mac[MAC_ADDRESS_SIZE]; - getMacAddressinString(src_mac, MAC_ADDRESS_SIZE, sourcemac); - sprintf(mess, - "Invalid udp source mac address for this detector. " - "Must be " - "same as hardware detector mac address %s\n", - src_mac); - LOG(logERROR, (mess)); - } else if (!enableTenGigabitEthernet(GET_FLAG) && - (udpDetails[0].srcip != getDetectorIP())) { - ret = FAIL; - uint32_t sourceip = getDetectorIP(); - char src_ip[INET_ADDRSTRLEN]; - getIpAddressinString(src_ip, sourceip); - sprintf( - mess, + // check for hardware mac and hardware ip + if (udpDetails[0].srcmac != getDetectorMAC()) { + ret = FAIL; + uint64_t sourcemac = getDetectorMAC(); + char src_mac[MAC_ADDRESS_SIZE]; + getMacAddressinString(src_mac, MAC_ADDRESS_SIZE, sourcemac); + sprintf(mess, + "Invalid udp source mac address for this detector. " + "Must be " + "same as hardware detector mac address %s\n", + src_mac); + LOG(logERROR, (mess)); + } else if (!enableTenGigabitEthernet(GET_FLAG) && + (udpDetails[0].srcip != getDetectorIP())) { + ret = FAIL; + uint32_t sourceip = getDetectorIP(); + char src_ip[INET_ADDRSTRLEN]; + getIpAddressinString(src_ip, sourceip); + sprintf(mess, "Invalid udp source ip address for this detector. Must " "be " "same as hardware detector ip address %s in 1G readout " "mode \n", src_ip); - LOG(logERROR, (mess)); - } else + LOG(logERROR, (mess)); + } else #endif - if (configured == FAIL) { + if (configured == FAIL) { + ret = FAIL; + strcpy(mess, "Could not start acquisition because "); + strcat(mess, configureMessage); + LOG(logERROR, (mess)); + } else if (sharedMemory_getScanStatus() == RUNNING) { + ret = FAIL; + strcpy(mess, "Could not start acquisition because a scan is " + "already running!\n"); + LOG(logERROR, (mess)); + } else { + memset(scanErrMessage, 0, MAX_STR_LENGTH); + sharedMemory_setScanStop(0); + sharedMemory_setScanStatus(IDLE); // if it was error + if (pthread_create(&pthread_tid, NULL, &start_state_machine, + &blocking)) { ret = FAIL; - strcpy(mess, "Could not start acquisition because "); - strcat(mess, configureMessage); - LOG(logERROR, (mess)); - } else if (sharedMemory_getScanStatus() == RUNNING) { - ret = FAIL; - strcpy(mess, - "Could not start acquisition because a scan is " - "already running!\n"); + strcpy(mess, "Could not start acquisition thread!\n"); LOG(logERROR, (mess)); } else { - memset(scanErrMessage, 0, MAX_STR_LENGTH); - sharedMemory_setScanStop(0); - sharedMemory_setScanStatus(IDLE); // if it was error - if (pthread_create(&pthread_tid, NULL, &start_state_machine, - &blocking)) { - ret = FAIL; - strcpy(mess, "Could not start acquisition thread!\n"); - LOG(logERROR, (mess)); - } else { - // wait for blocking always (scan or not) - // non blocking-no scan also wait (for error message) - // non blcoking-scan dont wait (there is - // scanErrorMessage) - if (blocking || !scan) { - pthread_join(pthread_tid, NULL); - } else - pthread_detach(pthread_tid); - } + // wait for blocking always (scan or not) + // non blocking-no scan also wait (for error message) + // non blcoking-scan dont wait (there is + // scanErrorMessage) + if (blocking || !scan) { + pthread_join(pthread_tid, NULL); + } else + pthread_detach(pthread_tid); } + } } return Server_SendResult(file_des, INT32, NULL, 0); } @@ -2282,15 +2277,15 @@ int set_num_additional_storage_cells(int file_des) { #else // only set if (Server_VerifyLock() == OK) { - if (getChipVersion() == 11) { + if (!hasStorageCellsFeature()) { ret = FAIL; - sprintf(mess, - "Cannot set addl. number of storage cells for chip v1.1\n"); + sprintf(mess, "Cannot set addl. number of storage cells for this " + "chip version\n"); LOG(logERROR, (mess)); - } else if (arg > getMaxStoragecellStart()) { + } else if (arg > getMaxStorageCellStart()) { ret = FAIL; sprintf(mess, "Max Storage cell number should not exceed %d\n", - getMaxStoragecellStart()); + getMaxStorageCellStart()); LOG(logERROR, (mess)); } else { setNumAdditionalStorageCells(arg); @@ -2750,9 +2745,10 @@ int get_storage_cell_delay(int file_des) { functionNotImplemented(); #else // get only - if (getChipVersion() == 11) { + if (!hasStorageCellsFeature()) { ret = FAIL; - strcpy(mess, "Storage cell delay is not applicable for chipv 1.1\n"); + strcpy(mess, + "Storage cell delay is not applicable for this chip version\n"); LOG(logERROR, (mess)); } else { retval = getStorageCellDelay(); @@ -2778,10 +2774,11 @@ int set_storage_cell_delay(int file_des) { #else // only set if (Server_VerifyLock() == OK) { - if (getChipVersion() == 11) { + if (!hasStorageCellsFeature()) { ret = FAIL; - strcpy(mess, - "Storage cell delay is not applicable for chipv 1.1\n"); + strcpy( + mess, + "Storage cell delay is not applicable for this chip version\n"); LOG(logERROR, (mess)); } else if (arg > MAX_STORAGE_CELL_DLY_NS_VAL) { ret = FAIL; @@ -4131,15 +4128,22 @@ int storage_cell_start(int file_des) { #else // set & get if ((arg == GET_FLAG) || (Server_VerifyLock() == OK)) { - if (arg > getMaxStoragecellStart()) { + if (arg > getMaxStorageCellStart()) { ret = FAIL; sprintf(mess, "Max Storage cell number should not exceed %d\n", - getMaxStoragecellStart()); + getMaxStorageCellStart()); LOG(logERROR, (mess)); } else { - retval = selectStoragecellStart(arg); - LOG(logDEBUG1, ("Storage cell start: %d\n", retval)); - validate(&ret, mess, arg, retval, "set storage cell start", DEC); + if (arg >= 0) { + ret = setStorageCellStart(arg); + if (ret == FAIL) { + strcpy(mess, "Could not set storage cell start\n"); + LOG(logERROR, (mess)); + } + } else { + retval = getStorageCellStart(); + LOG(logDEBUG1, ("Storage cell start: %d\n", retval)); + } } } #endif @@ -6734,17 +6738,20 @@ int set_current_source(int file_des) { strcpy(mess, "Could not enable/disable current source. Enable can " "be 0 or 1 only.\n"); LOG(logERROR, (mess)); + return Server_SendResult(file_des, INT32, NULL, 0); } // disable - else if (enable == 0 && (fix != -1 || normal != -1)) { - ret = FAIL; - strcpy( - mess, - "Could not disable current source. Requires no parameters.\n"); - LOG(logERROR, (mess)); + if (enable == 0) { + if (fix != -1 || normal != -1) { + ret = FAIL; + strcpy(mess, "Could not disable current source. Requires no " + "parameters.\n"); + LOG(logERROR, (mess)); + return Server_SendResult(file_des, INT32, NULL, 0); + } } // enable - else if (enable == 1) { + else { #ifdef GOTTHARD2D // no parameters allowed if (fix != -1 || normal != -1) { @@ -6752,65 +6759,60 @@ int set_current_source(int file_des) { strcpy(mess, "Could not enable current source. Fix and normal " "are invalid parameters for this detector.\n"); LOG(logERROR, (mess)); + return Server_SendResult(file_des, INT32, NULL, 0); } #else - int chipVersion = getChipVersion(); - if (ret == OK) { - if (chipVersion == 11) { - // require both - if ((fix != 0 && fix != 1) || - (normal != 0 && normal != 1)) { - ret = FAIL; - strcpy(mess, "Could not enable current source. Invalid " - "or insufficient parameters (fix or " - "normal). or Options: 0 or 1.\n"); - LOG(logERROR, (mess)); - } - } - // chipv1.0 - else { - // require only fix - if (fix != 0 && fix != 1) { - ret = FAIL; - strcpy(mess, - "Could not enable current source. Invalid value " - "for parameter (fix). Options: 0 or 1.\n"); - LOG(logERROR, (mess)); - } else if (normal != -1) { - ret = FAIL; - strcpy(mess, "Could not enable current source. Invalid " - "parmaeter (normal). Require only fix and " - "select for chipv1.0.\n"); - LOG(logERROR, (mess)); - } - // select can only be 0-63 - else if (select > MAX_SELECT_CHIP10_VAL) { - ret = FAIL; - strcpy(mess, - "Could not enable current source. Invalid value " - "for parameter (select). Options: 0-63.\n"); - LOG(logERROR, (mess)); - } + // fix + if (fix != 0 && fix != 1) { + ret = FAIL; + strcpy(mess, "Could not enable current source. Invalid value " + "for parameter (fix). Options: 0 or 1.\n"); + LOG(logERROR, (mess)); + return Server_SendResult(file_des, INT32, NULL, 0); + } + + // normal + if (hasCurrentSourceNormalFeature()) { + if (normal != 0 && normal != 1) { + ret = FAIL; + strcpy(mess, + "Could not enable current source. Invalid value for " + "parameter (normal). Options: 0 or 1.\n"); + LOG(logERROR, (mess)); + return Server_SendResult(file_des, INT32, NULL, 0); } + } else if (normal != -1) { + ret = FAIL; + strcpy(mess, + "Could not enable current source. Invalid parameter " + "(normal). Not supported for this chip version.\n"); + LOG(logERROR, (mess)); + return Server_SendResult(file_des, INT32, NULL, 0); + } + + // select (only 0-63) + if (!hasCurrentSource64BitSelectionFeature() && + select > MAX_SELECT_CHIP10_VAL) { + ret = FAIL; + strcpy(mess, "Could not enable current source. Invalid value " + "for parameter (select). Options: 0-63.\n"); + LOG(logERROR, (mess)); + return Server_SendResult(file_des, INT32, NULL, 0); } #endif } - if (ret == OK) { #if defined(JUNGFRAUD) - if (enable == 0) { - disableCurrentSource(); - } else { - enableCurrentSource(fix, select, normal); - } + if (enable == 0) + disableCurrentSource(); + else + enableCurrentSource(fix, select, normal); #else - setCurrentSource(enable); + setCurrentSource(enable); #endif - int retval = getCurrentSource(); - LOG(logDEBUG1, ("current source enable retval: %u\n", retval)); - validate(&ret, mess, enable, retval, "set current source enable", - DEC); - } + int retval = getCurrentSource(); + LOG(logDEBUG1, ("current source enable retval: %u\n", retval)); + validate(&ret, mess, enable, retval, "set current source enable", DEC); } #endif return Server_SendResult(file_des, INT32, NULL, 0); @@ -7923,10 +7925,10 @@ int get_filter_resistor(int file_des) { #else // get only #if defined(JUNGFRAUD) - if (getChipVersion() == 10) { + if (!hasFilterResistorFeature()) { ret = FAIL; - strcpy(mess, "Could not get filter cell. Not available for this chip " - "version 1.0.\n"); + strcpy(mess, "Could not get filter resistor. Not available for this " + "chip version.\n"); LOG(logERROR, (mess)); } #endif @@ -7962,10 +7964,11 @@ int set_filter_resistor(int file_des) { LOG(logERROR, (mess)); } #if defined(JUNGFRAUD) - else if (getChipVersion() == 10) { + else if (!hasFilterResistorFeature()) { ret = FAIL; - strcpy(mess, "Could not set filter cell. Not available for this " - "chip version 1.0.\n"); + strcpy(mess, + "Could not set filter resistor. Not available for this " + "chip version.\n"); LOG(logERROR, (mess)); } #endif @@ -8701,7 +8704,7 @@ int get_chip_version(int file_des) { #if !defined(JUNGFRAUD) functionNotImplemented(); #else - retval = getChipVersion(); + retval = getChipVersionInFPGA(); #endif LOG(logDEBUG1, ("chip version retval: %d\n", retval)); return Server_SendResult(file_des, INT32, &retval, sizeof(retval)); @@ -8981,11 +8984,10 @@ int get_num_filter_cells(int file_des) { functionNotImplemented(); #else // get only - // only for chipv1.1 - if (getChipVersion() == 10) { + if (!hasFilterCellsFeature()) { ret = FAIL; - strcpy(mess, "Could not get number of filter cells. Only available for " - "chip version 1.1\n"); + strcpy(mess, "Could not get number of filter cells. Not available for " + "this chip version.\n"); LOG(logERROR, (mess)); } else { retval = getNumberOfFilterCells(); @@ -9018,13 +9020,10 @@ int set_num_filter_cells(int file_des) { "0 - %d\n", arg, MAX_FILTER_CELL_VAL); LOG(logERROR, (mess)); - } - // only for chipv1.1 - else if (getChipVersion() == 10) { + } else if (!hasFilterCellsFeature()) { ret = FAIL; - strcpy(mess, - "Could not set number of filter cells. Only available for " - "chip version 1.1\n"); + strcpy(mess, "Could not set number of filter cells. Not available " + "for this chip version.\n"); LOG(logERROR, (mess)); } else { setNumberOfFilterCells(arg); diff --git a/slsDetectorSoftware/generator/commands.yaml b/slsDetectorSoftware/generator/commands.yaml index 87ca6ad0b..6b84ffff1 100644 --- a/slsDetectorSoftware/generator/commands.yaml +++ b/slsDetectorSoftware/generator/commands.yaml @@ -1969,7 +1969,7 @@ rx_threads: chipversion: inherit_actions: GET_COMMAND - help: "\n\t[Jungfrau] Returns chip version. Can be 1.0 or 1.1" + help: "\n\t[Jungfrau] Returns chip version. Can be 1.0, 1.1 or 1.2" actions: GET: function: getChipVersion diff --git a/slsDetectorSoftware/tests/Caller/test-Caller-jungfrau.cpp b/slsDetectorSoftware/tests/Caller/test-Caller-jungfrau.cpp index 629757728..acfc88521 100644 --- a/slsDetectorSoftware/tests/Caller/test-Caller-jungfrau.cpp +++ b/slsDetectorSoftware/tests/Caller/test-Caller-jungfrau.cpp @@ -285,8 +285,9 @@ TEST_CASE("extrastoragecells", "[.detectorintegration]") { Caller caller(&det); auto det_type = det.getDetectorType().squash(); if (det_type == defs::JUNGFRAU) { - // chip version 1.0 - if (det.getChipVersion().squash() * 10 == 10) { + auto chipVersion = det.getChipVersion().squash() * 10; + // chip version 1.0 and 1.2 + if (chipVersion == 10 || chipVersion == 12) { auto prev_val = det.getNumberOfAdditionalStorageCells().tsquash( "inconsistent #additional storage cells to test"); { @@ -373,8 +374,9 @@ TEST_CASE("storagecell_delay", "[.detectorintegration]") { Caller caller(&det); auto det_type = det.getDetectorType().squash(); if (det_type == defs::JUNGFRAU) { - // chip version 1.0 - if (det.getChipVersion().squash() * 10 == 10) { + // chip version 1.0 and 1.2 + auto chipVersion = det.getChipVersion().squash() * 10; + if (chipVersion == 10 || chipVersion == 12) { auto prev_val = det.getStorageCellDelay(); { std::ostringstream oss; @@ -491,7 +493,7 @@ TEST_CASE("filtercells", "[.detectorintegration]") { det.setNumberOfFilterCells(prev_val[i], {i}); } } - // chip version 1.0 + // chip version 1.0 and 1.2 else { // cannot set/get filter cell REQUIRE_THROWS(caller.call("filtercells", {"1"}, -1, PUT)); diff --git a/slsDetectorSoftware/tests/Caller/test-Caller.cpp b/slsDetectorSoftware/tests/Caller/test-Caller.cpp index bc6122f0a..aa3df3402 100644 --- a/slsDetectorSoftware/tests/Caller/test-Caller.cpp +++ b/slsDetectorSoftware/tests/Caller/test-Caller.cpp @@ -1694,13 +1694,13 @@ TEST_CASE("filterresistor", "[.detectorintegration]") { auto det_type = det.getDetectorType().squash(); // only for chipv1.1 - bool chip11 = false; - if (det_type == defs::JUNGFRAU && - det.getChipVersion().squash() * 10 == 11) { - chip11 = true; + bool hasFeature = false; + if (det_type == defs::JUNGFRAU) { + auto chipVersion = det.getChipVersion().squash() * 10; + hasFeature = (chipVersion == 11 || chipVersion == 12); } - if (det_type == defs::GOTTHARD2 || chip11) { + if (det_type == defs::GOTTHARD2 || hasFeature) { auto prev_val = det.getFilterResistor(); { std::ostringstream oss; @@ -1910,7 +1910,7 @@ TEST_CASE("currentsource", "[.detectorintegration]") { "currentsource [enabled, nofix, 63]\n"); } } - // chipv1.1 + // chipv1.1 abd chip v1.2 else { REQUIRE_THROWS(caller.call("currentsource", {"1"}, -1, PUT)); REQUIRE_THROWS( diff --git a/slsSupportLib/include/sls/versionAPI.h b/slsSupportLib/include/sls/versionAPI.h index 03fa8b555..489e4b038 100644 --- a/slsSupportLib/include/sls/versionAPI.h +++ b/slsSupportLib/include/sls/versionAPI.h @@ -8,6 +8,6 @@ #define APIMOENCH "0.0.0 0x260424" #define APIEIGER "0.0.0 0x260807" #define APIXILINXCTB "0.0.0 0x260813" -#define APIJUNGFRAU "0.0.0 0x260424" +#define APIJUNGFRAU "0.0.0 0x260814" #define APIMYTHEN3 "0.0.0 0x260506" #define APIMATTERHORN "0.0.0 0x260529"