diff --git a/python/slsdet/detector.py b/python/slsdet/detector.py index 211ddc602..c0c95cd26 100755 --- a/python/slsdet/detector.py +++ b/python/slsdet/detector.py @@ -2347,8 +2347,8 @@ class Detector(CppDetectorApi): Note ----- Default: AUTO_TIMING \n - [Jungfrau][Moench][Ctb][Gotthard2][Xilinx Ctb] AUTO_TIMING, TRIGGER_EXPOSURE \n - [Mythen3] AUTO_TIMING, TRIGGER_EXPOSURE, GATED, TRIGGER_GATED \n + [Jungfrau][Moench][Ctb][Gotthard2] AUTO_TIMING, TRIGGER_EXPOSURE \n + [Mythen3][Xilinx Ctb] AUTO_TIMING, TRIGGER_EXPOSURE, GATED, TRIGGER_GATED \n [Eiger] AUTO_TIMING, TRIGGER_EXPOSURE, GATED, BURST_TRIGGER """ return self.getTimingMode() diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 0a5bb400a..7e5521aed 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -786,7 +786,7 @@ int set_timing_mode(int file_des) { #ifdef EIGERD case GATED: case BURST_TRIGGER: -#elif MYTHEN3D +#elif defined(MYTHEN3D) || defined(XILINX_CHIPTESTBOARDD) case GATED: case TRIGGER_GATED: #endif diff --git a/slsDetectorServers/xilinx_ctbDetectorServer/RegisterDefs.h b/slsDetectorServers/xilinx_ctbDetectorServer/RegisterDefs.h index d0a6e8bdb..83652bc5a 100644 --- a/slsDetectorServers/xilinx_ctbDetectorServer/RegisterDefs.h +++ b/slsDetectorServers/xilinx_ctbDetectorServer/RegisterDefs.h @@ -10,7 +10,76 @@ #ifndef __CHEBY__XCTB__H__ #define __CHEBY__XCTB__H__ -#define XCTB_SIZE 49924 /* 0xc304 */ +#define XCTB_SIZE 50244 /* 0xc444 */ + +/* REG CRC0_LSB */ +#define CRC0_LSB 0xc400UL +#define CRC0_LSB_PRESET 0x0UL + +/* REG CRC0_MSB */ +#define CRC0_MSB 0xc404UL +#define CRC0_MSB_PRESET 0x0UL + +/* REG CRC1_LSB */ +#define CRC1_LSB 0xc408UL +#define CRC1_LSB_PRESET 0x0UL + +/* REG CRC1_MSB */ +#define CRC1_MSB 0xc40cUL +#define CRC1_MSB_PRESET 0x0UL + +/* REG CRC2_LSB */ +#define CRC2_LSB 0xc410UL +#define CRC2_LSB_PRESET 0x0UL + +/* REG CRC2_MSB */ +#define CRC2_MSB 0xc414UL +#define CRC2_MSB_PRESET 0x0UL + +/* REG CRC3_LSB */ +#define CRC3_LSB 0xc418UL +#define CRC3_LSB_PRESET 0x0UL + +/* REG CRC3_MSB */ +#define CRC3_MSB 0xc41cUL +#define CRC3_MSB_PRESET 0x0UL + +/* REG SET_CRC0_LSB */ +#define SET_CRC0_LSB 0xc420UL +#define SET_CRC0_LSB_PRESET 0x0UL + +/* REG SET_CRC0_MSB */ +#define SET_CRC0_MSB 0xc424UL +#define SET_CRC0_MSB_PRESET 0x0UL + +/* REG SET_CRC1_LSB */ +#define SET_CRC1_LSB 0xc428UL +#define SET_CRC1_LSB_PRESET 0x0UL + +/* REG SET_CRC1_MSB */ +#define SET_CRC1_MSB 0xc42cUL +#define SET_CRC1_MSB_PRESET 0x0UL + +/* REG SET_CRC2_LSB */ +#define SET_CRC2_LSB 0xc430UL +#define SET_CRC2_LSB_PRESET 0x0UL + +/* REG SET_CRC2_MSB */ +#define SET_CRC2_MSB 0xc434UL +#define SET_CRC2_MSB_PRESET 0x0UL + +/* REG SET_CRC3_LSB */ +#define SET_CRC3_LSB 0xc438UL +#define SET_CRC3_LSB_PRESET 0x0UL + +/* REG SET_CRC3_MSB */ +#define SET_CRC3_MSB 0xc43cUL +#define SET_CRC3_MSB_PRESET 0x0UL + +/* REG CRC_write */ +#define CRC_WRITE 0xc440UL +#define CRC_WRITE_MSK 0xfUL +#define CRC_WRITE_OFST 0 /* REG CTRL_Reg */ #define CTRL_REG 0x8000UL @@ -677,6 +746,34 @@ #define OBUFDTS_ENA_MSK 0xffffUL #define OBUFDTS_ENA_OFST 0 +/* REG OBUFDTS_invert */ +#define OBUFDTS_INVERT 0xc020UL +#define OBUFDTS_INVERT_MSK 0xffffUL +#define OBUFDTS_INVERT_OFST 0 + +/* REG GATE_MASK_LSB */ +#define GATE_MASK_LSB 0xc024UL +#define GATE_MASK_LSB_PRESET 0x0UL + +/* REG GATE_MASK_MSB */ +#define GATE_MASK_MSB 0xc028UL +#define GATE_MASK_MSB_PRESET 0x0UL + +/* REG GATE_CTRL */ +#define GATE_CTRL 0xc02cUL +#define GATE_ENABLE 0x1UL +#define GATE_ENABLE_MSK 0x1UL +#define GATE_ENABLE_OFST 0 +#define GATE_OPEN 0x2UL +#define GATE_OPEN_MSK 0x2UL +#define GATE_OPEN_OFST 1 +#define GATE_INVERT 0x4UL +#define GATE_INVERT_MSK 0x4UL +#define GATE_INVERT_OFST 2 +#define GATE_VALUE_WHEN_CLOSED 0x8UL +#define GATE_VALUE_WHEN_CLOSED_MSK 0x8UL +#define GATE_VALUE_WHEN_CLOSED_OFST 3 + /* REG A_FIFO_Overflow_Status_Reg */ #define A_FIFO_OVERFLOW_STATUS_REG 0x9000UL #define A_FIFO_OVERFLOW_STATUS_REG_PRESET 0x0UL diff --git a/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorFunctionList.c index 838a8f0ed..7f6563afb 100644 --- a/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorFunctionList.c @@ -1373,10 +1373,28 @@ void setTiming(enum timingMode arg) { case AUTO_TIMING: LOG(logINFO, ("Set Timing: Auto\n")); bus_w(FLOW_CONTROL_REG, bus_r(FLOW_CONTROL_REG) & ~TRIGGER_ENABLE_MSK); + bus_w(GATE_CTRL, bus_r(GATE_CTRL) & ~GATE_ENABLE_MSK); break; case TRIGGER_EXPOSURE: LOG(logINFO, ("Set Timing: Trigger\n")); bus_w(FLOW_CONTROL_REG, bus_r(FLOW_CONTROL_REG) | TRIGGER_ENABLE_MSK); + bus_w(GATE_CTRL, bus_r(GATE_CTRL) & ~GATE_ENABLE_MSK); + break; + case GATED: + // chip-specific config needed, see example reg definitions in matterhorn chiptesting repo + // - a gate mask setting to specify which bits of the pattern are gated (GATE_MASK_LSB & GATE_MASK_MSB) + // - value of the pattern bit when gating is enabled but gate is closed (GATE_VALUE_WHEN_CLOSED) + // - a gate inversion setting (GATE_INVERT_MSK) + LOG(logINFO, ("Set Timing: Gated\n")); + bus_w(FLOW_CONTROL_REG, bus_r(FLOW_CONTROL_REG) & ~TRIGGER_ENABLE_MSK); + bus_w(GATE_CTRL, bus_r(GATE_CTRL) | GATE_ENABLE_MSK); + break; + case TRIGGER_GATED: + // trigger + gate --> trigger will start a pattern and the output of the pattern is gated. + // NOT A GATED TRIGGER !! (this is not: "trigger starts a pattern only if the gate is open") + LOG(logINFO, ("Set Timing: Trigger Gated\n")); + bus_w(FLOW_CONTROL_REG, bus_r(FLOW_CONTROL_REG) | TRIGGER_ENABLE_MSK); + bus_w(GATE_CTRL, bus_r(GATE_CTRL) | GATE_ENABLE_MSK); break; default: LOG(logERROR, ("Unknown timing mode %d\n", arg)); @@ -1384,8 +1402,19 @@ void setTiming(enum timingMode arg) { } enum timingMode getTiming() { - if (bus_r(FLOW_CONTROL_REG) == TRIGGER_ENABLE_MSK) + uint32_t extTrigger = (bus_r(FLOW_CONTROL_REG) & TRIGGER_ENABLE_MSK); + uint32_t extGate = (bus_r(GATE_CTRL) & GATE_ENABLE_MSK); + + if (extTrigger) { + if (extGate) { + return TRIGGER_GATED; + } return TRIGGER_EXPOSURE; + } + + if (extGate) { + return GATED; + } return AUTO_TIMING; } diff --git a/slsDetectorSoftware/generator/commands.yaml b/slsDetectorSoftware/generator/commands.yaml index 2fd884845..87ca6ad0b 100644 --- a/slsDetectorSoftware/generator/commands.yaml +++ b/slsDetectorSoftware/generator/commands.yaml @@ -741,7 +741,7 @@ column: function: setColumn timing: - help: "[auto|trigger|gating|burst_trigger|trigger_gating]\n\tTiming Mode of detector.\n\t[Jungfrau][Moench][Ctb][Gotthard2][Xilinx Ctb] [auto|trigger]\n\t[Mythen3] [auto|trigger|gating|trigger_gating]\n\t[Eiger] [auto|trigger|gating|burst_trigger]" + help: "[auto|trigger|gating|burst_trigger|trigger_gating]\n\tTiming Mode of detector.\n\t[Jungfrau][Moench][Ctb][Gotthard2] [auto|trigger]\n\t[Mythen3][Xilinx Ctb] [auto|trigger|gating|trigger_gating]\n\t[Eiger] [auto|trigger|gating|burst_trigger]" inherit_actions: INTEGER_COMMAND_VEC_ID actions: GET: diff --git a/slsDetectorSoftware/generator/extended_commands.yaml b/slsDetectorSoftware/generator/extended_commands.yaml index a47bc1582..0134cf5ed 100644 --- a/slsDetectorSoftware/generator/extended_commands.yaml +++ b/slsDetectorSoftware/generator/extended_commands.yaml @@ -11347,7 +11347,7 @@ timing: command_name: timing function_alias: timing help: "[auto|trigger|gating|burst_trigger|trigger_gating]\n\tTiming Mode of detector.\n\ - \t[Jungfrau][Moench][Ctb][Gotthard2][Xilinx Ctb] [auto|trigger]\n\t[Mythen3] [auto|trigger|gating|trigger_gating]\n\ + \t[Jungfrau][Moench][Ctb][Gotthard2] [auto|trigger]\n\t[Mythen3][Xilinx Ctb] [auto|trigger|gating|trigger_gating]\n\ \t[Eiger] [auto|trigger|gating|burst_trigger]" infer_action: true template: true diff --git a/slsDetectorSoftware/include/sls/Detector.h b/slsDetectorSoftware/include/sls/Detector.h index b3669a6a3..b0cdb518d 100644 --- a/slsDetectorSoftware/include/sls/Detector.h +++ b/slsDetectorSoftware/include/sls/Detector.h @@ -371,8 +371,8 @@ class Detector { Result getTimingMode(Positions pos = {}) const; /** - * [Jungfrau][Moench][CTB][Gotthard2][Xilinx CTB] - * Options: AUTO_TIMING, TRIGGER_EXPOSURE \n [Mythen3] Options: AUTO_TIMING, + * [Jungfrau][Moench][CTB][Gotthard2] + * Options: AUTO_TIMING, TRIGGER_EXPOSURE \n [Mythen3][Xilinx CTB] Options: AUTO_TIMING, * TRIGGER_EXPOSURE, GATED, TRIGGER_GATED \n [Eiger] Options: AUTO_TIMING, * TRIGGER_EXPOSURE, GATED, BURST_TRIGGER */ diff --git a/slsDetectorSoftware/src/Caller.cpp b/slsDetectorSoftware/src/Caller.cpp index 3278b0889..690387c81 100644 --- a/slsDetectorSoftware/src/Caller.cpp +++ b/slsDetectorSoftware/src/Caller.cpp @@ -13897,8 +13897,8 @@ std::string Caller::timing(int action) { if (action == slsDetectorDefs::HELP_ACTION) { os << R"V0G0N([auto|trigger|gating|burst_trigger|trigger_gating] Timing Mode of detector. - [Jungfrau][Moench][Ctb][Gotthard2][Xilinx Ctb] [auto|trigger] - [Mythen3] [auto|trigger|gating|trigger_gating] + [Jungfrau][Moench][Ctb][Gotthard2] [auto|trigger] + [Mythen3][Xilinx Ctb] [auto|trigger|gating|trigger_gating] [Eiger] [auto|trigger|gating|burst_trigger] )V0G0N" << std::endl; return os.str(); diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index dde062e27..405f3914f 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -616,6 +616,10 @@ std::vector Detector::getTimingModeList() const { return std::vector{defs::AUTO_TIMING, defs::TRIGGER_EXPOSURE, defs::GATED, defs::TRIGGER_GATED}; + case defs::XILINX_CHIPTESTBOARD: + return std::vector{defs::AUTO_TIMING, + defs::TRIGGER_EXPOSURE, + defs::GATED, defs::TRIGGER_GATED}; default: return std::vector{defs::AUTO_TIMING, defs::TRIGGER_EXPOSURE}; diff --git a/slsDetectorSoftware/tests/Caller/test-Caller.cpp b/slsDetectorSoftware/tests/Caller/test-Caller.cpp index 77a1bd240..cac3bdb7f 100644 --- a/slsDetectorSoftware/tests/Caller/test-Caller.cpp +++ b/slsDetectorSoftware/tests/Caller/test-Caller.cpp @@ -1079,7 +1079,7 @@ TEST_CASE("timing", "[.detectorintegration]") { REQUIRE(oss2.str() == "timing burst_trigger\n"); } REQUIRE_THROWS(caller.call("timing", {"trigger_gating"}, -1, PUT)); - } else if (det_type == defs::MYTHEN3) { + } else if (det_type == defs::MYTHEN3 || det_type == defs::XILINX_CHIPTESTBOARD) { { std::ostringstream oss1, oss2; caller.call("timing", {"gating"}, -1, PUT, oss1);