Skip to content

Commit

Permalink
Merge branch 'fl-dev' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
flueke committed Dec 3, 2024
2 parents 2d45b5d + bdd885b commit ad82298
Show file tree
Hide file tree
Showing 17 changed files with 367 additions and 24 deletions.
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[submodule "external/nlohmann_json"]
path = external/nlohmann_json
url = https://github.com/nlohmann/json.git
branch = master
20 changes: 20 additions & 0 deletions doc/command_format.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
vme_read amod data_width address ['late']

vme_block_read amod transfers address [esst_rate]
vme_block_read_swapped amod transfers address [esst_rate]

vme_block_read_mem amod transfers address
vme_block_read_mem_swapped amod transfers address

vme_write amod data_width address value
write_marker value

wait cycles:24

signal_accu
mask_shift_accu mask shift
set_accu value
read_to_accu amod data_width address ['late']
compare_loop_accu cmp value

software_delay delay_ms
8 changes: 8 additions & 0 deletions external/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ option(YAML_BUILD_SHARED_LIBS "Build Shared Libraries" OFF)
add_subdirectory(yaml-cpp)
target_compile_options(yaml-cpp PRIVATE -Wno-shadow)

# nlohmann/json
set(JSON_BuildTests OFF CACHE INTERNAL "")

# If you only include this third party in PRIVATE source files, you do not
# need to install it when your main project gets installed.
set(JSON_Install OFF CACHE INTERNAL "")
add_subdirectory(nlohmann_json)

# Enable the PIC flag to fix a relocation error when linking against the
# static version of yaml-cpp.
set_target_properties(yaml-cpp PROPERTIES POSITION_INDEPENDENT_CODE ON)
Expand Down
1 change: 1 addition & 0 deletions external/nlohmann_json
Submodule nlohmann_json added at 9cca28
2 changes: 2 additions & 0 deletions src/mesytec-mvlc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ add_library(mesytec-mvlc SHARED
util/threadsafequeue.cc
util/ticketmutex.cc
util/udp_sockets.cc
util/yaml_json.cc
)

if (MESYTEC_MVLC_PLATFORM_LINUX)
Expand All @@ -73,6 +74,7 @@ target_link_libraries(mesytec-mvlc
PRIVATE lz4_static
PRIVATE minizip
PRIVATE yaml-cpp
PRIVATE nlohmann_json::nlohmann_json
PUBLIC argh
PUBLIC spdlog::spdlog
PUBLIC Threads::Threads
Expand Down
16 changes: 15 additions & 1 deletion src/mesytec-mvlc/mvlc_command_builders.cc
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,7 @@ StackCommand stack_command_from_string(const std::string &str)
arg = {};
iss >> arg; result.lateRead = (arg == "slow" || arg == "late");
}
// FIXME: undocumeneted as of yet. only the block read versions make sense?
else if (name == "vme_read_mem")
{
result.type = CT::VMEReadMem;
Expand Down Expand Up @@ -522,6 +523,7 @@ StackCommand stack_command_from_string(const std::string &str)
result.type = CT::WriteMarker;
iss >> arg; result.value = std::stoul(arg, nullptr, 0);
}
// TODO: test and document
else if (name == "write_special")
{
result.type = CT::WriteSpecial;
Expand Down Expand Up @@ -567,7 +569,7 @@ StackCommand stack_command_from_string(const std::string &str)
result.type = CT::SoftwareDelay;
iss >> arg; result.value = std::stoul(arg, nullptr, 0);
}
else if (name == "custom_cmd:")
else if (name == "custom_cmd:") // FIXME: remove the YAML dependency or do not support anymore or reimplement
{
// Note: the custom command is encoded as inline YAML!
YAML::Node yRoot = YAML::Load(str);
Expand Down Expand Up @@ -795,6 +797,18 @@ StackCommandBuilder &StackCommandBuilder::addCommand(const StackCommand &cmd)
return *this;
}

StackCommandBuilder &StackCommandBuilder::addCommand(const std::string &str)
{
if (!hasOpenGroup())
beginGroup();

assert(hasOpenGroup());

m_groups.back().commands.push_back(stack_command_from_string(str));

return *this;
}

