aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitmodules3
-rw-r--r--svd2funreg/Makefile2
-rw-r--r--svd2funreg/main.cpp81
m---------svd2funreg/pugixml0
4 files changed, 86 insertions, 0 deletions
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..72f2b95
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "svd2funreg/pugixml"]
+ path = svd2funreg/pugixml
+ url = https://github.com/zeux/pugixml
diff --git a/svd2funreg/Makefile b/svd2funreg/Makefile
new file mode 100644
index 0000000..743d59a
--- /dev/null
+++ b/svd2funreg/Makefile
@@ -0,0 +1,2 @@
+all:
+ g++ -o main main.cpp pugixml/src/pugixml.cpp -I pugixml/src
diff --git a/svd2funreg/main.cpp b/svd2funreg/main.cpp
new file mode 100644
index 0000000..d19d54d
--- /dev/null
+++ b/svd2funreg/main.cpp
@@ -0,0 +1,81 @@
+#include "pugixml.hpp"
+
+#include <cstdint>
+#include <cstdlib>
+#include <iostream>
+#include <string>
+
+static void parse_peripheral(const pugi::xml_node& node);
+static void parse_register(uint32_t base_address, const pugi::xml_node& node);
+static void parse_field(const char *reg, const pugi::xml_node& node);
+
+int main(int argc, char *argv[])
+{
+ if (argc < 2)
+ return -1;
+
+ pugi::xml_document doc;
+ pugi::xml_parse_result result = doc.load_file(argv[1]);
+ if (!result)
+ return -1;
+
+ std::cout << std::hex;
+ std::cout << "namespace " << doc.child("device").child_value("name")
+ << " {\n";
+
+ for (auto node : doc.child("device")
+ .child("peripherals")
+ .children("peripheral"))
+ {
+ parse_peripheral(node);
+ }
+
+ std::cout << "}\n";
+}
+
+void parse_peripheral(const pugi::xml_node& node)
+{
+ const auto base = std::strtol(node.child_value("baseAddress"), nullptr, 0);
+
+ std::cout << " namespace " << node.child_value("name") << " {\n";
+
+ for (auto n : node.child("registers").children("register"))
+ parse_register(base, n);
+
+ std::cout << " }\n";
+}
+
+void parse_register(uint32_t base_address, const pugi::xml_node& node)
+{
+ const auto offs = std::strtol(node.child_value("addressOffset"), nullptr, 0);
+ const auto size = std::strtol(node.child_value("size"), nullptr, 0);
+ const auto name = node.child_value("name");
+
+ std::cout << " struct " << name << " : public fr::MemRegister<";
+ switch (size) {
+ case 8: std::cout << "uint8_t, "; break;
+ case 16: std::cout << "uint16_t, "; break;
+ case 32:
+ default: std::cout << "uint32_t, "; break;
+ }
+ std::cout << "0x" << base_address + offs << "> {\n";
+
+ for (auto n : node.child("fields").children("field"))
+ parse_field(name, n);
+
+ std::cout << " };\n";
+}
+
+void parse_field(const char *reg, const pugi::xml_node& node)
+{
+ const auto offs = std::strtol(node.child_value("bitOffset"), nullptr, 0);
+ const auto width = std::strtol(node.child_value("bitWidth"), nullptr, 0);
+ std::string name = node.child_value("name");
+
+ if (name == reg)
+ name += "_val";
+
+ std::cout << " using " << name << " = fr::RegisterMask<"
+ << reg << ", (0x" << (1 << width) - 1 << "u << 0x" << offs << "u)>;\n";
+}
+
diff --git a/svd2funreg/pugixml b/svd2funreg/pugixml
new file mode 160000
+Subproject a305d01bc8dd3f3708c4ee80be8c87dfb51e13a