]> code.bitgloo.com Git - clyne/funreg.git/commitdiff
add svd2funreg
authorClyne Sullivan <clyne@bitgloo.com>
Wed, 5 Feb 2025 15:29:10 +0000 (10:29 -0500)
committerClyne Sullivan <clyne@bitgloo.com>
Wed, 5 Feb 2025 15:29:10 +0000 (10:29 -0500)
.gitmodules [new file with mode: 0644]
svd2funreg/Makefile [new file with mode: 0644]
svd2funreg/main.cpp [new file with mode: 0644]
svd2funreg/pugixml [new submodule]

diff --git a/.gitmodules b/.gitmodules
new file mode 100644 (file)
index 0000000..72f2b95
--- /dev/null
@@ -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 (file)
index 0000000..743d59a
--- /dev/null
@@ -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 (file)
index 0000000..d19d54d
--- /dev/null
@@ -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 (submodule)
index 0000000..a305d01
--- /dev/null
@@ -0,0 +1 @@
+Subproject commit a305d01bc8dd3f3708c4ee80be8c87dfb51e13ad