More TDF refactoring
Moved address space, module, property group, variant, pinout and peripheral module extraction to TDF initialisation. Also some other bits of tidying.
This commit is contained in:
@@ -231,7 +231,7 @@ void Avr8::loadTargetVariants() {
|
|||||||
|
|
||||||
auto targetVariant = TargetVariant();
|
auto targetVariant = TargetVariant();
|
||||||
targetVariant.id = static_cast<int>(this->targetVariantsById.size());
|
targetVariant.id = static_cast<int>(this->targetVariantsById.size());
|
||||||
targetVariant.name = tdVariant.orderCode;
|
targetVariant.name = tdVariant.name;
|
||||||
targetVariant.packageName = tdVariant.package;
|
targetVariant.packageName = tdVariant.package;
|
||||||
|
|
||||||
if (tdVariant.package.find("QFP") == 0 || tdVariant.package.find("TQFP") == 0) {
|
if (tdVariant.package.find("QFP") == 0 || tdVariant.package.find("TQFP") == 0) {
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ QJsonObject TargetDescriptionFile::getTargetDescriptionMapping() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TargetSignature TargetDescriptionFile::getTargetSignature() const {
|
TargetSignature TargetDescriptionFile::getTargetSignature() const {
|
||||||
auto propertyGroups = this->getPropertyGroupsMappedByName();
|
auto& propertyGroups = this->propertyGroupsMappedByName;
|
||||||
auto signaturePropertyGroupIt = propertyGroups.find("signatures");
|
auto signaturePropertyGroupIt = propertyGroups.find("signatures");
|
||||||
|
|
||||||
if (signaturePropertyGroupIt == propertyGroups.end()) {
|
if (signaturePropertyGroupIt == propertyGroups.end()) {
|
||||||
@@ -154,7 +154,7 @@ Family TargetDescriptionFile::getFamily() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::optional<MemorySegment> TargetDescriptionFile::getFlashMemorySegment() const {
|
std::optional<MemorySegment> TargetDescriptionFile::getFlashMemorySegment() const {
|
||||||
auto addressMapping = this->getAddressSpacesMappedById();
|
auto& addressMapping = this->addressSpacesMappedById;
|
||||||
auto programAddressSpaceIt = addressMapping.find("prog");
|
auto programAddressSpaceIt = addressMapping.find("prog");
|
||||||
|
|
||||||
// Flash memory attributes are typically found in memory segments within the program address space.
|
// Flash memory attributes are typically found in memory segments within the program address space.
|
||||||
@@ -183,7 +183,7 @@ std::optional<MemorySegment> TargetDescriptionFile::getFlashMemorySegment() cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::optional<MemorySegment> TargetDescriptionFile::getRamMemorySegment() const {
|
std::optional<MemorySegment> TargetDescriptionFile::getRamMemorySegment() const {
|
||||||
auto addressMapping = this->getAddressSpacesMappedById();
|
auto& addressMapping = this->addressSpacesMappedById;
|
||||||
|
|
||||||
// Internal RAM ®ister attributes are usually found in the data address space
|
// Internal RAM ®ister attributes are usually found in the data address space
|
||||||
auto dataAddressSpaceIt = addressMapping.find("data");
|
auto dataAddressSpaceIt = addressMapping.find("data");
|
||||||
@@ -206,7 +206,7 @@ std::optional<MemorySegment> TargetDescriptionFile::getRamMemorySegment() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::optional<MemorySegment> TargetDescriptionFile::getRegisterMemorySegment() const {
|
std::optional<MemorySegment> TargetDescriptionFile::getRegisterMemorySegment() const {
|
||||||
auto addressMapping = this->getAddressSpacesMappedById();
|
auto& addressMapping = this->addressSpacesMappedById;
|
||||||
|
|
||||||
// Internal RAM ®ister attributes are usually found in the data address space
|
// Internal RAM ®ister attributes are usually found in the data address space
|
||||||
auto dataAddressSpaceIt = addressMapping.find("data");
|
auto dataAddressSpaceIt = addressMapping.find("data");
|
||||||
@@ -229,7 +229,7 @@ std::optional<MemorySegment> TargetDescriptionFile::getRegisterMemorySegment() c
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::optional<MemorySegment> TargetDescriptionFile::getEepromMemorySegment() const {
|
std::optional<MemorySegment> TargetDescriptionFile::getEepromMemorySegment() const {
|
||||||
auto addressMapping = this->getAddressSpacesMappedById();
|
auto& addressMapping = this->addressSpacesMappedById;
|
||||||
|
|
||||||
if (addressMapping.contains("eeprom")) {
|
if (addressMapping.contains("eeprom")) {
|
||||||
auto& eepromAddressSpace = addressMapping.at("eeprom");
|
auto& eepromAddressSpace = addressMapping.at("eeprom");
|
||||||
@@ -254,7 +254,7 @@ std::optional<MemorySegment> TargetDescriptionFile::getEepromMemorySegment() con
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::optional<MemorySegment> TargetDescriptionFile::getFirstBootSectionMemorySegment() const {
|
std::optional<MemorySegment> TargetDescriptionFile::getFirstBootSectionMemorySegment() const {
|
||||||
auto addressMapping = this->getAddressSpacesMappedById();
|
auto& addressMapping = this->addressSpacesMappedById;
|
||||||
auto programAddressSpaceIt = addressMapping.find("prog");
|
auto programAddressSpaceIt = addressMapping.find("prog");
|
||||||
|
|
||||||
if (programAddressSpaceIt != addressMapping.end()) {
|
if (programAddressSpaceIt != addressMapping.end()) {
|
||||||
@@ -277,7 +277,7 @@ std::optional<MemorySegment> TargetDescriptionFile::getFirstBootSectionMemorySeg
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::optional<RegisterGroup> TargetDescriptionFile::getCpuRegisterGroup() const {
|
std::optional<RegisterGroup> TargetDescriptionFile::getCpuRegisterGroup() const {
|
||||||
auto& modulesByName = this->getModulesMappedByName();
|
auto& modulesByName = this->modulesMappedByName;
|
||||||
|
|
||||||
if (modulesByName.find("cpu") != modulesByName.end()) {
|
if (modulesByName.find("cpu") != modulesByName.end()) {
|
||||||
auto cpuModule = modulesByName.find("cpu")->second;
|
auto cpuModule = modulesByName.find("cpu")->second;
|
||||||
@@ -292,7 +292,7 @@ std::optional<RegisterGroup> TargetDescriptionFile::getCpuRegisterGroup() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::optional<RegisterGroup> TargetDescriptionFile::getBootLoadRegisterGroup() const {
|
std::optional<RegisterGroup> TargetDescriptionFile::getBootLoadRegisterGroup() const {
|
||||||
auto& modulesByName = this->getModulesMappedByName();
|
auto& modulesByName = this->modulesMappedByName;
|
||||||
|
|
||||||
if (modulesByName.contains("boot_load")) {
|
if (modulesByName.contains("boot_load")) {
|
||||||
auto& bootLoadModule = modulesByName.at("boot_load");
|
auto& bootLoadModule = modulesByName.at("boot_load");
|
||||||
@@ -307,7 +307,7 @@ std::optional<RegisterGroup> TargetDescriptionFile::getBootLoadRegisterGroup() c
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::optional<RegisterGroup> TargetDescriptionFile::getEepromRegisterGroup() const {
|
std::optional<RegisterGroup> TargetDescriptionFile::getEepromRegisterGroup() const {
|
||||||
auto& modulesByName = this->getModulesMappedByName();
|
auto& modulesByName = this->modulesMappedByName;
|
||||||
|
|
||||||
if (modulesByName.find("eeprom") != modulesByName.end()) {
|
if (modulesByName.find("eeprom") != modulesByName.end()) {
|
||||||
auto eepromModule = modulesByName.find("eeprom")->second;
|
auto eepromModule = modulesByName.find("eeprom")->second;
|
||||||
|
|||||||
@@ -31,6 +31,13 @@ void TargetDescriptionFile::init(const QDomDocument& xml) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this->deviceElement = device;
|
this->deviceElement = device;
|
||||||
|
|
||||||
|
this->loadAddressSpaces();
|
||||||
|
this->loadPropertyGroups();
|
||||||
|
this->loadModules();
|
||||||
|
this->loadPeripheralModules();
|
||||||
|
this->loadVariants();
|
||||||
|
this->loadPinouts();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string TargetDescriptionFile::getTargetName() const {
|
std::string TargetDescriptionFile::getTargetName() const {
|
||||||
@@ -208,147 +215,7 @@ Register TargetDescriptionFile::generateRegisterFromXml(const QDomElement& xmlEl
|
|||||||
return reg;
|
return reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<std::string, PropertyGroup>& TargetDescriptionFile::getPropertyGroupsMappedByName() const {
|
void TargetDescriptionFile::loadAddressSpaces() {
|
||||||
if (!this->cachedPropertyGroupMapping.has_value()) {
|
|
||||||
if (!this->deviceElement.isElement()) {
|
|
||||||
throw TargetDescriptionParsingFailureException("Device element not found.");
|
|
||||||
}
|
|
||||||
|
|
||||||
std::map<std::string, PropertyGroup> output;
|
|
||||||
auto propertyGroupNodes = this->deviceElement.elementsByTagName("property-groups").item(0).toElement()
|
|
||||||
.elementsByTagName("property-group");
|
|
||||||
|
|
||||||
for (int propertyGroupIndex = 0; propertyGroupIndex < propertyGroupNodes.count(); propertyGroupIndex++) {
|
|
||||||
auto propertyGroupElement = propertyGroupNodes.item(propertyGroupIndex).toElement();
|
|
||||||
auto propertyGroupName = propertyGroupElement.attributes().namedItem("name").nodeValue().toLower().toStdString();
|
|
||||||
PropertyGroup propertyGroup;
|
|
||||||
propertyGroup.name = propertyGroupName;
|
|
||||||
|
|
||||||
auto propertyNodes = propertyGroupElement.elementsByTagName("property");
|
|
||||||
for (int propertyIndex = 0; propertyIndex < propertyNodes.count(); propertyIndex++) {
|
|
||||||
auto propertyElement = propertyNodes.item(propertyIndex).toElement();
|
|
||||||
auto propertyName = propertyElement.attributes().namedItem("name").nodeValue();
|
|
||||||
|
|
||||||
Property property;
|
|
||||||
property.name = propertyName.toStdString();
|
|
||||||
property.value = propertyElement.attributes().namedItem("value").nodeValue();
|
|
||||||
|
|
||||||
propertyGroup.propertiesMappedByName.insert(std::pair(propertyName.toLower().toStdString(), property));
|
|
||||||
}
|
|
||||||
|
|
||||||
output.insert(std::pair(propertyGroup.name, propertyGroup));
|
|
||||||
}
|
|
||||||
|
|
||||||
this->cachedPropertyGroupMapping.emplace(output);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this->cachedPropertyGroupMapping.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::map<std::string, Module>& TargetDescriptionFile::getModulesMappedByName() const {
|
|
||||||
if (!this->cachedModuleByNameMapping.has_value()) {
|
|
||||||
std::map<std::string, Module> output;
|
|
||||||
auto moduleNodes = this->xml.elementsByTagName("modules").item(0).toElement()
|
|
||||||
.elementsByTagName("module");
|
|
||||||
|
|
||||||
for (int moduleIndex = 0; moduleIndex < moduleNodes.count(); moduleIndex++) {
|
|
||||||
auto moduleElement = moduleNodes.item(moduleIndex).toElement();
|
|
||||||
auto moduleName = moduleElement.attributes().namedItem("name").nodeValue().toLower().toStdString();
|
|
||||||
Module module;
|
|
||||||
module.name = moduleName;
|
|
||||||
|
|
||||||
auto registerGroupNodes = moduleElement.elementsByTagName("register-group");
|
|
||||||
for (int registerGroupIndex = 0; registerGroupIndex < registerGroupNodes.count(); registerGroupIndex++) {
|
|
||||||
auto registerGroup = TargetDescriptionFile::generateRegisterGroupFromXml(
|
|
||||||
registerGroupNodes.item(registerGroupIndex).toElement()
|
|
||||||
);
|
|
||||||
|
|
||||||
module.registerGroupsMappedByName.insert(std::pair(registerGroup.name, registerGroup));
|
|
||||||
}
|
|
||||||
|
|
||||||
output.insert(std::pair(module.name, module));
|
|
||||||
}
|
|
||||||
|
|
||||||
this->cachedModuleByNameMapping.emplace(output);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this->cachedModuleByNameMapping.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::map<std::string, Module>& TargetDescriptionFile::getPeripheralModulesMappedByName() const {
|
|
||||||
if (!this->cachedPeripheralModuleByNameMapping.has_value()) {
|
|
||||||
std::map<std::string, Module> output;
|
|
||||||
auto moduleNodes = this->deviceElement.elementsByTagName("peripherals").item(0).toElement()
|
|
||||||
.elementsByTagName("module");
|
|
||||||
|
|
||||||
for (int moduleIndex = 0; moduleIndex < moduleNodes.count(); moduleIndex++) {
|
|
||||||
auto moduleElement = moduleNodes.item(moduleIndex).toElement();
|
|
||||||
auto moduleName = moduleElement.attributes().namedItem("name").nodeValue().toLower().toStdString();
|
|
||||||
Module module;
|
|
||||||
module.name = moduleName;
|
|
||||||
|
|
||||||
auto registerGroupNodes = moduleElement.elementsByTagName("register-group");
|
|
||||||
for (int registerGroupIndex = 0; registerGroupIndex < registerGroupNodes.count(); registerGroupIndex++) {
|
|
||||||
auto registerGroup = TargetDescriptionFile::generateRegisterGroupFromXml(
|
|
||||||
registerGroupNodes.item(registerGroupIndex).toElement()
|
|
||||||
);
|
|
||||||
|
|
||||||
module.registerGroupsMappedByName.insert(std::pair(registerGroup.name, registerGroup));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto instanceNodes = moduleElement.elementsByTagName("instance");
|
|
||||||
for (int instanceIndex = 0; instanceIndex < instanceNodes.count(); instanceIndex++) {
|
|
||||||
auto instanceXml = instanceNodes.item(instanceIndex).toElement();
|
|
||||||
auto instance = ModuleInstance();
|
|
||||||
instance.name = instanceXml.attribute("name").toLower().toStdString();
|
|
||||||
|
|
||||||
auto registerGroupNodes = instanceXml.elementsByTagName("register-group");
|
|
||||||
for (int registerGroupIndex = 0; registerGroupIndex < registerGroupNodes.count(); registerGroupIndex++) {
|
|
||||||
auto registerGroup = TargetDescriptionFile::generateRegisterGroupFromXml(
|
|
||||||
registerGroupNodes.item(registerGroupIndex).toElement()
|
|
||||||
);
|
|
||||||
|
|
||||||
instance.registerGroupsMappedByName.insert(std::pair(registerGroup.name, registerGroup));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto signalNodes = instanceXml.elementsByTagName("signals").item(0).toElement()
|
|
||||||
.elementsByTagName("signal");
|
|
||||||
for (int signalIndex = 0; signalIndex < signalNodes.count(); signalIndex++) {
|
|
||||||
auto signalXml = signalNodes.item(signalIndex).toElement();
|
|
||||||
auto signal = Signal();
|
|
||||||
|
|
||||||
if (!signalXml.hasAttribute("pad")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
signal.padName = signalXml.attribute("pad").toLower().toStdString();
|
|
||||||
signal.function = signalXml.attribute("function").toStdString();
|
|
||||||
signal.group = signalXml.attribute("group").toStdString();
|
|
||||||
auto indexAttribute = signalXml.attribute("index");
|
|
||||||
bool indexValid = false;
|
|
||||||
auto indexValue = indexAttribute.toInt(&indexValid, 10);
|
|
||||||
|
|
||||||
if (!indexAttribute.isEmpty() && indexValid) {
|
|
||||||
signal.index = indexValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
instance.instanceSignals.emplace_back(signal);
|
|
||||||
}
|
|
||||||
|
|
||||||
module.instancesMappedByName.insert(std::pair(instance.name, instance));
|
|
||||||
}
|
|
||||||
|
|
||||||
output.insert(std::pair(module.name, module));
|
|
||||||
}
|
|
||||||
|
|
||||||
this->cachedPeripheralModuleByNameMapping.emplace(output);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this->cachedPeripheralModuleByNameMapping.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::map<std::string, AddressSpace> TargetDescriptionFile::getAddressSpacesMappedById() const {
|
|
||||||
std::map<std::string, AddressSpace> output;
|
|
||||||
|
|
||||||
auto addressSpaceNodes = this->deviceElement.elementsByTagName("address-spaces").item(0).toElement()
|
auto addressSpaceNodes = this->deviceElement.elementsByTagName("address-spaces").item(0).toElement()
|
||||||
.elementsByTagName("address-space");
|
.elementsByTagName("address-space");
|
||||||
@@ -358,19 +225,133 @@ std::map<std::string, AddressSpace> TargetDescriptionFile::getAddressSpacesMappe
|
|||||||
auto addressSpace = TargetDescriptionFile::generateAddressSpaceFromXml(
|
auto addressSpace = TargetDescriptionFile::generateAddressSpaceFromXml(
|
||||||
addressSpaceNodes.item(addressSpaceIndex).toElement()
|
addressSpaceNodes.item(addressSpaceIndex).toElement()
|
||||||
);
|
);
|
||||||
output.insert(std::pair(addressSpace.id, addressSpace));
|
this->addressSpacesMappedById.insert(std::pair(addressSpace.id, addressSpace));
|
||||||
|
|
||||||
} catch (const Exception& exception) {
|
} catch (const Exception& exception) {
|
||||||
Logger::debug("Failed to extract address space from target description element - " + exception.getMessage());
|
Logger::debug("Failed to extract address space from target description element - " + exception.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Variant> TargetDescriptionFile::getVariants() const {
|
void TargetDescriptionFile::loadPropertyGroups() {
|
||||||
std::vector<Variant> output;
|
if (!this->deviceElement.isElement()) {
|
||||||
|
throw TargetDescriptionParsingFailureException("Device element not found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto propertyGroupNodes = this->deviceElement.elementsByTagName("property-groups").item(0).toElement()
|
||||||
|
.elementsByTagName("property-group");
|
||||||
|
|
||||||
|
for (int propertyGroupIndex = 0; propertyGroupIndex < propertyGroupNodes.count(); propertyGroupIndex++) {
|
||||||
|
auto propertyGroupElement = propertyGroupNodes.item(propertyGroupIndex).toElement();
|
||||||
|
auto propertyGroupName = propertyGroupElement.attributes().namedItem("name").nodeValue().toLower().toStdString();
|
||||||
|
PropertyGroup propertyGroup;
|
||||||
|
propertyGroup.name = propertyGroupName;
|
||||||
|
|
||||||
|
auto propertyNodes = propertyGroupElement.elementsByTagName("property");
|
||||||
|
for (int propertyIndex = 0; propertyIndex < propertyNodes.count(); propertyIndex++) {
|
||||||
|
auto propertyElement = propertyNodes.item(propertyIndex).toElement();
|
||||||
|
auto propertyName = propertyElement.attributes().namedItem("name").nodeValue();
|
||||||
|
|
||||||
|
Property property;
|
||||||
|
property.name = propertyName.toStdString();
|
||||||
|
property.value = propertyElement.attributes().namedItem("value").nodeValue();
|
||||||
|
|
||||||
|
propertyGroup.propertiesMappedByName.insert(std::pair(propertyName.toLower().toStdString(), property));
|
||||||
|
}
|
||||||
|
|
||||||
|
this->propertyGroupsMappedByName.insert(std::pair(propertyGroup.name, propertyGroup));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TargetDescriptionFile::loadModules() {
|
||||||
|
auto moduleNodes = this->xml.elementsByTagName("modules").item(0).toElement()
|
||||||
|
.elementsByTagName("module");
|
||||||
|
|
||||||
|
for (int moduleIndex = 0; moduleIndex < moduleNodes.count(); moduleIndex++) {
|
||||||
|
auto moduleElement = moduleNodes.item(moduleIndex).toElement();
|
||||||
|
auto moduleName = moduleElement.attributes().namedItem("name").nodeValue().toLower().toStdString();
|
||||||
|
Module module;
|
||||||
|
module.name = moduleName;
|
||||||
|
|
||||||
|
auto registerGroupNodes = moduleElement.elementsByTagName("register-group");
|
||||||
|
for (int registerGroupIndex = 0; registerGroupIndex < registerGroupNodes.count(); registerGroupIndex++) {
|
||||||
|
auto registerGroup = TargetDescriptionFile::generateRegisterGroupFromXml(
|
||||||
|
registerGroupNodes.item(registerGroupIndex).toElement()
|
||||||
|
);
|
||||||
|
|
||||||
|
module.registerGroupsMappedByName.insert(std::pair(registerGroup.name, registerGroup));
|
||||||
|
}
|
||||||
|
|
||||||
|
this->modulesMappedByName.insert(std::pair(module.name, module));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TargetDescriptionFile::loadPeripheralModules() {
|
||||||
|
auto moduleNodes = this->deviceElement.elementsByTagName("peripherals").item(0).toElement()
|
||||||
|
.elementsByTagName("module");
|
||||||
|
|
||||||
|
for (int moduleIndex = 0; moduleIndex < moduleNodes.count(); moduleIndex++) {
|
||||||
|
auto moduleElement = moduleNodes.item(moduleIndex).toElement();
|
||||||
|
auto moduleName = moduleElement.attributes().namedItem("name").nodeValue().toLower().toStdString();
|
||||||
|
Module module;
|
||||||
|
module.name = moduleName;
|
||||||
|
|
||||||
|
auto registerGroupNodes = moduleElement.elementsByTagName("register-group");
|
||||||
|
for (int registerGroupIndex = 0; registerGroupIndex < registerGroupNodes.count(); registerGroupIndex++) {
|
||||||
|
auto registerGroup = TargetDescriptionFile::generateRegisterGroupFromXml(
|
||||||
|
registerGroupNodes.item(registerGroupIndex).toElement()
|
||||||
|
);
|
||||||
|
|
||||||
|
module.registerGroupsMappedByName.insert(std::pair(registerGroup.name, registerGroup));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto instanceNodes = moduleElement.elementsByTagName("instance");
|
||||||
|
for (int instanceIndex = 0; instanceIndex < instanceNodes.count(); instanceIndex++) {
|
||||||
|
auto instanceXml = instanceNodes.item(instanceIndex).toElement();
|
||||||
|
auto instance = ModuleInstance();
|
||||||
|
instance.name = instanceXml.attribute("name").toLower().toStdString();
|
||||||
|
|
||||||
|
auto registerGroupNodes = instanceXml.elementsByTagName("register-group");
|
||||||
|
for (int registerGroupIndex = 0; registerGroupIndex < registerGroupNodes.count(); registerGroupIndex++) {
|
||||||
|
auto registerGroup = TargetDescriptionFile::generateRegisterGroupFromXml(
|
||||||
|
registerGroupNodes.item(registerGroupIndex).toElement()
|
||||||
|
);
|
||||||
|
|
||||||
|
instance.registerGroupsMappedByName.insert(std::pair(registerGroup.name, registerGroup));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto signalNodes = instanceXml.elementsByTagName("signals").item(0).toElement()
|
||||||
|
.elementsByTagName("signal");
|
||||||
|
for (int signalIndex = 0; signalIndex < signalNodes.count(); signalIndex++) {
|
||||||
|
auto signalXml = signalNodes.item(signalIndex).toElement();
|
||||||
|
auto signal = Signal();
|
||||||
|
|
||||||
|
if (!signalXml.hasAttribute("pad")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
signal.padName = signalXml.attribute("pad").toLower().toStdString();
|
||||||
|
signal.function = signalXml.attribute("function").toStdString();
|
||||||
|
signal.group = signalXml.attribute("group").toStdString();
|
||||||
|
auto indexAttribute = signalXml.attribute("index");
|
||||||
|
bool indexValid = false;
|
||||||
|
auto indexValue = indexAttribute.toInt(&indexValid, 10);
|
||||||
|
|
||||||
|
if (!indexAttribute.isEmpty() && indexValid) {
|
||||||
|
signal.index = indexValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
instance.instanceSignals.emplace_back(signal);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.instancesMappedByName.insert(std::pair(instance.name, instance));
|
||||||
|
}
|
||||||
|
|
||||||
|
this->peripheralModulesMappedByName.insert(std::pair(module.name, module));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TargetDescriptionFile::loadVariants() {
|
||||||
auto variantNodes = this->xml.elementsByTagName("variants").item(0).toElement()
|
auto variantNodes = this->xml.elementsByTagName("variants").item(0).toElement()
|
||||||
.elementsByTagName("variant");
|
.elementsByTagName("variant");
|
||||||
|
|
||||||
@@ -391,7 +372,7 @@ std::vector<Variant> TargetDescriptionFile::getVariants() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto variant = Variant();
|
auto variant = Variant();
|
||||||
variant.orderCode = variantXml.attribute("ordercode").toStdString();
|
variant.name = variantXml.attribute("ordercode").toStdString();
|
||||||
variant.pinoutName = variantXml.attribute("pinout").toLower().toStdString();
|
variant.pinoutName = variantXml.attribute("pinout").toLower().toStdString();
|
||||||
variant.package = variantXml.attribute("package").toUpper().toStdString();
|
variant.package = variantXml.attribute("package").toUpper().toStdString();
|
||||||
|
|
||||||
@@ -399,67 +380,59 @@ std::vector<Variant> TargetDescriptionFile::getVariants() const {
|
|||||||
variant.disabled = (variantXml.attribute("disabled") == "1");
|
variant.disabled = (variantXml.attribute("disabled") == "1");
|
||||||
}
|
}
|
||||||
|
|
||||||
output.push_back(variant);
|
this->variants.push_back(variant);
|
||||||
|
|
||||||
} catch (const Exception& exception) {
|
} catch (const Exception& exception) {
|
||||||
Logger::debug("Failed to extract variant from target description element - " + exception.getMessage());
|
Logger::debug("Failed to extract variant from target description element - " + exception.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<std::string, Pinout>& TargetDescriptionFile::getPinoutsMappedByName() const {
|
void TargetDescriptionFile::loadPinouts() {
|
||||||
if (!this->cachedPinoutByNameMapping.has_value()) {
|
auto pinoutNodes = this->xml.elementsByTagName("pinouts").item(0).toElement()
|
||||||
this->cachedPinoutByNameMapping = std::map<std::string, Pinout>();
|
.elementsByTagName("pinout");
|
||||||
|
|
||||||
auto pinoutNodes = this->xml.elementsByTagName("pinouts").item(0).toElement()
|
for (int pinoutIndex = 0; pinoutIndex < pinoutNodes.count(); pinoutIndex++) {
|
||||||
.elementsByTagName("pinout");
|
try {
|
||||||
|
auto pinoutXml = pinoutNodes.item(pinoutIndex).toElement();
|
||||||
|
|
||||||
for (int pinoutIndex = 0; pinoutIndex < pinoutNodes.count(); pinoutIndex++) {
|
if (!pinoutXml.hasAttribute("name")) {
|
||||||
try {
|
throw Exception("Missing name attribute");
|
||||||
auto pinoutXml = pinoutNodes.item(pinoutIndex).toElement();
|
|
||||||
|
|
||||||
if (!pinoutXml.hasAttribute("name")) {
|
|
||||||
throw Exception("Missing name attribute");
|
|
||||||
}
|
|
||||||
|
|
||||||
auto pinout = Pinout();
|
|
||||||
pinout.name = pinoutXml.attribute("name").toLower().toStdString();
|
|
||||||
|
|
||||||
auto pinNodes = pinoutXml.elementsByTagName("pin");
|
|
||||||
|
|
||||||
for (int pinIndex = 0; pinIndex < pinNodes.count(); pinIndex++) {
|
|
||||||
auto pinXml = pinNodes.item(pinIndex).toElement();
|
|
||||||
|
|
||||||
if (!pinXml.hasAttribute("position")) {
|
|
||||||
throw Exception("Missing position attribute on pin element " + std::to_string(pinIndex));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pinXml.hasAttribute("pad")) {
|
|
||||||
throw Exception("Missing pad attribute on pin element " + std::to_string(pinIndex));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto pin = Pin();
|
|
||||||
bool positionConversionSucceeded = true;
|
|
||||||
pin.position = pinXml.attribute("position").toInt(&positionConversionSucceeded, 10);
|
|
||||||
pin.pad = pinXml.attribute("pad").toLower().toStdString();
|
|
||||||
|
|
||||||
if (!positionConversionSucceeded) {
|
|
||||||
throw Exception("Failed to convert position attribute value to integer on pin element "
|
|
||||||
+ std::to_string(pinIndex));
|
|
||||||
}
|
|
||||||
|
|
||||||
pinout.pins.push_back(pin);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->cachedPinoutByNameMapping->insert(std::pair(pinout.name, pinout));
|
|
||||||
|
|
||||||
} catch (const Exception& exception) {
|
|
||||||
Logger::debug("Failed to extract pinout from target description element - " + exception.getMessage());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto pinout = Pinout();
|
||||||
|
pinout.name = pinoutXml.attribute("name").toLower().toStdString();
|
||||||
|
|
||||||
|
auto pinNodes = pinoutXml.elementsByTagName("pin");
|
||||||
|
|
||||||
|
for (int pinIndex = 0; pinIndex < pinNodes.count(); pinIndex++) {
|
||||||
|
auto pinXml = pinNodes.item(pinIndex).toElement();
|
||||||
|
|
||||||
|
if (!pinXml.hasAttribute("position")) {
|
||||||
|
throw Exception("Missing position attribute on pin element " + std::to_string(pinIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pinXml.hasAttribute("pad")) {
|
||||||
|
throw Exception("Missing pad attribute on pin element " + std::to_string(pinIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pin = Pin();
|
||||||
|
bool positionConversionSucceeded = true;
|
||||||
|
pin.position = pinXml.attribute("position").toInt(&positionConversionSucceeded, 10);
|
||||||
|
pin.pad = pinXml.attribute("pad").toLower().toStdString();
|
||||||
|
|
||||||
|
if (!positionConversionSucceeded) {
|
||||||
|
throw Exception("Failed to convert position attribute value to integer on pin element "
|
||||||
|
+ std::to_string(pinIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
pinout.pins.push_back(pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->pinoutsMappedByName.insert(std::pair(pinout.name, pinout));
|
||||||
|
|
||||||
|
} catch (const Exception& exception) {
|
||||||
|
Logger::debug("Failed to extract pinout from target description element - " + exception.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this->cachedPinoutByNameMapping.value();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,15 +36,18 @@ namespace Bloom::Targets::TargetDescription
|
|||||||
QDomDocument xml;
|
QDomDocument xml;
|
||||||
QDomElement deviceElement;
|
QDomElement deviceElement;
|
||||||
|
|
||||||
|
std::map<std::string, AddressSpace> addressSpacesMappedById;
|
||||||
|
std::map<std::string, PropertyGroup> propertyGroupsMappedByName;
|
||||||
|
std::map<std::string, Module> modulesMappedByName;
|
||||||
|
std::map<std::string, Module> peripheralModulesMappedByName;
|
||||||
|
std::vector<Variant> variants;
|
||||||
|
std::map<std::string, Pinout> pinoutsMappedByName;
|
||||||
|
|
||||||
|
|
||||||
void init(const QDomDocument& xml);
|
void init(const QDomDocument& xml);
|
||||||
void init(const QString& xmlFilePath);
|
void init(const QString& xmlFilePath);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable std::optional<std::map<std::string, PropertyGroup>> cachedPropertyGroupMapping;
|
|
||||||
mutable std::optional<std::map<std::string, Module>> cachedModuleByNameMapping;
|
|
||||||
mutable std::optional<std::map<std::string, Module>> cachedPeripheralModuleByNameMapping;
|
|
||||||
mutable std::optional<std::map<std::string, Pinout>> cachedPinoutByNameMapping;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an AddressSpace object from an XML element.
|
* Constructs an AddressSpace object from an XML element.
|
||||||
*
|
*
|
||||||
@@ -77,6 +80,36 @@ namespace Bloom::Targets::TargetDescription
|
|||||||
*/
|
*/
|
||||||
static Register generateRegisterFromXml(const QDomElement& xmlElement);
|
static Register generateRegisterFromXml(const QDomElement& xmlElement);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts all address spaces and loads them into this->addressSpacesMappedById.
|
||||||
|
*/
|
||||||
|
void loadAddressSpaces();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts all property groups and loads them into this->propertyGroupsMappedByName.
|
||||||
|
*/
|
||||||
|
void loadPropertyGroups();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts all modules and loads them into this->modulesMappedByName.
|
||||||
|
*/
|
||||||
|
void loadModules();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts all peripheral modules and loads them into this->peripheralModulesMappedByName.
|
||||||
|
*/
|
||||||
|
void loadPeripheralModules();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts all variants and loads them into this->variants.
|
||||||
|
*/
|
||||||
|
void loadVariants();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts all pinouts and loads them into this->pinoutsMappedByName.
|
||||||
|
*/
|
||||||
|
void loadPinouts();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TargetDescriptionFile() = default;
|
TargetDescriptionFile() = default;
|
||||||
|
|
||||||
@@ -104,51 +137,51 @@ namespace Bloom::Targets::TargetDescription
|
|||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
std::string getTargetName() const;
|
[[nodiscard]] std::string getTargetName() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts all address spaces for the target.
|
* Returns a mapping of all property groups, with the property group name being the key.
|
||||||
*
|
|
||||||
* Will return a mapping of the extracted address spaces, mapped by id.
|
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
std::map<std::string, AddressSpace> getAddressSpacesMappedById() const;
|
[[nodiscard]] const std::map<std::string, PropertyGroup>& getPropertyGroupsMappedByName() const {
|
||||||
|
return this->propertyGroupsMappedByName;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts all property groups and returns a mapping of them, with the property group name being the key.
|
* Returns a mapping of all modules, with the module name being the key.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
const std::map<std::string, PropertyGroup>& getPropertyGroupsMappedByName() const;
|
[[nodiscard]] const std::map<std::string, Module>& getModulesMappedByName() const {
|
||||||
|
return this->modulesMappedByName;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts all modules and returns a mapping of them, with the module name being the key.
|
* Returns a mapping of all peripheral modules, with the peripheral module name being the key.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
const std::map<std::string, Module>& getModulesMappedByName() const;
|
[[nodiscard]] const std::map<std::string, Module>& getPeripheralModulesMappedByName() const {
|
||||||
|
return this->peripheralModulesMappedByName;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts all peripheral modules and returns a mapping of this, with the peripheral module name being
|
* Returns all variants found in the TDF.
|
||||||
* the key.
|
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
const std::map<std::string, Module>& getPeripheralModulesMappedByName() const;
|
[[nodiscard]] const std::vector<Variant>& getVariants() const {
|
||||||
|
return this->variants;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts all variants.
|
* Returns a mapping of pinouts, with the pinout name being the key.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
std::vector<Variant> getVariants() const;
|
[[nodiscard]] const std::map<std::string, Pinout>& getPinoutsMappedByName() const {
|
||||||
|
return this->pinoutsMappedByName;
|
||||||
/**
|
}
|
||||||
* Extracts all pinouts and returns a mapping of them, with the pinout name being the key.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
const std::map<std::string, Pinout>& getPinoutsMappedByName() const;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace Bloom::Targets::TargetDescription
|
|||||||
{
|
{
|
||||||
struct Variant
|
struct Variant
|
||||||
{
|
{
|
||||||
std::string orderCode;
|
std::string name;
|
||||||
std::string pinoutName;
|
std::string pinoutName;
|
||||||
std::string package;
|
std::string package;
|
||||||
bool disabled = false;
|
bool disabled = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user