#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"; }