mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2026-07-17 13:16:03 +02:00
modified memory model
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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<DerivedServer, VirtualMatterhornServer>,
|
||||
VirtualMemoryModel, HardwareMemoryModel>;
|
||||
|
||||
// TODO: for now in MatterhornServer and not generic Server but can be
|
||||
// templated on different IPCore types for each detector
|
||||
BusCommunication<IPCore, MemoryModel> 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<DerivedServer>::processFunction(const detFuncs function_id,
|
||||
}
|
||||
}
|
||||
|
||||
template <typename DerivedServer>
|
||||
void BaseMatterhornServer<DerivedServer>::setupDetector() {
|
||||
// TODO: extend
|
||||
setNumFrames(1); // maybe have a file with constexpr default values
|
||||
|
||||
setNumTriggers(1);
|
||||
}
|
||||
|
||||
template <typename DerivedServer>
|
||||
ReturnCode BaseMatterhornServer<DerivedServer>::get_num_udp_interfaces(
|
||||
ServerInterface &socket) const {
|
||||
@@ -154,9 +173,11 @@ ReturnCode BaseMatterhornServer<DerivedServer>::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<DerivedServer>::get_receiver_parameters(
|
||||
}
|
||||
|
||||
template <typename DerivedServer>
|
||||
ReturnCode BaseMatterhornServer<DerivedServer>::get_num_frames(
|
||||
ServerInterface &socket) const {
|
||||
uint64_t BaseMatterhornServer<DerivedServer>::getNumFrames() const {
|
||||
|
||||
uint64_t num_frames = get_frames();
|
||||
return static_cast<ReturnCode>(socket.sendResult(num_frames));
|
||||
try {
|
||||
uint32_t num_frames =
|
||||
busCommunication.readRegister(Reg::MH_SM_Frames_Reg);
|
||||
return static_cast<uint64_t>(num_frames);
|
||||
} catch (const std::exception &e) {
|
||||
LOG(logERROR) << "Failed to read number of frames from register: "
|
||||
<< e.what();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename DerivedServer>
|
||||
uint64_t BaseMatterhornServer<DerivedServer>::get_frames() const {
|
||||
return static_cast<uint64_t>(
|
||||
busCommunication.readRegister(Reg::MH_SM_Frames_Reg));
|
||||
void BaseMatterhornServer<DerivedServer>::setNumFrames(
|
||||
const uint64_t num_frames) {
|
||||
|
||||
try {
|
||||
busCommunication.writeRegister(Reg::MH_SM_Frames_Reg,
|
||||
static_cast<uint32_t>(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 <typename DerivedServer>
|
||||
void BaseMatterhornServer<DerivedServer>::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 <typename DerivedServer>
|
||||
uint32_t BaseMatterhornServer<DerivedServer>::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 <typename DerivedServer>
|
||||
ReturnCode BaseMatterhornServer<DerivedServer>::set_module_position(
|
||||
ServerInterface &socket) {
|
||||
|
||||
std::array<int, 2> 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<ReturnCode>(socket.Send(ReturnCode::OK));
|
||||
}
|
||||
|
||||
} // namespace sls
|
||||
@@ -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
|
||||
|
||||
@@ -13,40 +13,30 @@ namespace sls {
|
||||
template <typename MemoryModel>
|
||||
struct IpCoreRegisterBlock<IPCore, MemoryModel> {
|
||||
|
||||
std::map<IPCore, MemoryModel> &operator()() {
|
||||
memoryblocks_.try_emplace(
|
||||
IPCore::MH_RO_SM_AXI,
|
||||
MemoryModel{static_cast<uint32_t>(IPCore::MH_RO_SM_AXI),
|
||||
IPCORE_REGISTER_BLOCK_SIZE});
|
||||
memoryblocks_.try_emplace(
|
||||
IPCore::FHDR_AXI,
|
||||
MemoryModel{static_cast<uint32_t>(IPCore::FHDR_AXI),
|
||||
IPCORE_REGISTER_BLOCK_SIZE});
|
||||
memoryblocks_.try_emplace(
|
||||
IPCore::AURORA_STATUS,
|
||||
MemoryModel{static_cast<uint32_t>(IPCore::AURORA_STATUS),
|
||||
IPCORE_REGISTER_BLOCK_SIZE});
|
||||
memoryblocks_.try_emplace(
|
||||
IPCore::AURORA_STATUS2,
|
||||
MemoryModel{static_cast<uint32_t>(IPCore::AURORA_STATUS2),
|
||||
IPCORE_REGISTER_BLOCK_SIZE});
|
||||
memoryblocks_.try_emplace(
|
||||
IPCore::PACKETIZERREG,
|
||||
MemoryModel{static_cast<uint32_t>(IPCore::PACKETIZERREG),
|
||||
IPCORE_REGISTER_BLOCK_SIZE});
|
||||
memoryblocks_.try_emplace(
|
||||
IPCore::UNKNOWN, MemoryModel{static_cast<uint32_t>(IPCore::UNKNOWN),
|
||||
IPCORE_REGISTER_BLOCK_SIZE});
|
||||
|
||||
return memoryblocks_;
|
||||
}
|
||||
std::map<IPCore, MemoryModel> &operator()() { return memoryblocks_; }
|
||||
|
||||
const std::map<IPCore, MemoryModel> &operator()() const {
|
||||
return memoryblocks_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<IPCore, MemoryModel> memoryblocks_;
|
||||
std::map<IPCore, MemoryModel> memoryblocks_{
|
||||
{IPCore::MH_RO_SM_AXI,
|
||||
MemoryModel{static_cast<uint32_t>(IPCore::MH_RO_SM_AXI),
|
||||
IPCORE_REGISTER_BLOCK_SIZE}},
|
||||
{IPCore::FHDR_AXI, MemoryModel{static_cast<uint32_t>(IPCore::FHDR_AXI),
|
||||
IPCORE_REGISTER_BLOCK_SIZE}},
|
||||
{IPCore::AURORA_STATUS,
|
||||
MemoryModel{static_cast<uint32_t>(IPCore::AURORA_STATUS),
|
||||
IPCORE_REGISTER_BLOCK_SIZE}},
|
||||
{IPCore::AURORA_STATUS2,
|
||||
MemoryModel{static_cast<uint32_t>(IPCore::AURORA_STATUS2),
|
||||
IPCORE_REGISTER_BLOCK_SIZE}},
|
||||
{IPCore::PACKETIZERREG,
|
||||
MemoryModel{static_cast<uint32_t>(IPCore::PACKETIZERREG),
|
||||
IPCORE_REGISTER_BLOCK_SIZE}},
|
||||
{IPCore::UNKNOWN, MemoryModel{static_cast<uint32_t>(IPCore::UNKNOWN),
|
||||
IPCORE_REGISTER_BLOCK_SIZE}}};
|
||||
};
|
||||
|
||||
} // namespace sls
|
||||
@@ -4,14 +4,15 @@ namespace sls {
|
||||
|
||||
MatterhornServer::MatterhornServer(uint16_t port)
|
||||
: BaseMatterhornServer<MatterhornServer>(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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
#include <sys/mman.h>
|
||||
#include <vector>
|
||||
|
||||
// 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<IPCoreEnumType, MemoryModel> 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<IPCoreEnumType, MemoryModel>::readRegister(
|
||||
|
||||
template <typename IPCoreEnumType, typename MemoryModel>
|
||||
void BusCommunication<IPCoreEnumType, MemoryModel>::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<IPCoreEnumType, MemoryModel>::bus_r(
|
||||
template <typename IPCoreEnumType, typename MemoryModel>
|
||||
void BusCommunication<IPCoreEnumType, MemoryModel>::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;
|
||||
|
||||
@@ -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<uint64_t>(rand() % 256) << (i * 8));
|
||||
}
|
||||
return mac;
|
||||
}
|
||||
|
||||
/// @brief Shared memory structure for stop server to store run status
|
||||
struct acquisitionStatus {
|
||||
|
||||
@@ -65,12 +78,17 @@ template <typename DerivedDetectorServer> 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<acquisitionStatus> 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 <typename DerivedDetectorServer> 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 <typename DerivedDetectorServer>
|
||||
@@ -162,9 +188,20 @@ ReturnCode DetectorServer<DerivedDetectorServer>::processFunction(
|
||||
case detFuncs::F_GET_RUN_STATUS:
|
||||
return static_cast<DerivedDetectorServer *>(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<DerivedDetectorServer *>(this)
|
||||
->get_receiver_parameters(socket);
|
||||
case detFuncs::F_SET_POSITION:
|
||||
return static_cast<DerivedDetectorServer *>(this)->set_module_position(
|
||||
socket);
|
||||
default:
|
||||
LOG(logDEBUG) << "Checking specific server functions for function ID: "
|
||||
<< function_id;
|
||||
@@ -189,6 +226,30 @@ void DetectorServer<DerivedDetectorServer>::createSharedMemory() {
|
||||
}
|
||||
}
|
||||
|
||||
template <typename DerivedDetectorServer>
|
||||
void DetectorServer<DerivedDetectorServer>::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 <typename DerivedDetectorServer>
|
||||
ReturnCode DetectorServer<DerivedDetectorServer>::get_update_mode(
|
||||
ServerInterface &socket) const {
|
||||
@@ -210,8 +271,13 @@ ReturnCode DetectorServer<DerivedDetectorServer>::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<ReturnCode>(socket.Send(ReturnCode::OK));
|
||||
}
|
||||
|
||||
@@ -315,4 +381,71 @@ ReturnCode DetectorServer<DerivedDetectorServer>::get_destination_udp_port(
|
||||
return static_cast<ReturnCode>(socket.sendResult(udpDetails[0].dstport));
|
||||
};
|
||||
|
||||
template <typename DerivedDetectorServer>
|
||||
ReturnCode DetectorServer<DerivedDetectorServer>::get_num_frames(
|
||||
ServerInterface &socket) const {
|
||||
uint64_t num_frames{};
|
||||
try {
|
||||
num_frames =
|
||||
static_cast<const DerivedDetectorServer *>(this)->getNumFrames();
|
||||
} catch (const std::exception &e) {
|
||||
LOG(logERROR) << "Failed to get number of frames: " << e.what();
|
||||
return ReturnCode::FAIL;
|
||||
}
|
||||
return static_cast<ReturnCode>(socket.sendResult(num_frames));
|
||||
}
|
||||
|
||||
template <typename DerivedDetectorServer>
|
||||
ReturnCode
|
||||
DetectorServer<DerivedDetectorServer>::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<DerivedDetectorServer *>(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<ReturnCode>(socket.Send(ReturnCode::OK));
|
||||
}
|
||||
|
||||
template <typename DerivedDetectorServer>
|
||||
ReturnCode DetectorServer<DerivedDetectorServer>::get_num_triggers(
|
||||
ServerInterface &socket) const {
|
||||
uint32_t num_triggers{};
|
||||
try {
|
||||
num_triggers =
|
||||
static_cast<const DerivedDetectorServer *>(this)->getNumTriggers();
|
||||
} catch (const std::exception &e) {
|
||||
LOG(logERROR) << "Failed to get number of triggers: " << e.what();
|
||||
return ReturnCode::FAIL;
|
||||
}
|
||||
return static_cast<ReturnCode>(socket.sendResult(num_triggers));
|
||||
}
|
||||
|
||||
template <typename DerivedDetectorServer>
|
||||
ReturnCode DetectorServer<DerivedDetectorServer>::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<DerivedDetectorServer *>(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<ReturnCode>(socket.Send(ReturnCode::OK));
|
||||
}
|
||||
|
||||
} // namespace sls
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "fmt/format.h"
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
/// @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<uint32_t[]> mapped_memory_ptr;
|
||||
std::vector<uint32_t> mapped_memory{};
|
||||
|
||||
/// @brief offset of the IP core base address in the memory space, used for
|
||||
/// mapping
|
||||
|
||||
@@ -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 <typename T>
|
||||
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<uint32_t>(field_value) & reg_field.bitmask)
|
||||
<< reg_field.bit_position;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
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<T>(field_value);
|
||||
}
|
||||
|
||||
} // namespace sls
|
||||
@@ -59,10 +59,15 @@ VirtualMemoryModel::VirtualMemoryModel(const uint32_t IPcore_base_address,
|
||||
|
||||
void VirtualMemoryModel::mapToMemory() {
|
||||
|
||||
mapped_memory_ptr =
|
||||
std::make_unique<uint32_t[]>(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();
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user