StackCommandBuilder &StackCommandBuilder::beginGroup(const std::string &name,
const std::map<std::string, std::string> & meta)
{
Expand Down
4 changes: 4 additions & 0 deletions src/mesytec-mvlc/mvlc_command_builders.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ class MESYTEC_MVLC_EXPORT StackCommandBuilder

// Optional meta info. mvme stores the VME module type name (the one
// defined by the mvme templates) under 'vme_module_type'.
// The module vendor names is now also stored under 'vme_module_vendor'.
std::map<std::string, std::string> meta;

bool operator==(const Group &o) const
Expand Down Expand Up @@ -278,6 +279,8 @@ class MESYTEC_MVLC_EXPORT StackCommandBuilder
// Add a manually created StackCommand object.
StackCommandBuilder &addCommand(const StackCommand &cmd);

StackCommandBuilder &addCommand(const std::string &str);

// Begins a new group using the supplied name.
StackCommandBuilder &beginGroup(
const std::string &name = {},
Expand Down Expand Up @@ -342,6 +345,7 @@ class MESYTEC_MVLC_EXPORT StackCommandBuilder
}

size_t commandCount() const;
void clear() { m_groups.clear(); }

private:
std::string m_name;
Expand Down
87 changes: 70 additions & 17 deletions src/mesytec-mvlc/mvlc_readout_config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

#include <cassert>
#include <fstream>
#include <yaml-cpp/yaml.h>
#include <yaml-cpp/emittermanip.h>

#include "util/fmt.h"
#include "util/string_util.h"
#include "util/yaml_json.h"
#include "util/yaml_json_internal.h"

namespace mesytec
{
Expand Down Expand Up @@ -117,17 +117,12 @@ StackCommandBuilder stack_command_builder_from_yaml(const YAML::Node &yStack)
return stack;
}

} // end anon namespace

/// Serializes a CrateConfig to YAML format.
std::string to_yaml(const CrateConfig &crateConfig)
YAML::Emitter &operator<<(YAML::Emitter &out, const CrateConfig &crateConfig)
{
YAML::Emitter out;
assert(out.good());

out << YAML::Hex;

assert(out.good());

out << YAML::BeginMap;
out << YAML::Key << "crate" << YAML::Value << YAML::BeginMap;

Expand Down Expand Up @@ -167,7 +162,18 @@ std::string to_yaml(const CrateConfig &crateConfig)

assert(out.good());

return out.c_str();
return out;
}

} // end anon namespace

inline YAML::Emitter & to_yaml(YAML::Emitter &out, const CrateConfig &crateConfig)
{
out << YAML::Hex;
assert(out.good());
out << crateConfig;
assert(out.good());
return out;
}

/// Parses a CreateConfig from the given YAML input string.
Expand All @@ -180,12 +186,10 @@ CrateConfig crate_config_from_yaml(const std::string &yamlText)

/// Parses a CreateConfig from the given YAML input stream.
/// throws std::runtime_error on error.
CrateConfig crate_config_from_yaml(std::istream &input)
CrateConfig crate_config_from_yaml(const YAML::Node &yRoot)
{
CrateConfig result = {};

YAML::Node yRoot = YAML::Load(input);

if (!yRoot)
throw std::runtime_error("CrateConfig YAML data is empty");

Expand Down Expand Up @@ -249,21 +253,42 @@ CrateConfig crate_config_from_yaml(std::istream &input)
return result;
}

CrateConfig crate_config_from_yaml(std::istream &input)
{
YAML::Node yRoot = YAML::Load(input);

if (!yRoot)
throw std::runtime_error("CrateConfig YAML data is empty");

return crate_config_from_yaml(yRoot);
}

CrateConfig MESYTEC_MVLC_EXPORT crate_config_from_yaml_file(const std::string &filename)
{
std::ifstream input(filename);
input.exceptions(std::ios::failbit | std::ios::badbit);
return crate_config_from_yaml(input);
}

std::string to_yaml(const StackCommandBuilder &sb)
inline YAML::Emitter & to_yaml(YAML::Emitter &out, const StackCommandBuilder &sb)
{
YAML::Emitter out;
out << YAML::Hex;
assert(out.good());
out << sb;
assert(out.good());
return out.c_str();
return out;
}

std::string to_yaml(const StackCommandBuilder &sb)
{
YAML::Emitter yEmitter;
return to_yaml(yEmitter, sb).c_str();
}

std::string to_yaml(const CrateConfig &crateConfig)
{
YAML::Emitter yEmitter;
return to_yaml(yEmitter, crateConfig).c_str();
}

StackCommandBuilder stack_command_builder_from_yaml(const std::string &yaml)
Expand All @@ -282,13 +307,41 @@ StackCommandBuilder stack_command_builder_from_yaml(std::istream &input)
return stack_command_builder_from_yaml(yRoot);
}

