diff --git a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c index 50c79186b..7c65c6bf0 100644 --- a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c @@ -58,7 +58,7 @@ char udpPacketData[UDP_PACKET_DATA_BYTES + sizeof(sls_detector_header)]; uint32_t adcEnableMask_1g = BIT32_MSK; // 10g readout -uint8_t adcEnableMask_10g = BIT32_MSK; +uint8_t adcEnableMask_10g = 0xFF; int32_t clkPhase[NUM_CLOCKS] = {}; uint32_t clkFrequency[NUM_CLOCKS] = {40, 20, 20, 200}; @@ -471,7 +471,7 @@ void setupDetector() { vLimit = DEFAULT_VLIMIT; highvoltage = 0; adcEnableMask_1g = BIT32_MSK; - adcEnableMask_10g = BIT32_MSK; + adcEnableMask_10g = 0xFF; analogEnable = 1; digitalEnable = 0; naSamples = 1; diff --git a/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c index 64e949bda..77585cc12 100644 --- a/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c @@ -1341,6 +1341,18 @@ void setNumberofDestinations(int value) { bus_w(CONTROL_REG, bus_r(CONTROL_REG) | ((value << CONTROL_RX_ADDTNL_ENDPTS_NUM_OFST) & CONTROL_RX_ADDTNL_ENDPTS_NUM_MSK)); } +int getFirstUDPDestination() { + return ((bus_r(CONTROL_REG) & CONTROL_RX_ENDPTS_START_MSK) >> + CONTROL_RX_ENDPTS_START_OFST); +} + +void setFirstUDPDestination(int value) { + LOG(logINFO, ("Setting first entry to %d\n", value)); + bus_w(CONTROL_REG, + bus_r(CONTROL_REG) | ((value << CONTROL_RX_ENDPTS_START_OFST) & + CONTROL_RX_ENDPTS_START_MSK)); +} + void selectPrimaryInterface(int val) { uint32_t addr = CONFIG_REG; diff --git a/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c index 4e423c08d..45bda6da6 100644 --- a/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c @@ -56,7 +56,7 @@ char udpPacketData[UDP_PACKET_DATA_BYTES + sizeof(sls_detector_header)]; uint32_t adcEnableMask_1g = BIT32_MSK; // 10g readout -uint8_t adcEnableMask_10g = BIT32_MSK; +uint8_t adcEnableMask_10g = 0xFF; int32_t clkPhase[NUM_CLOCKS] = {}; uint32_t clkFrequency[NUM_CLOCKS] = {40, 20, 20, 200}; @@ -481,7 +481,7 @@ void setupDetector() { vLimit = DEFAULT_VLIMIT; highvoltage = 0; adcEnableMask_1g = BIT32_MSK; - adcEnableMask_10g = BIT32_MSK; + adcEnableMask_10g = 0xFF; nSamples = 1; #ifdef VIRTUAL sharedMemory_setStatus(IDLE); diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h index f0b055760..7079bfac1 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h @@ -388,6 +388,8 @@ int getNumberofUDPInterfaces(); #ifdef JUNGFRAUD int getNumberofDestinations(); void setNumberofDestinations(int value); +int getFirstUDPDestination(); +void setFirstUDPDestination(int value); void selectPrimaryInterface(int val); int getPrimaryInterface(); void setupHeader(int iRxEntry, enum interfaceType type, uint32_t destip, diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h index ce9a7044d..6bf9ef13e 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h @@ -272,4 +272,6 @@ int set_module_id(int); int get_dest_udp_list(int); int set_dest_udp_list(int); int get_num_dest_list(int); -int set_num_dest_list(int); \ No newline at end of file +int set_num_dest_list(int); +int get_udp_first_dest(int); +int set_udp_first_dest(int); \ No newline at end of file diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 4438cd761..15da6c066 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -52,6 +52,7 @@ int checkModuleFlag = 1; udpStruct udpDetails[MAX_UDP_DESTINATION]; int numUdpDestinations = 1; +int firstUDPDestination = 0; int configured = FAIL; char configureMessage[MAX_STR_LENGTH] = "udp parameters not configured yet"; @@ -408,6 +409,8 @@ void function_table() { flist[F_SET_DEST_UDP_LIST] = &set_dest_udp_list; flist[F_GET_NUM_DEST_UDP] = &get_num_dest_list; flist[F_SET_NUM_DEST_UDP] = &set_num_dest_list; + flist[F_GET_UDP_FIRST_DEST] = &get_udp_first_dest; + flist[F_SET_UDP_FIRST_DEST] = &set_udp_first_dest; // check if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) { @@ -2926,14 +2929,16 @@ int enable_ten_giga(int file_des) { uint64_t hardwaremac = getDetectorMAC(); if (udpDetails[0].srcmac != hardwaremac) { LOG(logINFOBLUE, ("Updating udp source mac\n")); - for (int iRxEntry = 0; iRxEntry != numUdpDestinations; ++iRxEntry) { + for (int iRxEntry = 0; iRxEntry != MAX_UDP_DESTINATION; + ++iRxEntry) { udpDetails[iRxEntry].srcmac = hardwaremac; } } uint32_t hardwareip = getDetectorIP(); if (arg == 0 && udpDetails[0].srcip != hardwareip) { LOG(logINFOBLUE, ("Updating udp source ip\n")); - for (int iRxEntry = 0; iRxEntry != numUdpDestinations; ++iRxEntry) { + for (int iRxEntry = 0; iRxEntry != MAX_UDP_DESTINATION; + ++iRxEntry) { udpDetails[iRxEntry].srcip = hardwareip; } } @@ -4872,9 +4877,10 @@ void calculate_and_set_position() { for (int i = 0; i < 6; ++i) { udpDetails[0].srcmac = (udpDetails[0].srcmac << 8) + a[i]; } - for (int iRxEntry = 1; iRxEntry != numUdpDestinations; ++iRxEntry) { + for (int iRxEntry = 1; iRxEntry != MAX_UDP_DESTINATION; + ++iRxEntry) { udpDetails[iRxEntry].srcmac = udpDetails[0].srcmac; - } + } } #if defined(JUNGFRAUD) || defined(GOTTHARD2D) if (getNumberofUDPInterfaces() > 1) { @@ -4891,9 +4897,10 @@ void calculate_and_set_position() { for (int i = 0; i < 6; ++i) { udpDetails[0].srcmac2 = (udpDetails[0].srcmac2 << 8) + a[i]; } - for (int iRxEntry = 1; iRxEntry != numUdpDestinations; ++iRxEntry) { + for (int iRxEntry = 1; iRxEntry != MAX_UDP_DESTINATION; + ++iRxEntry) { udpDetails[iRxEntry].srcmac2 = udpDetails[0].srcmac2; - } + } } } #endif @@ -4937,7 +4944,8 @@ int check_detector_idle(const char *s) { } int is_udp_configured() { - for (int i = 0; i != numUdpDestinations; ++i) { + for (int i = firstUDPDestination; + i != firstUDPDestination + numUdpDestinations; ++i) { if (udpDetails[i].dstip == 0) { sprintf(configureMessage, "udp destination ip not configured [entry:%d]\n", i); LOG(logWARNING, ("%s", configureMessage)); @@ -5026,7 +5034,8 @@ int set_source_udp_ip(int file_des) { if (Server_VerifyLock() == OK) { if (check_detector_idle("configure mac") == OK) { if (udpDetails[0].srcip != arg) { - for (int iRxEntry = 0; iRxEntry != numUdpDestinations; ++iRxEntry) { + for (int iRxEntry = 0; iRxEntry != MAX_UDP_DESTINATION; + ++iRxEntry) { udpDetails[iRxEntry].srcip = arg; } configure_mac(); @@ -5067,7 +5076,8 @@ int set_source_udp_ip2(int file_des) { if (Server_VerifyLock() == OK) { if (check_detector_idle("configure mac") == OK) { if (udpDetails[0].srcip2 != arg) { - for (int iRxEntry = 0; iRxEntry != numUdpDestinations; ++iRxEntry) { + for (int iRxEntry = 0; iRxEntry != MAX_UDP_DESTINATION; + ++iRxEntry) { udpDetails[iRxEntry].srcip2 = arg; } configure_mac(); @@ -5187,7 +5197,8 @@ int set_source_udp_mac(int file_des) { if (Server_VerifyLock() == OK) { if (check_detector_idle("configure mac") == OK) { if (udpDetails[0].srcmac != arg) { - for (int iRxEntry = 0; iRxEntry != numUdpDestinations; ++iRxEntry) { + for (int iRxEntry = 0; iRxEntry != MAX_UDP_DESTINATION; + ++iRxEntry) { udpDetails[iRxEntry].srcmac = arg; } configure_mac(); @@ -5226,7 +5237,8 @@ int set_source_udp_mac2(int file_des) { if (Server_VerifyLock() == OK) { if (check_detector_idle("configure mac") == OK) { if (udpDetails[0].srcmac2 != arg) { - for (int iRxEntry = 0; iRxEntry != numUdpDestinations; ++iRxEntry) { + for (int iRxEntry = 0; iRxEntry != MAX_UDP_DESTINATION; + ++iRxEntry) { udpDetails[iRxEntry].srcmac2 = arg; } configure_mac(); @@ -9178,14 +9190,56 @@ int set_num_dest_list(int file_des) { } else { if (check_detector_idle("set number of udp destinations") == OK) { numUdpDestinations = arg; - // copying src details from first src entry - for (int iRxEntry = 1; iRxEntry != numUdpDestinations; ++iRxEntry) { - udpDetails[iRxEntry].srcip = udpDetails[0].srcip; - udpDetails[iRxEntry].srcip2 = udpDetails[0].srcip2; - udpDetails[iRxEntry].srcmac = udpDetails[0].srcmac; - udpDetails[iRxEntry].srcmac2 = udpDetails[0].srcmac2; - - } + configure_mac(); + } + } +#endif + return Server_SendResult(file_des, INT32, NULL, 0); +} + +int get_udp_first_dest(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int retval = -1; +#if !defined(JUNGFRAUD) && !defined(EIGERD) + functionNotImplemented(); +#else + retval = firstUDPDestination; +#ifdef JUNGFRAUD + if (getFirstUDPDestination() != retval) { + ret = FAIL; + sprintf(mess, + "Could not get first desintation. (server reads %d, fpga reads " + "%d).\n", + getFirstUDPDestination(), retval); + LOG(logERROR, (mess)); + } +#endif +#endif + LOG(logDEBUG1, ("first udp destination retval: 0x%x\n", retval)); + return Server_SendResult(file_des, INT32, &retval, sizeof(retval)); +} + +int set_udp_first_dest(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int arg = -1; + + if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0) + return printSocketReadError(); + LOG(logDEBUG1, ("Setting first udp destination to %d\n", arg)); + +#if !defined(JUNGFRAUD) && !defined(EIGERD) + functionNotImplemented(); +#else + if (arg < 0 || arg >= MAX_UDP_DESTINATION) { + ret = FAIL; + sprintf(mess, "Could not set first destination. Options: 0-%d\n", + MAX_UDP_DESTINATION - 1); + LOG(logERROR, (mess)); + } else { + if (check_detector_idle("set first udp destination") == OK) { + firstUDPDestination = arg; configure_mac(); } } diff --git a/slsDetectorSoftware/include/sls/Detector.h b/slsDetectorSoftware/include/sls/Detector.h index 3ac5e406e..0e53c892b 100644 --- a/slsDetectorSoftware/include/sls/Detector.h +++ b/slsDetectorSoftware/include/sls/Detector.h @@ -677,6 +677,12 @@ class Detector { /**[Jungfrau][Eiger] Options 1-32 */ void setNumberofUDPDestinations(const int value, Positions pos = {}); + /** [Jungfrau][Eiger] */ + Result getFirstUDPDestination(Positions pos = {}) const; + + /**[Jungfrau][Eiger] Options 0-31 */ + void setFirstUDPDestination(const int value, Positions pos = {}); + Result getDestinationUDPIP(Positions pos = {}) const; /** IP of the interface in receiver that the detector sends data to */ diff --git a/slsDetectorSoftware/src/CmdProxy.h b/slsDetectorSoftware/src/CmdProxy.h index 7f1bf0d09..5d2708678 100644 --- a/slsDetectorSoftware/src/CmdProxy.h +++ b/slsDetectorSoftware/src/CmdProxy.h @@ -859,6 +859,7 @@ class CmdProxy { {"selinterface", &CmdProxy::selinterface}, {"udp_dstlist", &CmdProxy::UDPDestinationList}, {"udp_numdst", &CmdProxy::udp_numdst}, + {"udp_firstdst", &CmdProxy::udp_firstdst}, {"udp_srcip", &CmdProxy::udp_srcip}, {"udp_srcip2", &CmdProxy::udp_srcip2}, {"udp_dstip", &CmdProxy::UDPDestinationIP}, @@ -1539,6 +1540,14 @@ class CmdProxy { "destinations that the detector will stream images " "out in a round robin fashion. Default: 1"); + INTEGER_COMMAND_VEC_ID( + udp_firstdst, getFirstUDPDestination, setFirstUDPDestination, + StringTo, + "[0 - 31]\n\t[Jungfrau][Eiger] One can set which is the first " + "destination that the detector will stream images " + "out from in a round robin fashion. The entry must not have been " + "empty. Default: 0"); + INTEGER_COMMAND_VEC_ID( udp_srcip, getSourceUDPIP, setSourceUDPIP, IpAddr, "[x.x.x.x]\n\tIp address of the detector (source) udp " diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index c467a1609..93c0b6497 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -929,6 +929,14 @@ void Detector::setNumberofUDPDestinations(const int value, Positions pos) { pimpl->Parallel(&Module::setNumberofUDPDestinations, pos, value); } +Result Detector::getFirstUDPDestination(Positions pos) const { + return pimpl->Parallel(&Module::getFirstUDPDestination, pos); +} + +void Detector::setFirstUDPDestination(const int value, Positions pos) { + pimpl->Parallel(&Module::setFirstUDPDestination, pos, value); +} + Result Detector::getDestinationUDPIP(Positions pos) const { return pimpl->Parallel(&Module::getDestinationUDPIP, pos); } diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index 94494adbf..3b8c647fa 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -970,6 +970,14 @@ void Module::setNumberofUDPDestinations(const int value) { sendToDetector(F_SET_NUM_DEST_UDP, value, nullptr); } +int Module::getFirstUDPDestination() const { + return sendToDetector(F_GET_UDP_FIRST_DEST); +} + +void Module::setFirstUDPDestination(const int value) { + sendToDetector(F_SET_UDP_FIRST_DEST, value, nullptr); +} + sls::IpAddr Module::getDestinationUDPIP() const { return sendToDetector(F_GET_DEST_UDP_IP); } diff --git a/slsDetectorSoftware/src/Module.h b/slsDetectorSoftware/src/Module.h index 9f9a20ed1..2a85f433a 100644 --- a/slsDetectorSoftware/src/Module.h +++ b/slsDetectorSoftware/src/Module.h @@ -226,6 +226,8 @@ class Module : public virtual slsDetectorDefs { void setDestinationUDPList(const defs::udpDestination dest); int getNumberofUDPDestinations() const; void setNumberofUDPDestinations(const int value); + int getFirstUDPDestination() const; + void setFirstUDPDestination(const int value); sls::IpAddr getDestinationUDPIP() const; void setDestinationUDPIP(const sls::IpAddr ip); sls::IpAddr getDestinationUDPIP2() const; diff --git a/slsDetectorSoftware/tests/test-CmdProxy.cpp b/slsDetectorSoftware/tests/test-CmdProxy.cpp index 85d55cab6..c0ef4f93b 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy.cpp @@ -2262,6 +2262,37 @@ TEST_CASE("udp_numdst", "[.cmd]") { } } +TEST_CASE("udp_firstdst", "[.cmd]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::JUNGFRAU || det_type == defs::EIGER) { + auto prev_val = det.getFirstUDPDestination(); + { + std::ostringstream oss; + proxy.Call("udp_firstdst", {"0"}, -1, PUT, oss); + REQUIRE(oss.str() == "udp_firstdst 10\n"); + } + { + std::ostringstream oss; + proxy.Call("udp_firstdst", {}, -1, GET, oss); + REQUIRE(oss.str() == "udp_firstdst 0\n"); + } + { + std::ostringstream oss; + proxy.Call("udp_firstdst", {"31"}, -1, PUT, oss); + REQUIRE(oss.str() == "udp_firstdst 31\n"); + } + REQUIRE_THROWS(proxy.Call("udp_firstdst", {"33"}, -1, PUT)); + + for (int i = 0; i != det.size(); ++i) { + det.setFirstUDPDestination(prev_val[i], {i}); + } + } else { + REQUIRE_THROWS(proxy.Call("udp_numdst", {}, -1, GET)); + } +} + TEST_CASE("udp_dstip", "[.cmd]") { Detector det; CmdProxy proxy(&det); diff --git a/slsSupportLib/include/sls/sls_detector_funcs.h b/slsSupportLib/include/sls/sls_detector_funcs.h index 8701c731d..8e8210aae 100755 --- a/slsSupportLib/include/sls/sls_detector_funcs.h +++ b/slsSupportLib/include/sls/sls_detector_funcs.h @@ -249,6 +249,8 @@ enum detFuncs { F_SET_DEST_UDP_LIST, F_GET_NUM_DEST_UDP, F_SET_NUM_DEST_UDP, + F_GET_UDP_FIRST_DEST, + F_SET_UDP_FIRST_DEST, NUM_DET_FUNCTIONS, RECEIVER_ENUM_START = 256, /**< detector function should not exceed this @@ -605,6 +607,8 @@ const char* getFunctionNameFromEnum(enum detFuncs func) { case F_SET_DEST_UDP_LIST: return "F_SET_DEST_UDP_LIST"; case F_GET_NUM_DEST_UDP: return "F_GET_NUM_DEST_UDP"; case F_SET_NUM_DEST_UDP: return "F_SET_NUM_DEST_UDP"; + case F_GET_UDP_FIRST_DEST: return "F_GET_UDP_FIRST_DEST"; + case F_SET_UDP_FIRST_DEST: return "F_SET_UDP_FIRST_DEST"; case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS"; case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START";