From 94c20b297823128e57ab4e73ed6b103b2ce47ca0 Mon Sep 17 00:00:00 2001 From: Nav Date: Tue, 27 Feb 2024 21:01:36 +0000 Subject: [PATCH] Updated TDF peripheral, register group instance and signal extraction to align with new TDF format --- src/Targets/TargetDescription/Peripheral.hpp | 63 ++++++++++++ .../RegisterGroupInstance.hpp | 34 +++++++ src/Targets/TargetDescription/Signal.hpp | 24 ++++- .../TargetDescriptionFile.cpp | 96 +++++++++++++++++-- .../TargetDescriptionFile.hpp | 24 +++-- 5 files changed, 221 insertions(+), 20 deletions(-) create mode 100644 src/Targets/TargetDescription/Peripheral.hpp create mode 100644 src/Targets/TargetDescription/RegisterGroupInstance.hpp diff --git a/src/Targets/TargetDescription/Peripheral.hpp b/src/Targets/TargetDescription/Peripheral.hpp new file mode 100644 index 00000000..9a4098d3 --- /dev/null +++ b/src/Targets/TargetDescription/Peripheral.hpp @@ -0,0 +1,63 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include "RegisterGroupInstance.hpp" +#include "Signal.hpp" + +#include "Exceptions/InvalidTargetDescriptionDataException.hpp" + +namespace Targets::TargetDescription +{ + struct Peripheral + { + std::string key; + std::string name; + std::string moduleKey; + + std::map> registerGroupInstancesByKey; + std::vector sigs; + + Peripheral( + const std::string& key, + const std::string& name, + const std::string& moduleKey, + const std::map>& registerGroupInstancesByKey, + const std::vector& sigs + ) + : key(key) + , name(name) + , moduleKey(moduleKey) + , registerGroupInstancesByKey(registerGroupInstancesByKey) + , sigs(sigs) + {} + + std::optional> tryGetRegisterGroupInstance( + std::string_view key + ) const { + const auto instanceIt = this->registerGroupInstancesByKey.find(key); + + if (instanceIt == this->registerGroupInstancesByKey.end()) { + return std::nullopt; + } + + return std::cref(instanceIt->second); + } + + const RegisterGroupInstance& getRegisterGroupInstance(std::string_view key) const { + const auto instance = this->tryGetRegisterGroupInstance(key); + if (!instance.has_value()) { + throw Exceptions::InvalidTargetDescriptionDataException( + "Failed to get register group instance \"" + std::string(key) + + "\" from peripheral in TDF - register group instance not found" + ); + } + + return instance->get(); + } + }; +} diff --git a/src/Targets/TargetDescription/RegisterGroupInstance.hpp b/src/Targets/TargetDescription/RegisterGroupInstance.hpp new file mode 100644 index 00000000..88468040 --- /dev/null +++ b/src/Targets/TargetDescription/RegisterGroupInstance.hpp @@ -0,0 +1,34 @@ +#pragma once + +#include +#include +#include + +namespace Targets::TargetDescription +{ + struct RegisterGroupInstance + { + std::string key; + std::string name; + std::string registerGroupKey; + std::string addressSpaceKey; + std::uint32_t offset; + std::optional description; + + RegisterGroupInstance( + const std::string& key, + const std::string& name, + const std::string& registerGroupKey, + const std::string& addressSpaceKey, + std::uint32_t offset, + const std::optional& description + ) + : key(key) + , name(name) + , registerGroupKey(registerGroupKey) + , addressSpaceKey(addressSpaceKey) + , offset(offset) + , description(description) + {} + }; +} diff --git a/src/Targets/TargetDescription/Signal.hpp b/src/Targets/TargetDescription/Signal.hpp index 350c3caa..ae68a636 100644 --- a/src/Targets/TargetDescription/Signal.hpp +++ b/src/Targets/TargetDescription/Signal.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -7,9 +8,24 @@ namespace Targets::TargetDescription { struct Signal { - std::string padName; - std::string function; - std::optional index; - std::string group; + std::string padId; + std::optional index; + std::optional function; + std::optional group; + std::optional field; + + Signal( + const std::string& padId, + const std::optional& index, + const std::optional& function, + const std::optional& group, + const std::optional& field + ) + : padId(padId) + , index(index) + , function(function) + , group(group) + , field(field) + {} }; } diff --git a/src/Targets/TargetDescription/TargetDescriptionFile.cpp b/src/Targets/TargetDescription/TargetDescriptionFile.cpp index b0f89cf4..807a080d 100644 --- a/src/Targets/TargetDescription/TargetDescriptionFile.cpp +++ b/src/Targets/TargetDescription/TargetDescriptionFile.cpp @@ -141,6 +141,27 @@ namespace Targets::TargetDescription return module->get(); } + std::optional> TargetDescriptionFile::tryGetPeripheral( + std::string_view key + ) const { + const auto peripheralIt = this->peripheralsByKey.find(key); + return peripheralIt != this->peripheralsByKey.end() + ? std::optional(std::cref(peripheralIt->second)) + : std::nullopt; + } + + const Peripheral& TargetDescriptionFile::getPeripheral(std::string_view key) const { + const auto peripheral = this->tryGetPeripheral(key); + + if (!peripheral.has_value()) { + throw InvalidTargetDescriptionDataException( + "Failed to get peripheral \"" + std::string(key) + "\" from TDF - peripheral not found" + ); + } + + return peripheral->get(); + } + void TargetDescriptionFile::init(const std::string& xmlFilePath) { auto file = QFile(QString::fromStdString(xmlFilePath)); if (!file.exists()) { @@ -219,7 +240,17 @@ namespace Targets::TargetDescription ); } - this->loadPeripheralModules(document); + for ( + auto element = deviceElement.firstChildElement("peripherals").firstChildElement("peripheral"); + !element.isNull(); + element = element.nextSiblingElement("peripheral") + ) { + auto peripheral = TargetDescriptionFile::peripheralFromXml(element); + this->peripheralsByKey.insert( + std::pair(peripheral.key, std::move(peripheral)) + ); + } + this->loadVariants(document); this->loadPinouts(document); } @@ -507,6 +538,62 @@ namespace Targets::TargetDescription ); } + Peripheral TargetDescriptionFile::peripheralFromXml(const QDomElement& xmlElement) { + const auto offset = TargetDescriptionFile::tryGetAttribute(xmlElement, "offset"); + + auto output = Peripheral( + TargetDescriptionFile::getAttribute(xmlElement, "key"), + TargetDescriptionFile::getAttribute(xmlElement, "name"), + TargetDescriptionFile::getAttribute(xmlElement, "module-key"), + {}, + {} + ); + + for ( + auto element = xmlElement.firstChildElement("register-group-instance"); + !element.isNull(); + element = element.nextSiblingElement("register-group-instance") + ) { + auto registerGroupInstance = TargetDescriptionFile::registerGroupInstanceFromXml(element); + output.registerGroupInstancesByKey.insert( + std::pair(registerGroupInstance.key, std::move(registerGroupInstance)) + ); + } + + for ( + auto element = xmlElement.firstChildElement("signals").firstChildElement("signal"); + !element.isNull(); + element = element.nextSiblingElement("signal") + ) { + output.sigs.emplace_back(TargetDescriptionFile::signalFromXml(element)); + } + + return output; + } + + RegisterGroupInstance TargetDescriptionFile::registerGroupInstanceFromXml(const QDomElement& xmlElement) { + return RegisterGroupInstance( + TargetDescriptionFile::getAttribute(xmlElement, "key"), + TargetDescriptionFile::getAttribute(xmlElement, "name"), + TargetDescriptionFile::getAttribute(xmlElement, "register-group-key"), + TargetDescriptionFile::getAttribute(xmlElement, "address-space-key"), + StringService::toUint32(TargetDescriptionFile::getAttribute(xmlElement, "offset")), + TargetDescriptionFile::tryGetAttribute(xmlElement, "description") + ); + } + + Signal TargetDescriptionFile::signalFromXml(const QDomElement& xmlElement) { + const auto index = TargetDescriptionFile::tryGetAttribute(xmlElement, "index"); + + return Signal( + TargetDescriptionFile::getAttribute(xmlElement, "pad-id"), + index.has_value() ? std::optional(StringService::toUint64(*index)) : std::nullopt, + TargetDescriptionFile::tryGetAttribute(xmlElement, "function"), + TargetDescriptionFile::tryGetAttribute(xmlElement, "group"), + TargetDescriptionFile::tryGetAttribute(xmlElement, "field") + ); + } + const std::string& TargetDescriptionFile::deviceAttribute(const std::string& attributeName) const { const auto attributeIt = this->deviceAttributesByName.find(attributeName); @@ -517,13 +604,6 @@ namespace Targets::TargetDescription return attributeIt->second; } - void TargetDescriptionFile::loadPeripheralModules(const QDomDocument& document) { - const auto deviceElement = document.elementsByTagName("device").item(0).toElement(); - - auto moduleNodes = deviceElement.elementsByTagName("peripherals").item(0).toElement() - .elementsByTagName("module"); - } - void TargetDescriptionFile::loadVariants(const QDomDocument& document) { const auto deviceElement = document.elementsByTagName("device").item(0).toElement(); diff --git a/src/Targets/TargetDescription/TargetDescriptionFile.hpp b/src/Targets/TargetDescription/TargetDescriptionFile.hpp index ed293b1f..736ae1bd 100644 --- a/src/Targets/TargetDescription/TargetDescriptionFile.hpp +++ b/src/Targets/TargetDescription/TargetDescriptionFile.hpp @@ -14,10 +14,15 @@ #include "MemorySegment.hpp" #include "MemorySegmentSection.hpp" #include "PhysicalInterface.hpp" -#include "RegisterGroup.hpp" #include "Module.hpp" -#include "Variant.hpp" +#include "RegisterGroup.hpp" +#include "Register.hpp" +#include "RegisterGroupReference.hpp" +#include "Peripheral.hpp" +#include "RegisterGroupInstance.hpp" +#include "Signal.hpp" #include "Pinout.hpp" +#include "Variant.hpp" #include "src/Targets/TargetFamily.hpp" #include "src/Targets/TargetPhysicalInterface.hpp" @@ -107,13 +112,18 @@ namespace Targets::TargetDescription ) const; [[nodiscard]] const Module& getModule(std::string_view key) const; + [[nodiscard]] std::optional> tryGetPeripheral( + std::string_view key + ) const; + [[nodiscard]] const Peripheral& getPeripheral(std::string_view key) const; + protected: std::map deviceAttributesByName; std::map> propertyGroupsByKey; std::map> addressSpacesByKey; std::vector physicalInterfaces; std::map> modulesByKey; - std::map peripheralModulesMappedByName; + std::map> peripheralsByKey; std::map> peripheralRegisterGroupsMappedByModuleRegisterGroupName; std::vector variants; std::map pinoutsMappedByName; @@ -144,6 +154,9 @@ namespace Targets::TargetDescription static RegisterGroupReference registerGroupReferenceFromXml(const QDomElement& xmlElement); static Register registerFromXml(const QDomElement& xmlElement); static BitField bitFieldFromXml(const QDomElement& xmlElement); + static Peripheral peripheralFromXml(const QDomElement& xmlElement); + static RegisterGroupInstance registerGroupInstanceFromXml(const QDomElement& xmlElement); + static Signal signalFromXml(const QDomElement& xmlElement); /** * Fetches a device attribute value by name. Throws an exception if the attribute is not found. @@ -153,11 +166,6 @@ namespace Targets::TargetDescription */ const std::string& deviceAttribute(const std::string& attributeName) const; - /** - * Extracts all peripheral modules and loads them into this->peripheralModulesMappedByName. - */ - void loadPeripheralModules(const QDomDocument& document); - /** * Extracts all variants and loads them into this->variants. */