StackCommandBuilder MESYTEC_MVLC_EXPORT stack_command_builder_from_yaml_file(
StackCommandBuilder stack_command_builder_from_yaml_file(
const std::string &filename)
{
std::ifstream input(filename);
input.exceptions(std::ios::failbit | std::ios::badbit);
return stack_command_builder_from_yaml(input);
}

namespace detail
{
template<typename T>
std::string to_json(const T &t)
{
YAML::Emitter yEmitter;
YAML::Node yRoot = YAML::Load(to_yaml(yEmitter, t).c_str());

if (!yRoot)
return {};

return util::detail::yaml_to_json(yRoot).dump(true);
}
}

std::string to_json(const CrateConfig &t) { return detail::to_json(t); }
std::string to_json(const StackCommandBuilder &t) { return detail::to_json(t); }

CrateConfig crate_config_from_json(const std::string &json)
{
return crate_config_from_yaml(util::json_to_yaml(json));
}

StackCommandBuilder stack_command_builder_from_json(const std::string &json)
{
return stack_command_builder_from_yaml(util::json_to_yaml(json));
}

} // end namespace mvlc
} // end namespace mesytec
6 changes: 6 additions & 0 deletions src/mesytec-mvlc/mvlc_readout_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ StackCommandBuilder MESYTEC_MVLC_EXPORT stack_command_builder_from_yaml(const st
StackCommandBuilder MESYTEC_MVLC_EXPORT stack_command_builder_from_yaml(std::istream &input);
StackCommandBuilder MESYTEC_MVLC_EXPORT stack_command_builder_from_yaml_file(const std::string &filename);

std::string MESYTEC_MVLC_EXPORT to_json(const CrateConfig &crateConfig);
CrateConfig MESYTEC_MVLC_EXPORT crate_config_from_json(const std::string &json);

std::string MESYTEC_MVLC_EXPORT to_json(const StackCommandBuilder &sb);
StackCommandBuilder MESYTEC_MVLC_EXPORT stack_command_builder_from_json(const std::string &json);


} // end namespace mvlc
} // end namespace mesytec
Expand Down
74 changes: 71 additions & 3 deletions src/mesytec-mvlc/mvlc_readout_config.test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,34 @@ TEST(mvlc_readout_config, StackCommandBuilderYaml)

auto yamlText = to_yaml(sb);

cout << yamlText << endl;
//cout << yamlText << endl;

auto sb1 = stack_command_builder_from_yaml(yamlText);

ASSERT_EQ(sb, sb1); // depends on StackCommandBuilder::operator==() being correct!
}

TEST(mvlc_readout_config, StackCommandBuilderJson)
{
StackCommandBuilder sb("myStack");
sb.beginGroup("module0");
sb.addVMEBlockRead(0x00000000u, vme_amods::MBLT64, (1u << 16)-1);
sb.beginGroup("module1");
sb.addVMEBlockRead(0x10000000u, vme_amods::MBLT64, (1u << 16)-1);
sb.beginGroup("module2");
sb.addVMEBlockReadSwapped(0x20000000u, vme_amods::MBLT64, (1u << 16)-1);
sb.beginGroup("reset");
sb.addVMEWrite(0xbb006070u, 1, vme_amods::A32, VMEDataWidth::D32);

auto jsonText = to_json(sb);

//cout << jsonText << endl;

auto sb1 = stack_command_builder_from_json(jsonText);

ASSERT_EQ(sb, sb1); // depends on StackCommandBuilder::operator==() being correct!
}

TEST(mvlc_readout_config, CrateConfigYaml)
{
CrateConfig cc;
Expand Down Expand Up @@ -64,14 +85,61 @@ TEST(mvlc_readout_config, CrateConfigYaml)

ASSERT_EQ(cc.stacks.size(), 1u);
ASSERT_EQ(cc.stacks.size(), cc.triggers.size());
cout << to_yaml(cc) << endl;
//cout << to_yaml(cc) << endl;
}

{
auto yString = to_yaml(cc);
auto cc2 = crate_config_from_yaml(yString);

cout << to_yaml(cc2) << endl;
//cout << to_yaml(cc2) << endl;

ASSERT_EQ(cc, cc2); // depends on CrateConfig::operator==() being correct!
}
}

TEST(mvlc_readout_config, CrateConfigJson)
{
CrateConfig cc;

{
cc.connectionType = ConnectionType::USB;
cc.usbIndex = 42;
cc.usbSerial = "1234";
cc.ethHost = "example.com";
cc.initRegisters.emplace_back(std::make_pair(0x1180, 500));

{
StackCommandBuilder sb("event0");
sb.beginGroup("module0");
sb.addVMEBlockRead(0x00000000u, vme_amods::MBLT64, (1u << 16)-1);
sb.beginGroup("module1");
sb.addVMEBlockRead(0x10000000u, vme_amods::MBLT64, (1u << 16)-1);
sb.beginGroup("module2");
sb.addVMEBlockReadSwapped(0x20000000u, vme_amods::MBLT64, (1u << 16)-1);
sb.beginGroup("reset");
sb.addVMEWrite(0xbb006070u, 1, vme_amods::A32, VMEDataWidth::D32);

cc.stacks.emplace_back(sb);
}

{
stacks::Trigger trigger{};
trigger.type = stacks::TriggerType::IRQNoIACK;
trigger.subtype = stacks::TriggerSubtype::IRQ1;
cc.triggers.push_back(trigger.value);
}

ASSERT_EQ(cc.stacks.size(), 1u);
ASSERT_EQ(cc.stacks.size(), cc.triggers.size());
//cout << to_json(cc) << endl;
}

{
auto yString = to_json(cc);
auto cc2 = crate_config_from_json(yString);

//cout << to_json(cc2) << endl;

ASSERT_EQ(cc, cc2); // depends on CrateConfig::operator==() being correct!
}
Expand Down
Loading

0 comments on commit ad82298

Please sign in to comment.