diff --git a/RELEASE.txt b/RELEASE.txt index 35ebc7a75..20b3af4c5 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -26,11 +26,7 @@ This document describes the differences between vx.x.x and vx.0.2 1 New, Changed or Resolved Features ===================================== -1.8 Gui ----------- -Bug Fix: - Plotting specific ADC as waveform plots correct data 2 On-board Detector Server Compatibility diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h index a11f1e1ab..7114c7f4b 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h @@ -398,8 +398,8 @@ int getPower(); void setPower(enum DACINDEX ind, int val); void powerOff(); #elif XILINX_CHIPTESTBOARDD +int getBitOffsetFromDACIndex(enum DACINDEX ind); int isPowerValid(enum DACINDEX ind, int val); - int getPower(); void setPower(enum DACINDEX ind, int val); #endif diff --git a/slsDetectorServers/xilinx_ctbDetectorServer/bin/xilinx_ctbDetectorServer_developer b/slsDetectorServers/xilinx_ctbDetectorServer/bin/xilinx_ctbDetectorServer_developer index 90c7fd215..d28cb6db7 100755 Binary files a/slsDetectorServers/xilinx_ctbDetectorServer/bin/xilinx_ctbDetectorServer_developer and b/slsDetectorServers/xilinx_ctbDetectorServer/bin/xilinx_ctbDetectorServer_developer differ diff --git a/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorFunctionList.c index 9380f7d9c..992d11f18 100644 --- a/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorFunctionList.c @@ -1205,6 +1205,26 @@ void setVLimit(int l) { vLimit = l; } +int getBitOffsetFromDACIndex(enum DACINDEX ind) { + switch (ind) { + case D_PWR_IO: + return POWER_VIO_OFST; + case D_PWR_A: + return POWER_VCC_A_OFST; + case D_PWR_B: + return POWER_VCC_B_OFST; + case D_PWR_C: + return POWER_VCC_C_OFST; + case D_PWR_D: + return POWER_VCC_D_OFST; + default: + LOG(logERROR, + ("DAC index %d is not defined to get offset in ctrl register\n", + ind)); + return -1; + } +} + int isPowerValid(enum DACINDEX ind, int val) { char *powerNames[] = {PWR_NAMES}; int pwrIndex = (int)(ind - D_PWR_D); @@ -1227,10 +1247,23 @@ int isPowerValid(enum DACINDEX ind, int val) { } int getPower(enum DACINDEX ind) { + // get bit offset in ctrl register + int bitOffset = getBitOffsetFromDACIndex(ind); + if (bitOffset == -1) { + return -1; + } + + // powered enable off + { + uint32_t addr = CTRL_REG; + uint32_t mask = (1 << bitOffset); + if (!(bus_r(addr) & mask)) + return 0; + } + char *powerNames[] = {PWR_NAMES}; int pwrIndex = (int)(ind - D_PWR_D); - // check dac value // not set yet if (dacValues[ind] == -1) { LOG(logERROR, @@ -1240,7 +1273,8 @@ int getPower(enum DACINDEX ind) { // dac powered off if (dacValues[ind] == LTC2620_D_GetPowerDownValue()) { - LOG(logWARNING, ("Power V%s is powered down\n", powerNames[pwrIndex])); + LOG(logWARNING, ("Power V%s enabled, but voltage is at minimum or 0.\n", + powerNames[pwrIndex])); return LTC2620_D_GetPowerDownValue(); } @@ -1254,26 +1288,43 @@ int getPower(enum DACINDEX ind) { } void setPower(enum DACINDEX ind, int val) { + // validate index and get bit offset in ctrl register + int bitOffset = getBitOffsetFromDACIndex(ind); + if (bitOffset == -1) { + return; + } + uint32_t addr = CTRL_REG; + uint32_t mask = (1 << bitOffset); + + if (val == -1) + return; + char *powerNames[] = {PWR_NAMES}; int pwrIndex = (int)(ind - D_PWR_D); + LOG(logINFO, ("Setting Power V%s to %d mV\n", powerNames[pwrIndex], val)); - // power down dac - if (val == LTC2620_D_GetPowerDownValue()) { - LOG(logINFO, ("\tPowering down V%d\n", powerNames[pwrIndex])); - setDAC(ind, LTC2620_D_GetPowerDownValue(), 0); + // validate value (already checked at tcp (funcs.c)) + if (!isPowerValid(ind, val)) { + LOG(logERROR, ("Invalid power value for V%s: %d mV\n", + powerNames[pwrIndex], val)); + return; } - // set dac - else if (val >= 0) { - LOG(logINFO, - ("Setting Power V%s to %d mV\n", powerNames[pwrIndex], val)); + // Switch off power enable + LOG(logDEBUG1, ("Switching off power enable\n")); + bus_w(addr, bus_r(addr) & ~(mask)); - // validate value (already checked at tcp (funcs.c)) - if (!isPowerValid(ind, val)) { - return; - } + // power down dac + LOG(logINFO, ("\tPowering down V%d\n", powerNames[pwrIndex])); + setDAC(ind, LTC2620_D_GetPowerDownValue(), 0); + + //(power off is anyway done with power enable) + if (val == 0) + val = LTC2620_D_GetPowerDownValue(); + + // convert voltage to dac (power off is anyway done with power enable) + if (val != LTC2620_D_GetPowerDownValue()) { - // convert voltage to dac int dacval = -1; if (ConvertToDifferentRange( POWER_RGLTR_MIN, POWER_RGLTR_MAX, LTC2620_D_GetMaxInput(), @@ -1290,6 +1341,12 @@ void setPower(enum DACINDEX ind, int val) { LOG(logINFO, ("Setting Power V%s: %d mV (%d dac)\n", powerNames[pwrIndex], val, dacval)); setDAC(ind, dacval, 0); + + // if valid, enable power + if (dacval >= 0) { + LOG(logDEBUG1, ("Switching on power enable\n")); + bus_w(addr, bus_r(addr) | mask); + } } } diff --git a/slsDetectorSoftware/tests/Caller/test-Caller-chiptestboard.cpp b/slsDetectorSoftware/tests/Caller/test-Caller-chiptestboard.cpp index 66ae42c1c..2bc827476 100644 --- a/slsDetectorSoftware/tests/Caller/test-Caller-chiptestboard.cpp +++ b/slsDetectorSoftware/tests/Caller/test-Caller-chiptestboard.cpp @@ -1025,91 +1025,43 @@ TEST_CASE("dbitclk", "[.cmdcall]") { } } -TEST_CASE("v_a", "[.cmdcall]") { +TEST_CASE("v_abcd", "[.cmdcall]") { Detector det; Caller caller(&det); auto det_type = det.getDetectorType().squash(); - if (det_type == defs::CHIPTESTBOARD || - det_type == defs::XILINX_CHIPTESTBOARD) { - auto prev_val = det.getPower(defs::V_POWER_A); - { - std::ostringstream oss1, oss2; - caller.call("v_a", {"1200"}, -1, PUT, oss1); - REQUIRE(oss1.str() == "v_a 1200\n"); - caller.call("v_a", {}, -1, GET, oss2); - REQUIRE(oss2.str() == "v_a 1200\n"); - } - for (int i = 0; i != det.size(); ++i) { - det.setPower(defs::V_POWER_A, prev_val[i], {i}); - } - } else { - REQUIRE_THROWS(caller.call("v_a", {}, -1, GET)); - } -} -TEST_CASE("v_b", "[.cmdcall]") { - Detector det; - Caller caller(&det); - auto det_type = det.getDetectorType().squash(); - if (det_type == defs::CHIPTESTBOARD || - det_type == defs::XILINX_CHIPTESTBOARD) { - auto prev_val = det.getPower(defs::V_POWER_B); - { - std::ostringstream oss1, oss2; - caller.call("v_b", {"1200"}, -1, PUT, oss1); - REQUIRE(oss1.str() == "v_b 1200\n"); - caller.call("v_b", {}, -1, GET, oss2); - REQUIRE(oss2.str() == "v_b 1200\n"); - } - for (int i = 0; i != det.size(); ++i) { - det.setPower(defs::V_POWER_B, prev_val[i], {i}); - } - } else { - REQUIRE_THROWS(caller.call("v_b", {}, -1, GET)); - } -} + std::vector cmds{"v_a", "v_b", "v_c", "v_d"}; + std::vector indices{defs::V_POWER_A, defs::V_POWER_B, + defs::V_POWER_C, defs::V_POWER_D}; -TEST_CASE("v_c", "[.cmdcall]") { - Detector det; - Caller caller(&det); - auto det_type = det.getDetectorType().squash(); - if (det_type == defs::CHIPTESTBOARD || - det_type == defs::XILINX_CHIPTESTBOARD) { - auto prev_val = det.getPower(defs::V_POWER_C); - { - std::ostringstream oss1, oss2; - caller.call("v_c", {"1200"}, -1, PUT, oss1); - REQUIRE(oss1.str() == "v_c 1200\n"); - caller.call("v_c", {}, -1, GET, oss2); - REQUIRE(oss2.str() == "v_c 1200\n"); - } - for (int i = 0; i != det.size(); ++i) { - det.setPower(defs::V_POWER_C, prev_val[i], {i}); - } - } else { - REQUIRE_THROWS(caller.call("v_c", {}, -1, GET)); + if (det.isVirtualDetectorServer().tsquash("Inconsistent virtual servers")) { + cmds.push_back("v_io"); + indices.push_back(defs::V_POWER_IO); } -} -TEST_CASE("v_d", "[.cmdcall]") { - Detector det; - Caller caller(&det); - auto det_type = det.getDetectorType().squash(); - if (det_type == defs::CHIPTESTBOARD || - det_type == defs::XILINX_CHIPTESTBOARD) { - auto prev_val = det.getPower(defs::V_POWER_D); - { - std::ostringstream oss1, oss2; - caller.call("v_d", {"1200"}, -1, PUT, oss1); - REQUIRE(oss1.str() == "v_d 1200\n"); - caller.call("v_d", {}, -1, GET, oss2); - REQUIRE(oss2.str() == "v_d 1200\n"); + for (size_t i = 0; i < cmds.size(); ++i) { + if (det_type == defs::CHIPTESTBOARD || + det_type == defs::XILINX_CHIPTESTBOARD) { + auto prev_val = det.getPower(indices[i]); + { + std::ostringstream oss; + caller.call(cmds[i], {"0"}, -1, PUT, oss); + REQUIRE(oss.str() == cmds[i] + " 0\n"); + } + { + std::ostringstream oss1, oss2; + caller.call(cmds[i], {"1200"}, -1, PUT, oss1); + REQUIRE(oss1.str() == cmds[i] + " 1200\n"); + caller.call(cmds[i], {}, -1, GET, oss2); + REQUIRE(oss2.str() == cmds[i] + " 1200\n"); + } + for (int i = 0; i != det.size(); ++i) { + det.setPower(indices[i], prev_val[i], {i}); + } + + } else { + REQUIRE_THROWS(caller.call(cmds[i], {}, -1, GET)); } - for (int i = 0; i != det.size(); ++i) { - det.setPower(defs::V_POWER_D, prev_val[i], {i}); - } - } else { - REQUIRE_THROWS(caller.call("v_d", {}, -1, GET)); } } diff --git a/slsSupportLib/include/sls/versionAPI.h b/slsSupportLib/include/sls/versionAPI.h index 579ac62b3..075fd280b 100644 --- a/slsSupportLib/include/sls/versionAPI.h +++ b/slsSupportLib/include/sls/versionAPI.h @@ -7,6 +7,6 @@ #define APIGOTTHARD2 "0.0.0 0x250909" #define APIMOENCH "0.0.0 0x250909" #define APIEIGER "0.0.0 0x250909" -#define APIXILINXCTB "0.0.0 0x250930" +#define APIXILINXCTB "0.0.0 0x251015" #define APIJUNGFRAU "0.0.0 0x250909" #define APIMYTHEN3 "0.0.0 0x250922"