diff --git a/python/src/detector.cpp b/python/src/detector.cpp index 5fce855e6..c29c8cabf 100644 --- a/python/src/detector.cpp +++ b/python/src/detector.cpp @@ -428,9 +428,9 @@ void init_det(py::module &m) { Detector::setNextFrameNumber, py::arg(), py::arg() = Positions{}) .def("sendSoftwareTrigger", - (void (Detector::*)(sls::Positions)) & + (void (Detector::*)(const bool, sls::Positions)) & Detector::sendSoftwareTrigger, - py::arg() = Positions{}) + py::arg(), py::arg() = Positions{}) .def("getScan", (Result(Detector::*)(sls::Positions) const) & Detector::getScan, diff --git a/slsDetectorServers/eigerDetectorServer/FebControl.c b/slsDetectorServers/eigerDetectorServer/FebControl.c index 608207ea6..f12bffa07 100644 --- a/slsDetectorServers/eigerDetectorServer/FebControl.c +++ b/slsDetectorServers/eigerDetectorServer/FebControl.c @@ -715,14 +715,16 @@ int Feb_Control_ProcessingInProgress() { if (!Feb_Control_activated) return IDLE; - if (!Feb_Interface_ReadRegister(Feb_Control_rightAddress, - FEB_REG_STATUS, ®r)) { - LOG(logERROR, ("Could not read right FEB_REG_STATUS to get feb processing status\n")); + if (!Feb_Interface_ReadRegister(Feb_Control_rightAddress, FEB_REG_STATUS, + ®r)) { + LOG(logERROR, ("Could not read right FEB_REG_STATUS to get feb " + "processing status\n")); return STATUS_ERROR; } - if (!Feb_Interface_ReadRegister(Feb_Control_leftAddress, - FEB_REG_STATUS, ®l)) { - LOG(logERROR, ("Could not read left FEB_REG_STATUS to get feb processing status\n")); + if (!Feb_Interface_ReadRegister(Feb_Control_leftAddress, FEB_REG_STATUS, + ®l)) { + LOG(logERROR, ("Could not read left FEB_REG_STATUS to get feb " + "processing status\n")); return STATUS_ERROR; } // processing done @@ -730,7 +732,7 @@ int Feb_Control_ProcessingInProgress() { return STATUS_IDLE; } // processing running - return STATUS_RUNNING; + return STATUS_RUNNING; } int Feb_Control_AcquisitionStartedBit() { @@ -1026,7 +1028,8 @@ int Feb_Control_StopAcquisition() { unsigned int orig_value = 0; if (!Feb_Interface_ReadRegister(Feb_Control_AddressToAll(), DAQ_REG_CTRL, &orig_value)) { - LOG(logERROR, ("Could not read DAQ_REG_CTRL to stop acquisition (send complete frames)\n")); + LOG(logERROR, ("Could not read DAQ_REG_CTRL to stop acquisition " + "(send complete frames)\n")); return 0; } if (!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(), @@ -1035,7 +1038,8 @@ int Feb_Control_StopAcquisition() { LOG(logERROR, ("Could not send last frames.\n")); return 0; } - LOG(logINFOBLUE, ("send last frame value:0x%x\n", orig_value | DAQ_CTRL_STOP)); + LOG(logINFOBLUE, + ("send last frame value:0x%x\n", orig_value | DAQ_CTRL_STOP)); // wait for feb processing to be done int is_processing = Feb_Control_ProcessingInProgress(); @@ -1044,8 +1048,8 @@ int Feb_Control_StopAcquisition() { usleep(500); is_processing = Feb_Control_ProcessingInProgress(); - // check error only 5 times (ensuring it is not something that happens - // sometimes) + // check error only 5 times (ensuring it is not something that + // happens sometimes) if (is_processing == STATUS_ERROR) { if (check_error == 5) break; @@ -1053,42 +1057,98 @@ int Feb_Control_StopAcquisition() { } // reset check_error for next time else check_error = 0; - } - + // stop acquisition return Feb_Control_Reset(); } return 1; } -int Feb_Control_SoftwareTrigger() { - if (Feb_Control_activated) { - unsigned int orig_value = 0; - if (!Feb_Interface_ReadRegister(Feb_Control_AddressToAll(), - DAQ_REG_CHIP_CMDS, &orig_value)) { - LOG(logERROR, ("Could not read DAQ_REG_CHIP_CMDS to send software " - "trigger\n")); - return 0; - } - unsigned int cmd = orig_value | DAQ_REG_CHIP_CMDS_INT_TRIGGER; +int Feb_Control_IsReadyForTrigger(int *readyForTrigger) { + unsigned int addr[2] = {Feb_Control_leftAddress, Feb_Control_rightAddress}; + unsigned int value[2] = {0, 0}; - // set trigger bit - LOG(logDEBUG1, ("Setting Trigger, Register:0x%x\n", cmd)); - if (!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(), - DAQ_REG_CHIP_CMDS, cmd, 0, 0)) { - LOG(logERROR, ("Could not give software trigger\n")); + for (int i = 0; i < 2; ++i) { + if (!Feb_Interface_ReadRegister(addr[i], FEB_REG_STATUS, &value[i])) { + LOG(logERROR, ("Could not read %s FEB_REG_STATUS reg\n", + (i == 0 ? "left" : "right"))); return 0; } - // unset trigger bit - LOG(logDEBUG1, ("Unsetting Trigger, Register:0x%x\n", orig_value)); - if (!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(), - DAQ_REG_CHIP_CMDS, orig_value, 0, 0)) { - LOG(logERROR, ("Could not give software trigger\n")); - return 0; - } - LOG(logINFO, ("Software Internal Trigger Sent!\n")); } + *readyForTrigger = + ((value[0] | value[1]) & FEB_REG_STATUS_WAIT_FOR_TRGGR_MSK); + return 1; +} + +int Feb_Control_SendSoftwareTrigger() { + // read old value in register + unsigned int orig_value = 0; + if (!Feb_Interface_ReadRegister(Feb_Control_AddressToAll(), + DAQ_REG_CHIP_CMDS, &orig_value)) { + LOG(logERROR, ("Could not read DAQ_REG_CHIP_CMDS to send software " + "trigger\n")); + return 0; + } + unsigned int cmd = orig_value | DAQ_REG_CHIP_CMDS_INT_TRIGGER; + + // set trigger bit + LOG(logDEBUG1, ("Setting Trigger, Register:0x%x\n", cmd)); + if (!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(), + DAQ_REG_CHIP_CMDS, cmd, 0, 0)) { + LOG(logERROR, ("Could not give software trigger\n")); + return 0; + } + // unset trigger bit + LOG(logDEBUG1, ("Unsetting Trigger, Register:0x%x\n", orig_value)); + if (!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(), + DAQ_REG_CHIP_CMDS, orig_value, 0, 0)) { + LOG(logERROR, ("Could not give software trigger\n")); + return 0; + } + LOG(logINFO, ("Software Internal Trigger Sent!\n")); + return 1; +} + +int Feb_Control_SoftwareTrigger(int block) { + if (Feb_Control_activated) { + // cant read reg + int readyForTrigger = 0; + if (!Feb_Control_IsReadyForTrigger(&readyForTrigger)) { + LOG(logERROR, ("Could not read FEB_REG_STATUS reg!\n")); + return 0; + } + // if not ready for trigger, throw + if (!readyForTrigger) { + LOG(logWARNING, ("Not yet ready for trigger!\n")); + return 0; + } + + // send trigger to both fpgas + Feb_Control_SendSoftwareTrigger(); + + // wait for next trigger ready + if (block) { + LOG(logINFO, ("Blocking Software Trigger\n")); + int readyForTrigger = 0; + if (!Feb_Control_IsReadyForTrigger(&readyForTrigger)) { + LOG(logERROR, ("Could not read FEB_REG_STATUS reg after giving " + "trigger!\n")); + return 0; + } + + while (!readyForTrigger) { + usleep(5000); + if (!Feb_Control_IsReadyForTrigger(&readyForTrigger)) { + LOG(logERROR, ("Could not read FEB_REG_STATUS reg after " + "giving trigger!\n")); + return 0; + } + } + LOG(logINFO, ("Done waiting (wait for trigger)!\n")); + } + } + return 1; } @@ -1954,8 +2014,8 @@ int Feb_Control_GetLeftFPGATemp() { "temperature\n")); return 0; } - - unsigned int temperature = ((value & FEB_REG_STATUS_TEMP_MSK) >> FEB_REG_STATUS_TEMP_OFST); + unsigned int temperature = + ((value & FEB_REG_STATUS_TEMP_MSK) >> FEB_REG_STATUS_TEMP_OFST); temperature = ((((float)(temperature) / 65536.0f) / 0.00198421639f) - 273.15f) * 1000; // Static conversation, copied from xps sysmon standalone driver diff --git a/slsDetectorServers/eigerDetectorServer/FebControl.h b/slsDetectorServers/eigerDetectorServer/FebControl.h index 07921d65b..856b5b015 100644 --- a/slsDetectorServers/eigerDetectorServer/FebControl.h +++ b/slsDetectorServers/eigerDetectorServer/FebControl.h @@ -56,7 +56,9 @@ int Feb_Control_PrepareForAcquisition(); void Feb_Control_PrintAcquisitionSetup(); int Feb_Control_StartAcquisition(); int Feb_Control_StopAcquisition(); -int Feb_Control_SoftwareTrigger(); +int Feb_Control_IsReadyForTrigger(int *readyForTrigger); +int Feb_Control_SendSoftwareTrigger(); +int Feb_Control_SoftwareTrigger(int block); // parameters int Feb_Control_SetDynamicRange(unsigned int four_eight_sixteen_or_thirtytwo); diff --git a/slsDetectorServers/eigerDetectorServer/FebRegisterDefs.h b/slsDetectorServers/eigerDetectorServer/FebRegisterDefs.h index 6d2da9af9..1bc79c331 100644 --- a/slsDetectorServers/eigerDetectorServer/FebRegisterDefs.h +++ b/slsDetectorServers/eigerDetectorServer/FebRegisterDefs.h @@ -33,10 +33,12 @@ #define FEB_REG_STATUS (DAQ_REG_RO_OFFSET + 3) -#define FEB_REG_STATUS_ACQ_DONE_OFST (6) -#define FEB_REG_STATUS_ACQ_DONE_MSK (0x00000001 << FEB_REG_STATUS_ACQ_DONE_OFST) -#define FEB_REG_STATUS_TEMP_OFST (16) -#define FEB_REG_STATUS_TEMP_MSK (0x0000FFFF << FEB_REG_STATUS_TEMP_OFST) +#define FEB_REG_STATUS_WAIT_FOR_TRGGR_OFST (5) +#define FEB_REG_STATUS_WAIT_FOR_TRGGR_MSK (0x00000001 << FEB_REG_STATUS_WAIT_FOR_TRGGR_OFST) +#define FEB_REG_STATUS_ACQ_DONE_OFST (6) +#define FEB_REG_STATUS_ACQ_DONE_MSK (0x00000001 << FEB_REG_STATUS_ACQ_DONE_OFST) +#define FEB_REG_STATUS_TEMP_OFST (16) +#define FEB_REG_STATUS_TEMP_MSK (0x0000FFFF << FEB_REG_STATUS_TEMP_OFST) #define MEAS_SUBPERIOD_REG (DAQ_REG_RO_OFFSET + 4) #define MEAS_PERIOD_REG (DAQ_REG_RO_OFFSET + 5) diff --git a/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c index a97f93544..51c594b9d 100644 --- a/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c @@ -2405,12 +2405,12 @@ int stopStateMachine() { #endif } -int softwareTrigger() { +int softwareTrigger(int block) { #ifdef VIRTUAL return OK; #else sharedMemory_lockLocalLink(); - if (!Feb_Control_SoftwareTrigger()) { + if (!Feb_Control_SoftwareTrigger(block)) { sharedMemory_unlockLocalLink(); return FAIL; } diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h index c351c6689..87e7b7256 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h @@ -556,9 +556,12 @@ int startStateMachine(); void *start_timer(void *arg); #endif int stopStateMachine(); -#if defined(EIGERD) || defined(MYTHEN3D) +#ifdef MYTHEN3D int softwareTrigger(); #endif +#ifdef EIGERD +int softwareTrigger(int block); +#endif #if defined(EIGERD) || defined(MYTHEN3D) int startReadOut(); #endif diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 8f003ebd2..e97b600ab 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -4094,16 +4094,29 @@ int check_version(int file_des) { int software_trigger(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, ("Software Trigger (block: %d\n", arg)); - LOG(logDEBUG1, ("Software Trigger\n")); #if !defined(EIGERD) && !defined(MYTHEN3D) functionNotImplemented(); #else + if (arg && myDetectorType == MYTHEN3) { + ret = FAIL; + strcpy(mess, "Blocking trigger not implemented for Mythen3. Please use non blocking trigger.\n"); + LOG(logERROR, (mess)); + } // only set - if (Server_VerifyLock() == OK) { + else if (Server_VerifyLock() == OK) { +#ifdef MYTHEN3 ret = softwareTrigger(); +#else + ret = softwareTrigger(arg); +#endif if (ret == FAIL) { - sprintf(mess, "Could not send software trigger\n"); + strcpy(mess, "Could not send software trigger\n"); LOG(logERROR, (mess)); } LOG(logDEBUG1, ("Software trigger successful\n")); diff --git a/slsDetectorSoftware/include/sls/Detector.h b/slsDetectorSoftware/include/sls/Detector.h index 1a1b5852d..32b16d192 100644 --- a/slsDetectorSoftware/include/sls/Detector.h +++ b/slsDetectorSoftware/include/sls/Detector.h @@ -522,8 +522,10 @@ class Detector { * numbers for different modules.*/ void setNextFrameNumber(uint64_t value, Positions pos = {}); - /** [Eiger][Mythen3] Sends an internal software trigger to the detector */ - void sendSoftwareTrigger(Positions pos = {}); + /** [Eiger][Mythen3] Sends an internal software trigger to the detector + * block true if command blocks till frames are sent out from that trigger + */ + void sendSoftwareTrigger(const bool block = false, Positions pos = {}); Result getScan(Positions pos = {}) const; diff --git a/slsDetectorSoftware/src/CmdProxy.cpp b/slsDetectorSoftware/src/CmdProxy.cpp index 629bd4233..bd7fdce80 100644 --- a/slsDetectorSoftware/src/CmdProxy.cpp +++ b/slsDetectorSoftware/src/CmdProxy.cpp @@ -1193,6 +1193,41 @@ std::string CmdProxy::Scan(int action) { return os.str(); } +std::string CmdProxy::Trigger(int action) { + std::ostringstream os; + os << cmd << ' '; + if (action == defs::HELP_ACTION) { + if (cmd == "trigger") { + os << "[Eiger][Mythen3] Sends software trigger signal to detector"; + } else if (cmd == "blockingtrigger") { + os << "[Eiger] Sends software trigger signal to detector and " + "blocks till " + "the frames are sent out for that trigger."; + } else { + throw sls::RuntimeError("unknown command " + cmd); + } + os << '\n'; + } else if (action == slsDetectorDefs::GET_ACTION) { + throw sls::RuntimeError("Cannot get"); + } else if (action == slsDetectorDefs::PUT_ACTION) { + if (det_id != -1) { + throw sls::RuntimeError("Cannot execute this at module level"); + } + if (!args.empty()) { + WrongNumberOfParameters(0); + } + bool block = false; + if (cmd == "blockingtrigger") { + block = true; + } + det->sendSoftwareTrigger(block); + os << "successful\n"; + } else { + throw sls::RuntimeError("Unknown action"); + } + return os.str(); +} + /* Network Configuration (Detector<->Receiver) */ std::string CmdProxy::UDPDestinationIP(int action) { diff --git a/slsDetectorSoftware/src/CmdProxy.h b/slsDetectorSoftware/src/CmdProxy.h index da5d38b7e..f0d3e41ff 100644 --- a/slsDetectorSoftware/src/CmdProxy.h +++ b/slsDetectorSoftware/src/CmdProxy.h @@ -571,7 +571,6 @@ class CmdProxy { return ToString(value, unit); } - using FunctionMap = std::map; using StringMap = std::map; @@ -839,7 +838,7 @@ class CmdProxy { {"rx_framescaught", &CmdProxy::rx_framescaught}, {"rx_missingpackets", &CmdProxy::rx_missingpackets}, {"nextframenumber", &CmdProxy::nextframenumber}, - {"trigger", &CmdProxy::trigger}, + {"trigger", &CmdProxy::Trigger}, {"scan", &CmdProxy::Scan}, {"scanerrmsg", &CmdProxy::scanerrmsg}, @@ -900,6 +899,7 @@ class CmdProxy { {"rx_zmqhwm", &CmdProxy::rx_zmqhwm}, /* Eiger Specific */ + {"blockingtrigger", &CmdProxy::Trigger}, {"subexptime", &CmdProxy::subexptime}, {"subdeadtime", &CmdProxy::subdeadtime}, {"overflow", &CmdProxy::overflow}, @@ -1094,6 +1094,7 @@ class CmdProxy { std::string ReceiverStatus(int action); std::string DetectorStatus(int action); std::string Scan(int action); + std::string Trigger(int action); /* Network Configuration (Detector<->Receiver) */ std::string UDPDestinationIP(int action); std::string UDPDestinationIP2(int action); @@ -1445,8 +1446,8 @@ class CmdProxy { "and automatically returns to idle at the end of readout."); EXECUTE_SET_COMMAND(stop, stopDetector, - "\n\tAbort detector acquisition. Status changes " - "to IDLE or STOPPED. Goes to stop server."); + "\n\tAbort detector acquisition. Status changes " + "to IDLE or STOPPED. Goes to stop server."); GET_COMMAND(rx_framescaught, getFramesCaught, "\n\tNumber of frames caught by receiver."); @@ -1460,10 +1461,6 @@ class CmdProxy { "Stopping acquisition might result in " "different frame numbers for different modules."); - EXECUTE_SET_COMMAND( - trigger, sendSoftwareTrigger, - "\n\t[Eiger][Mythen3] Sends software trigger signal to detector."); - GET_COMMAND(scanerrmsg, getScanErrorMessage, "\n\tGets Scan error message if scan ended in error for non " "blocking acquisitions."); diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index 1ca6a2068..1d0bd7489 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -725,8 +725,8 @@ void Detector::setNextFrameNumber(uint64_t value, Positions pos) { pimpl->Parallel(&Module::setNextFrameNumber, pos, value); } -void Detector::sendSoftwareTrigger(Positions pos) { - pimpl->Parallel(&Module::sendSoftwareTrigger, pos); +void Detector::sendSoftwareTrigger(const bool block, Positions pos) { + pimpl->Parallel(&Module::sendSoftwareTrigger, pos, block); } Result Detector::getScan(Positions pos) const { diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index 713229fea..f2ebb2d02 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -776,7 +776,9 @@ void Module::setNextFrameNumber(uint64_t value) { sendToDetector(F_SET_NEXT_FRAME_NUMBER, value, nullptr); } -void Module::sendSoftwareTrigger() { sendToDetectorStop(F_SOFTWARE_TRIGGER); } +void Module::sendSoftwareTrigger(const bool block) { + sendToDetectorStop(F_SOFTWARE_TRIGGER, static_cast(block), nullptr); +} defs::scanParameters Module::getScan() const { return sendToDetector(F_GET_SCAN); diff --git a/slsDetectorSoftware/src/Module.h b/slsDetectorSoftware/src/Module.h index 445bccc40..6462ffac2 100644 --- a/slsDetectorSoftware/src/Module.h +++ b/slsDetectorSoftware/src/Module.h @@ -185,7 +185,7 @@ class Module : public virtual slsDetectorDefs { std::vector getNumMissingPackets() const; uint64_t getNextFrameNumber() const; void setNextFrameNumber(uint64_t value); - void sendSoftwareTrigger(); + void sendSoftwareTrigger(const bool block); defs::scanParameters getScan() const; void setScan(const defs::scanParameters t); std::string getScanErrorMessage() const; diff --git a/slsDetectorSoftware/tests/test-CmdProxy.cpp b/slsDetectorSoftware/tests/test-CmdProxy.cpp index a28fedde2..c9ca73ea2 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy.cpp @@ -1446,6 +1446,45 @@ TEST_CASE("trigger", "[.cmd]") { } } +TEST_CASE("blockingtrigger", "[.cmd]") { + Detector det; + CmdProxy proxy(&det); + REQUIRE_THROWS(proxy.Call("blockingtrigger", {}, -1, GET)); + auto det_type = det.getDetectorType().squash(); + if (det_type != defs::EIGER) { + REQUIRE_THROWS(proxy.Call("blockingtrigger", {}, -1, PUT)); + } else if (det_type == defs::EIGER) { + auto prev_timing = + det.getTimingMode().tsquash("inconsistent timing mode in test"); + auto prev_frames = + det.getNumberOfFrames().tsquash("inconsistent #frames in test"); + auto prev_exptime = + det.getExptime().tsquash("inconsistent exptime in test"); + auto prev_period = + det.getPeriod().tsquash("inconsistent period in test"); + det.setTimingMode(defs::TRIGGER_EXPOSURE); + det.setNumberOfFrames(1); + det.setExptime(std::chrono::microseconds(200)); + det.setPeriod(std::chrono::milliseconds(1)); + auto nextframenumber = + det.getNextFrameNumber().tsquash("inconsistent frame nr in test"); + det.startDetector(); + { + std::ostringstream oss; + proxy.Call("blockingtrigger", {}, -1, PUT, oss); + REQUIRE(oss.str() == "blockingtrigger successful\n"); + } + auto currentfnum = + det.getNextFrameNumber().tsquash("inconsistent frame nr in test"); + REQUIRE(nextframenumber + 1 == currentfnum); + det.stopDetector(); + det.setTimingMode(prev_timing); + det.setNumberOfFrames(prev_frames); + det.setExptime(prev_exptime); + det.setPeriod(prev_period); + } +} + TEST_CASE("clearbusy", "[.cmd]") { Detector det; CmdProxy proxy(&det); diff --git a/slsSupportLib/include/sls/versionAPI.h b/slsSupportLib/include/sls/versionAPI.h index 81f04948d..3766cc731 100644 --- a/slsSupportLib/include/sls/versionAPI.h +++ b/slsSupportLib/include/sls/versionAPI.h @@ -3,10 +3,10 @@ #define APILIB 0x210225 #define APIRECEIVER 0x210225 #define APIGUI 0x210225 -#define APICTB 0x210621 -#define APIGOTTHARD 0x210621 +#define APICTB 0x210621 +#define APIGOTTHARD 0x210621 #define APIGOTTHARD2 0x210621 -#define APIJUNGFRAU 0x210621 -#define APIMYTHEN3 0x210621 -#define APIMOENCH 0x210621 -#define APIEIGER 0x210625 +#define APIJUNGFRAU 0x210621 +#define APIMYTHEN3 0x210621 +#define APIMOENCH 0x210621 +#define APIEIGER 0x210621