From 4acb48d15aac0549f9f7d11482e06e9119365a89 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Wed, 5 Feb 2025 10:29:10 -0500 Subject: [PATCH] add svd2funreg --- .gitmodules | 3 ++ svd2funreg/Makefile | 2 ++ svd2funreg/main.cpp | 81 +++++++++++++++++++++++++++++++++++++++++++++ svd2funreg/pugixml | 1 + 4 files changed, 87 insertions(+) create mode 100644 .gitmodules create mode 100644 svd2funreg/Makefile create mode 100644 svd2funreg/main.cpp create mode 160000 svd2funreg/pugixml 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 +#include +#include +#include + +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 index 0000000..a305d01 --- /dev/null +++ b/svd2funreg/pugixml @@ -0,0 +1 @@ +Subproject commit a305d01bc8dd3f3708c4ee80be8c87dfb51e13ad