From 8f18eaca925283d4ba310f4e63ba7947d0302478 Mon Sep 17 00:00:00 2001 From: Alice Date: Mon, 18 May 2026 10:31:14 +0200 Subject: [PATCH] modified memory model --- etc/generate_registerdefs.py | 11 ++ .../include/BaseMatterhornServer.h | 155 ++++++++++++++++-- .../matterhornServer/include/RegisterDefs.hpp | 43 ++++- .../include/SpecializedTemplates.h | 46 ++---- .../matterhornServer/src/MatterhornServer.cpp | 5 +- .../src/VirtualMatterhornServer.cpp | 4 +- .../include/ArmBusCommunication.hpp | 12 +- .../include/DetectorServer.h | 139 +++++++++++++++- .../include/MemoryModel.hpp | 15 +- .../include/RegisterHelperStructs.hpp | 24 +++ .../slsDetectorServer_cpp/src/MemoryModel.cpp | 13 +- slsReceiverSoftware/src/GeneralData.h | 11 +- slsReceiverSoftware/src/receiver_defs.h | 3 + 13 files changed, 408 insertions(+), 73 deletions(-) diff --git a/etc/generate_registerdefs.py b/etc/generate_registerdefs.py index 2e83a9057..47e5d4c32 100644 --- a/etc/generate_registerdefs.py +++ b/etc/generate_registerdefs.py @@ -78,6 +78,17 @@ constexpr RegisterField ModuleIndex{ """ postpend = r""" +constexpr RegisterField ModuleRow{ + Frame_HDR_ModCoord_LSB_Reg, 0, 0xffff}; + +constexpr RegisterField ModuleCol{ + Frame_HDR_ModCoord_LSB_Reg, 16, 0xffff}; + +constexpr RegisterField ModuleCoordz{ + Frame_HDR_ModCoord_MSB_Reg, 0, 0xffff}; + +constexpr RegisterField ModuleIndex{ + Frame_HDR_ModCoord_MSB_Reg, 16, 0xffff}; } // namespace Reg } // namespace sls // clang-format on diff --git a/slsDetectorServers/matterhornServer/include/BaseMatterhornServer.h b/slsDetectorServers/matterhornServer/include/BaseMatterhornServer.h index c3122b8c2..3ecd0c6c5 100644 --- a/slsDetectorServers/matterhornServer/include/BaseMatterhornServer.h +++ b/slsDetectorServers/matterhornServer/include/BaseMatterhornServer.h @@ -53,9 +53,15 @@ class BaseMatterhornServer ReturnCode get_receiver_parameters(ServerInterface &socket) const; - ReturnCode get_num_frames(ServerInterface &socket) const; + ReturnCode set_module_position(ServerInterface &socket); - uint64_t get_frames() const; + uint64_t getNumFrames() const; + + void setNumFrames(const uint64_t num_frames); + + uint32_t getNumTriggers() const; + + void setNumTriggers(const uint32_t num_triggers); /** * @brief call function corresponding to the function ID received from the @@ -71,13 +77,18 @@ class BaseMatterhornServer std::is_same_v, VirtualMemoryModel, HardwareMemoryModel>; + // TODO: for now in MatterhornServer and not generic Server but can be + // templated on different IPCore types for each detector BusCommunication busCommunication{}; + // TODO: probably virtaul server specific details, can be moved to derived + // class + /// @brief initial setup of detector + void setupDetector(); + private: static std::string getMatterhornServerVersion(); - int64_t getNumFrames() const; - static constexpr uint8_t numUDPInterfaces = 1; // only one udp per module for now }; @@ -95,6 +106,14 @@ BaseMatterhornServer::processFunction(const detFuncs function_id, } } +template +void BaseMatterhornServer::setupDetector() { + // TODO: extend + setNumFrames(1); // maybe have a file with constexpr default values + + setNumTriggers(1); +} + template ReturnCode BaseMatterhornServer::get_num_udp_interfaces( ServerInterface &socket) const { @@ -154,9 +173,11 @@ ReturnCode BaseMatterhornServer::get_receiver_parameters( rx_params.udp_dstmac = this->udpDetails[0].dstmac; - rx_params.frames = get_frames(); + rx_params.frames = getNumFrames(); - // rx_params.triggers = 0; + rx_params.triggers = getNumTriggers(); + + // TODO: extend // rx_params.expTimeNs = 0; @@ -172,17 +193,125 @@ ReturnCode BaseMatterhornServer::get_receiver_parameters( } template -ReturnCode BaseMatterhornServer::get_num_frames( - ServerInterface &socket) const { +uint64_t BaseMatterhornServer::getNumFrames() const { - uint64_t num_frames = get_frames(); - return static_cast(socket.sendResult(num_frames)); + try { + uint32_t num_frames = + busCommunication.readRegister(Reg::MH_SM_Frames_Reg); + return static_cast(num_frames); + } catch (const std::exception &e) { + LOG(logERROR) << "Failed to read number of frames from register: " + << e.what(); + throw; + } } template -uint64_t BaseMatterhornServer::get_frames() const { - return static_cast( - busCommunication.readRegister(Reg::MH_SM_Frames_Reg)); +void BaseMatterhornServer::setNumFrames( + const uint64_t num_frames) { + + try { + busCommunication.writeRegister(Reg::MH_SM_Frames_Reg, + static_cast(num_frames)); + } catch (const std::exception &e) { + LOG(logERROR) << "Failed to set number of frames: " << e.what(); + throw; + } + // TODO: maybe always check that the value is correctly set by reading back + // the register and comparing +} + +template +void BaseMatterhornServer::setNumTriggers( + const uint32_t num_triggers) { + + try { + busCommunication.writeRegister(Reg::MH_SM_Triggers_Reg, num_triggers); + } catch (const std::exception &e) { + LOG(logERROR) << "Failed to set number of triggers: " << e.what(); + throw; + } +} + +template +uint32_t BaseMatterhornServer::getNumTriggers() const { + + try { + uint32_t num_triggers = + busCommunication.readRegister(Reg::MH_SM_Triggers_Reg); + return num_triggers; + } catch (const std::exception &e) { + LOG(logERROR) << "Failed to read number of triggers from register: " + << e.what(); + throw; + } +} + +template +ReturnCode BaseMatterhornServer::set_module_position( + ServerInterface &socket) { + + std::array position_info{}; // [num_modules_in_y, module_index] + try { + int ret = socket.Receive(position_info.data(), + position_info.size() * sizeof(int)); + } catch (const SocketError &e) { + LOG(logERROR) + << "Failed to receive num modules in y dimension and module index: " + << e.what(); + return ReturnCode::FAIL; + } + + const size_t module_row = position_info[1] % position_info[0]; + const size_t module_col = position_info[1] / position_info[0]; + + // write to register + uint32_t register_value_LSB{}; + uint32_t register_value_MSB{}; + + try { + register_value_LSB = + busCommunication.readRegister(Reg::Frame_HDR_ModCoord_LSB_Reg); + register_value_MSB = + busCommunication.readRegister(Reg::Frame_HDR_ModCoord_MSB_Reg); + } catch (const std::exception &e) { + LOG(logERROR) << "Failed to read module position register: " + << e.what(); + return ReturnCode::FAIL; + } + + setRegisterField(register_value_LSB, Reg::ModuleRow, module_row); + setRegisterField(register_value_LSB, Reg::ModuleCol, module_col); + setRegisterField(register_value_MSB, Reg::ModuleCoordz, 0); + setRegisterField(register_value_MSB, Reg::ModuleIndex, position_info[1]); + + try { + busCommunication.writeRegister(Reg::Frame_HDR_ModCoord_LSB_Reg, + register_value_LSB); + busCommunication.writeRegister(Reg::Frame_HDR_ModCoord_MSB_Reg, + register_value_MSB); + } catch (const std::exception &e) { + LOG(logERROR) << "Failed to write module position register: " + << e.what(); + return ReturnCode::FAIL; + } + + // configure mac address based on module position + if (this->udpDetails[0].srcmac == + 0) { // only configure if source mac address is not set already + this->udpDetails[0].srcmac = generaterandomMacAddress(); + uint64_t newSrcMac = (this->udpDetails[0].srcmac & 0xffffffffffff0000) | + (module_row << 16) | module_col; + try { + this->updateSrcMacAddress(newSrcMac); + } catch (const std::invalid_argument &e) { + LOG(logERROR) << "Failed to update source MAC address: " + << e.what(); + return ReturnCode::FAIL; + } + } + + return static_cast(socket.Send(ReturnCode::OK)); } } // namespace sls \ No newline at end of file diff --git a/slsDetectorServers/matterhornServer/include/RegisterDefs.hpp b/slsDetectorServers/matterhornServer/include/RegisterDefs.hpp index d0aa2f914..b695909f4 100644 --- a/slsDetectorServers/matterhornServer/include/RegisterDefs.hpp +++ b/slsDetectorServers/matterhornServer/include/RegisterDefs.hpp @@ -1,3 +1,5 @@ + +// clang-format off #pragma once #include "RegisterHelperStructs.hpp" @@ -20,6 +22,7 @@ constexpr size_t IPCORE_REGISTER_BLOCK_SIZE = // clang-format off namespace Reg { + // Register definitions constexpr Register CTRL_Reg{IPCore::UNKNOWN, 0x0}; @@ -27,7 +30,7 @@ constexpr Register Status_Reg{IPCore::UNKNOWN, 0x4}; constexpr Register FPGAVersionReg{IPCore::UNKNOWN, 0x8}; -constexpr Register FPGA_GIT_HEAD_Reg{IPCore::UNKNOWN, 0xc}; +constexpr Register FPGA_GIT_HEADReg{IPCore::UNKNOWN, 0xc}; constexpr Register FixedPatternReg{IPCore::UNKNOWN, 0x10}; @@ -47,6 +50,8 @@ constexpr Register MH_SM_StoreLength_Reg{IPCore::MH_RO_SM_AXI, 0x10}; constexpr Register MH_SM_ResetMHLength_Reg{IPCore::MH_RO_SM_AXI, 0x14}; +constexpr Register MH_SM_Triggers_Reg{IPCore::MH_RO_SM_AXI, 0x18}; + constexpr Register Frame_HDR_Set_Reg{IPCore::FHDR_AXI, 0x0}; constexpr Register Frame_HDR_FrameNumLSB_Reg{IPCore::FHDR_AXI, 0x4}; @@ -121,7 +126,7 @@ constexpr RegisterField FPGADetType{ FPGAVersionReg, 24, 0xff}; constexpr RegisterField FPGA_GIT_HEAD{ - FPGA_GIT_HEAD_Reg, 0, 0xffffffff}; + FPGA_GIT_HEADReg, 0, 0xffffffff}; constexpr RegisterField FixedPattern{ FixedPatternReg, 0, 0xffffffff}; @@ -141,6 +146,24 @@ constexpr RegisterField Start_Acquistion{ constexpr RegisterField Stop_Acquistion{ MH_SM_Ctrl_Reg, 1, 0x1}; +constexpr RegisterField External_Counter_Enable{ + MH_SM_Ctrl_Reg, 2, 0x1}; + +constexpr RegisterField Parallel_RO{ + MH_SM_Ctrl_Reg, 3, 0x1}; + +constexpr RegisterField Trigger_Mode{ + MH_SM_Ctrl_Reg, 4, 0x3}; + +constexpr RegisterField HW_Trigger_Polarity{ + MH_SM_Ctrl_Reg, 6, 0x1}; + +constexpr RegisterField SW_Trigger{ + MH_SM_Ctrl_Reg, 7, 0x1}; + +constexpr RegisterField Reset_Readout_SM{ + MH_SM_Ctrl_Reg, 8, 0x1}; + constexpr RegisterField MH_Readout_Exposure_Time{ MH_SM_Exposure_Reg, 0, 0xffffffff}; @@ -156,6 +179,9 @@ constexpr RegisterField MH_SM_StoreLength{ constexpr RegisterField MH_SM_ResetMHLength{ MH_SM_ResetMHLength_Reg, 0, 0xffffffff}; +constexpr RegisterField MH_SM_Triggers{ + MH_SM_Triggers_Reg, 0, 0xffffffff}; + constexpr RegisterField Frame_Hdr_Set_Framenumber{ Frame_HDR_Set_Reg, 0, 0x1}; @@ -240,7 +266,18 @@ constexpr RegisterField Coordy{ constexpr RegisterField Coordz{ PktCoordReg2, 0, 0xffff}; -} // namespace Reg +constexpr RegisterField ModuleRow{ + Frame_HDR_ModCoord_LSB_Reg, 0, 0xffff}; + +constexpr RegisterField ModuleCol{ + Frame_HDR_ModCoord_LSB_Reg, 16, 0xffff}; + +constexpr RegisterField ModuleCoordz{ + Frame_HDR_ModCoord_MSB_Reg, 0, 0xffff}; + +constexpr RegisterField ModuleIndex{ + Frame_HDR_ModCoord_MSB_Reg, 16, 0xffff}; +} // namespace Reg } // namespace sls // clang-format on diff --git a/slsDetectorServers/matterhornServer/include/SpecializedTemplates.h b/slsDetectorServers/matterhornServer/include/SpecializedTemplates.h index 6dd2eefaa..4f57e825a 100644 --- a/slsDetectorServers/matterhornServer/include/SpecializedTemplates.h +++ b/slsDetectorServers/matterhornServer/include/SpecializedTemplates.h @@ -13,40 +13,30 @@ namespace sls { template struct IpCoreRegisterBlock { - std::map &operator()() { - memoryblocks_.try_emplace( - IPCore::MH_RO_SM_AXI, - MemoryModel{static_cast(IPCore::MH_RO_SM_AXI), - IPCORE_REGISTER_BLOCK_SIZE}); - memoryblocks_.try_emplace( - IPCore::FHDR_AXI, - MemoryModel{static_cast(IPCore::FHDR_AXI), - IPCORE_REGISTER_BLOCK_SIZE}); - memoryblocks_.try_emplace( - IPCore::AURORA_STATUS, - MemoryModel{static_cast(IPCore::AURORA_STATUS), - IPCORE_REGISTER_BLOCK_SIZE}); - memoryblocks_.try_emplace( - IPCore::AURORA_STATUS2, - MemoryModel{static_cast(IPCore::AURORA_STATUS2), - IPCORE_REGISTER_BLOCK_SIZE}); - memoryblocks_.try_emplace( - IPCore::PACKETIZERREG, - MemoryModel{static_cast(IPCore::PACKETIZERREG), - IPCORE_REGISTER_BLOCK_SIZE}); - memoryblocks_.try_emplace( - IPCore::UNKNOWN, MemoryModel{static_cast(IPCore::UNKNOWN), - IPCORE_REGISTER_BLOCK_SIZE}); - - return memoryblocks_; - } + std::map &operator()() { return memoryblocks_; } const std::map &operator()() const { return memoryblocks_; } private: - std::map memoryblocks_; + std::map memoryblocks_{ + {IPCore::MH_RO_SM_AXI, + MemoryModel{static_cast(IPCore::MH_RO_SM_AXI), + IPCORE_REGISTER_BLOCK_SIZE}}, + {IPCore::FHDR_AXI, MemoryModel{static_cast(IPCore::FHDR_AXI), + IPCORE_REGISTER_BLOCK_SIZE}}, + {IPCore::AURORA_STATUS, + MemoryModel{static_cast(IPCore::AURORA_STATUS), + IPCORE_REGISTER_BLOCK_SIZE}}, + {IPCore::AURORA_STATUS2, + MemoryModel{static_cast(IPCore::AURORA_STATUS2), + IPCORE_REGISTER_BLOCK_SIZE}}, + {IPCore::PACKETIZERREG, + MemoryModel{static_cast(IPCore::PACKETIZERREG), + IPCORE_REGISTER_BLOCK_SIZE}}, + {IPCore::UNKNOWN, MemoryModel{static_cast(IPCore::UNKNOWN), + IPCORE_REGISTER_BLOCK_SIZE}}}; }; } // namespace sls \ No newline at end of file diff --git a/slsDetectorServers/matterhornServer/src/MatterhornServer.cpp b/slsDetectorServers/matterhornServer/src/MatterhornServer.cpp index 489e25963..a45043e81 100644 --- a/slsDetectorServers/matterhornServer/src/MatterhornServer.cpp +++ b/slsDetectorServers/matterhornServer/src/MatterhornServer.cpp @@ -4,14 +4,15 @@ namespace sls { MatterhornServer::MatterhornServer(uint16_t port) : BaseMatterhornServer(port) { - // map the IP core base addresses to memory busCommunication.mapToMemory(); // TODO: should this happen in constructor? // should maybe be part of the constructor? tcpInterface->startTCPServer(); - // need a function to setup detector - e.g. set all registers etc. + // TODO: no init_server function for now is it neccessary to set the init + // flag + this->setupDetector(); } ReturnCode MatterhornServer::initial_checks(ServerInterface &socket) { diff --git a/slsDetectorServers/matterhornServer/src/VirtualMatterhornServer.cpp b/slsDetectorServers/matterhornServer/src/VirtualMatterhornServer.cpp index 4adc1e1b0..88cfbfe2a 100644 --- a/slsDetectorServers/matterhornServer/src/VirtualMatterhornServer.cpp +++ b/slsDetectorServers/matterhornServer/src/VirtualMatterhornServer.cpp @@ -14,7 +14,9 @@ VirtualMatterhornServer::VirtualMatterhornServer(uint16_t port) // should maybe be part of the constructor? tcpInterface->startTCPServer(); - // need a function to setup detector - e.g. set all registers etc. + // TODO: no init_server function for now is it neccessary to set the init + // flag + this->setupDetector(); } ReturnCode VirtualMatterhornServer::initial_checks(ServerInterface &socket) { diff --git a/slsDetectorServers/slsDetectorServer_cpp/include/ArmBusCommunication.hpp b/slsDetectorServers/slsDetectorServer_cpp/include/ArmBusCommunication.hpp index f1a80947d..3cc5222d7 100644 --- a/slsDetectorServers/slsDetectorServer_cpp/include/ArmBusCommunication.hpp +++ b/slsDetectorServers/slsDetectorServer_cpp/include/ArmBusCommunication.hpp @@ -9,8 +9,8 @@ #include #include -// TODO: maybe should be templated on address type (e.g. uint32_t or uint64_t) -// for more flexibility? +// TODO: maybe should be templated on address type (e.g. uint32_t register or +// uint64_t register) for more flexibility? namespace sls { @@ -38,14 +38,14 @@ class BusCommunication { void mapToMemory(); uint32_t readRegister(const Register ®ister_) const; - void writeRegister(const Register ®ister_, const uint32_t data) const; + void writeRegister(const Register ®ister_, const uint32_t data); private: /// @brief stores register blocks for each IP core IpCoreRegisterBlock ipcoreregisterblocks; void bus_w(const uint32_t offset, IPCoreEnumType baseadress, - const uint32_t data) const; + const uint32_t data); uint32_t bus_r(const uint32_t offset, IPCoreEnumType baseadress) const; }; @@ -66,7 +66,7 @@ uint32_t BusCommunication::readRegister( template void BusCommunication::writeRegister( - const Register ®ister_, const uint32_t data) const { + const Register ®ister_, const uint32_t data) { bus_w(register_.offset_in_bytes, register_.ip_core, data); } @@ -81,7 +81,7 @@ uint32_t BusCommunication::bus_r( template void BusCommunication::bus_w( const uint32_t offset, const IPCoreEnumType baseadress, - const uint32_t data) const { + const uint32_t data) { auto ptr1 = ipcoreregisterblocks().at(baseadress).getMappedMemoryPtr() + offset / (sizeof(uint32_t)); *ptr1 = data; diff --git a/slsDetectorServers/slsDetectorServer_cpp/include/DetectorServer.h b/slsDetectorServers/slsDetectorServer_cpp/include/DetectorServer.h index c3170526d..2fb5f171a 100644 --- a/slsDetectorServers/slsDetectorServer_cpp/include/DetectorServer.h +++ b/slsDetectorServers/slsDetectorServer_cpp/include/DetectorServer.h @@ -26,6 +26,19 @@ struct UDPInfo { }; using ReturnCode = slsDetectorDefs::ReturnCode; +/// @brief generates a random locally administered unicast MAC address for the +/// source UDP +/// @return generated MAC address +inline uint64_t generaterandomMacAddress() { + uint64_t mac = + 0xAA0000000000; // locally administered unicast address (0xA: 0b1010) // + // TODO maybe 0x02000000000 better? + for (int i = 2; i < 5; ++i) { + mac |= (static_cast(rand() % 256) << (i * 8)); + } + return mac; +} + /// @brief Shared memory structure for stop server to store run status struct acquisitionStatus { @@ -65,12 +78,17 @@ template class DetectorServer { udpDetails{}; // TODO: for now only one receiver per module /// @brief TODO what is this? - bool updateMode{true}; + bool updateMode{ + false}; // what should the default be - can update module size etc. /// @brief shared mempory with aquisition status mutable SharedMemory shm{ 0, 0}; // TODO: is mutable really neccessary? + /// @brief sets source UDP MAC address in udpDetails and updates udp header + /// @param srcmac + void updateSrcMacAddress(const uint64_t srcmac); + private: /// @brief creates and maps shared memory void createSharedMemory(); @@ -102,6 +120,14 @@ template class DetectorServer { ReturnCode set_destination_udp_port(ServerInterface &socket); ReturnCode get_destination_udp_port(ServerInterface &socket) const; + + ReturnCode get_num_frames(ServerInterface &socket) const; + + ReturnCode set_num_frames(ServerInterface &socket); + + ReturnCode get_num_triggers(ServerInterface &socket) const; + + ReturnCode set_num_triggers(ServerInterface &socket); }; template @@ -162,9 +188,20 @@ ReturnCode DetectorServer::processFunction( case detFuncs::F_GET_RUN_STATUS: return static_cast(this)->get_run_status( socket); + case detFuncs::F_GET_NUM_FRAMES: + return get_num_frames(socket); + case detFuncs::F_SET_NUM_FRAMES: + return set_num_frames(socket); + case detFuncs::F_GET_NUM_TRIGGERS: + return get_num_triggers(socket); + case detFuncs::F_SET_NUM_TRIGGERS: + return set_num_triggers(socket); case detFuncs::F_GET_RECEIVER_PARAMETERS: return static_cast(this) ->get_receiver_parameters(socket); + case detFuncs::F_SET_POSITION: + return static_cast(this)->set_module_position( + socket); default: LOG(logDEBUG) << "Checking specific server functions for function ID: " << function_id; @@ -189,6 +226,30 @@ void DetectorServer::createSharedMemory() { } } +template +void DetectorServer::updateSrcMacAddress( + const uint64_t srcmac) { + + LOG(logINFO) << "Updating source MAC address to: " + << fmt::format("{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}", + (srcmac >> 40) & 0xff, (srcmac >> 32) & 0xff, + (srcmac >> 24) & 0xff, (srcmac >> 16) & 0xff, + (srcmac >> 8) & 0xff, srcmac & 0xff); + + if ((srcmac & 0x020000000000) == 0) { + LOG(logERROR) << "Invalid source MAC address: unicast bit or local " + "administration bit is not set"; + throw std::invalid_argument("Invalid source MAC address: unicast bit " + "or local administration bit is not set"); + } + + udpDetails[0].srcmac = srcmac; + + // TODO: update UDP header with new source MAC address + + // TODO: do i need to keep track of the configured member ? +} + template ReturnCode DetectorServer::get_update_mode( ServerInterface &socket) const { @@ -210,8 +271,13 @@ ReturnCode DetectorServer::set_source_udp_mac( return ReturnCode::FAIL; } - udpDetails[0].srcmac = newsrcudpMac; - // TODO: configuremac, check unicast address + try { + updateSrcMacAddress(newsrcudpMac); + } catch (const std::invalid_argument &e) { + LOG(logERROR) << "Failed to update source MAC address: " << e.what(); + return ReturnCode::FAIL; + } + return static_cast(socket.Send(ReturnCode::OK)); } @@ -315,4 +381,71 @@ ReturnCode DetectorServer::get_destination_udp_port( return static_cast(socket.sendResult(udpDetails[0].dstport)); }; +template +ReturnCode DetectorServer::get_num_frames( + ServerInterface &socket) const { + uint64_t num_frames{}; + try { + num_frames = + static_cast(this)->getNumFrames(); + } catch (const std::exception &e) { + LOG(logERROR) << "Failed to get number of frames: " << e.what(); + return ReturnCode::FAIL; + } + return static_cast(socket.sendResult(num_frames)); +} + +template +ReturnCode +DetectorServer::set_num_frames(ServerInterface &socket) { + int64_t num_frames{}; + try { + int ret = socket.Receive(num_frames); + } catch (const SocketError &e) { + LOG(logERROR) << "Failed to receive number of frames: " << e.what(); + return ReturnCode::FAIL; + } + try { + static_cast(this)->setNumFrames(num_frames); + } catch (const std::exception &e) { + LOG(logERROR) << "Failed to set number of frames: " << e.what(); + return ReturnCode::FAIL; + } + return static_cast(socket.Send(ReturnCode::OK)); +} + +template +ReturnCode DetectorServer::get_num_triggers( + ServerInterface &socket) const { + uint32_t num_triggers{}; + try { + num_triggers = + static_cast(this)->getNumTriggers(); + } catch (const std::exception &e) { + LOG(logERROR) << "Failed to get number of triggers: " << e.what(); + return ReturnCode::FAIL; + } + return static_cast(socket.sendResult(num_triggers)); +} + +template +ReturnCode DetectorServer::set_num_triggers( + ServerInterface &socket) { + uint32_t num_triggers{}; + try { + int ret = socket.Receive(num_triggers); + } catch (const SocketError &e) { + LOG(logERROR) << "Failed to receive number of triggers: " << e.what(); + return ReturnCode::FAIL; + } + try { + static_cast(this)->setNumTriggers( + num_triggers); + } catch (const std::exception &e) { + LOG(logERROR) << "Failed to set number of triggers: " << e.what(); + return ReturnCode::FAIL; + } + return static_cast(socket.Send(ReturnCode::OK)); +} + } // namespace sls \ No newline at end of file diff --git a/slsDetectorServers/slsDetectorServer_cpp/include/MemoryModel.hpp b/slsDetectorServers/slsDetectorServer_cpp/include/MemoryModel.hpp index d1b1a5aea..06a6892cb 100644 --- a/slsDetectorServers/slsDetectorServer_cpp/include/MemoryModel.hpp +++ b/slsDetectorServers/slsDetectorServer_cpp/include/MemoryModel.hpp @@ -1,6 +1,6 @@ #include "fmt/format.h" #include -#include +#include /// @brief class to handle memory mapping and access for hardware IP cores class HardwareMemoryModel { @@ -38,19 +38,14 @@ class VirtualMemoryModel { ~VirtualMemoryModel() = default; - VirtualMemoryModel(const VirtualMemoryModel &) = delete; - VirtualMemoryModel &operator=(const VirtualMemoryModel &) = delete; - - VirtualMemoryModel(VirtualMemoryModel &&) noexcept = default; - VirtualMemoryModel & - operator=(VirtualMemoryModel &&) = delete; // const members - void mapToMemory(); - uint32_t *getMappedMemoryPtr() const; + uint32_t *getMappedMemoryPtr(); + + const uint32_t *getMappedMemoryPtr() const; private: - std::unique_ptr mapped_memory_ptr; + std::vector mapped_memory{}; /// @brief offset of the IP core base address in the memory space, used for /// mapping diff --git a/slsDetectorServers/slsDetectorServer_cpp/include/RegisterHelperStructs.hpp b/slsDetectorServers/slsDetectorServer_cpp/include/RegisterHelperStructs.hpp index c62273cdc..7847b0ce4 100644 --- a/slsDetectorServers/slsDetectorServer_cpp/include/RegisterHelperStructs.hpp +++ b/slsDetectorServers/slsDetectorServer_cpp/include/RegisterHelperStructs.hpp @@ -6,6 +6,7 @@ namespace sls { enum class IPCore : uint32_t; // forward declaration of IPCore enum class +/// @brief struct representing 32 bit register struct Register { /// @brief IP core address space const IPCore ip_core{}; // TODO replace by enum type @@ -27,4 +28,27 @@ struct RegisterField { const uint32_t bitmask{}; }; +// TODO: maybe static member function of RegisterField? +template +void setRegisterField(uint32_t ®istervalue, const RegisterField ®_field, + T field_value) { + // Clear the bits corresponding to the field + registervalue &= ~(reg_field.bitmask << reg_field.bit_position); + // Set the new value for the field + registervalue |= (static_cast(field_value) & reg_field.bitmask) + << reg_field.bit_position; +} + +template +T getRegisterField(const uint32_t ®istervalue, + const RegisterField ®_field) { + // Extract the bits corresponding to the field and shift them to get the + // value + + auto field_value = + (registervalue >> reg_field.bit_position) & reg_field.bitmask; + + return static_cast(field_value); +} + } // namespace sls \ No newline at end of file diff --git a/slsDetectorServers/slsDetectorServer_cpp/src/MemoryModel.cpp b/slsDetectorServers/slsDetectorServer_cpp/src/MemoryModel.cpp index ce91b57d3..ed379ace3 100644 --- a/slsDetectorServers/slsDetectorServer_cpp/src/MemoryModel.cpp +++ b/slsDetectorServers/slsDetectorServer_cpp/src/MemoryModel.cpp @@ -59,10 +59,15 @@ VirtualMemoryModel::VirtualMemoryModel(const uint32_t IPcore_base_address, void VirtualMemoryModel::mapToMemory() { - mapped_memory_ptr = - std::make_unique(size_memory_space / sizeof(uint32_t)); + mapped_memory.resize( + size_memory_space / + sizeof(uint32_t)); // TODO: should it be zero initialized? } -uint32_t *VirtualMemoryModel::getMappedMemoryPtr() const { - return mapped_memory_ptr.get(); +uint32_t *VirtualMemoryModel::getMappedMemoryPtr() { + return mapped_memory.data(); +} + +const uint32_t *VirtualMemoryModel::getMappedMemoryPtr() const { + return mapped_memory.data(); } \ No newline at end of file diff --git a/slsReceiverSoftware/src/GeneralData.h b/slsReceiverSoftware/src/GeneralData.h index a17a452b8..256a4a100 100644 --- a/slsReceiverSoftware/src/GeneralData.h +++ b/slsReceiverSoftware/src/GeneralData.h @@ -474,14 +474,15 @@ class MatterhornData : public GeneralData { MatterhornData() { detType = slsDetectorDefs::MATTERHORN; headerSizeinPacket = sizeof(slsDetectorDefs::sls_detector_header); - framesPerFile = 10000; // TODO: dummy value - fifoDepth = 50000; // TODO: dummy value + framesPerFile = MATTERHORN_MAX_FRAMES_PER_FILE; // TODO: dummy value + fifoDepth = 50000; // TODO: dummy value standardheader = true; // udpSocketBufferSize = 0; // TODO: dummy value dynamicRange = 16; // default - tengigaEnable = true; // TODO: not sure + tengigaEnable = true; // TODO: not sure should also be 100g SetCounterMask(0xf); // default all 4 counters enabled UpdateImageSize(); + calculatefifoDepth(); }; void SetDynamicRange(int dr) { @@ -500,6 +501,8 @@ class MatterhornData : public GeneralData { UpdateImageSize(); }; + void calculatefifoDepth() { fifoDepth = max_fifo_depth / imageSize; } + private: void UpdateImageSize() { nPixelsX = (nChannelsX * ncounters); @@ -528,6 +531,8 @@ class MatterhornData : public GeneralData { int ncounters{0}; int nChannelsX{1024}; int nChannelsY{512}; + + constexpr static int max_fifo_depth = 100000; // TODO: dummy value for now }; class Gotthard2Data : public GeneralData { diff --git a/slsReceiverSoftware/src/receiver_defs.h b/slsReceiverSoftware/src/receiver_defs.h index 0d38ba749..6add81fc5 100644 --- a/slsReceiverSoftware/src/receiver_defs.h +++ b/slsReceiverSoftware/src/receiver_defs.h @@ -31,6 +31,9 @@ namespace sls { #define XILINX_CTB_MAX_FRAMES_PER_FILE 20000 #define MYTHEN3_MAX_FRAMES_PER_FILE 10000 #define GOTTHARD2_MAX_FRAMES_PER_FILE 20000 +#define MATTERHORN_MAX_FRAMES_PER_FILE \ + 20000 // dummy value for now - maybe even specialized receiver for + // matterhorn? #define STATISTIC_FRAMENUMBER_INFINITE (20000)