From 38260dc358aa3d635f8faa9933bd32031a45b543 Mon Sep 17 00:00:00 2001 From: Nav Date: Fri, 4 Mar 2022 23:43:26 +0000 Subject: [PATCH] DWEN & SPIEN fuse bit descriptor extraction from AVR8 TDFs --- .../TargetDescriptionFile.cpp | 47 +++++++++++++++++++ .../TargetDescriptionFile.hpp | 21 +++++++++ 2 files changed, 68 insertions(+) diff --git a/src/Targets/Microchip/AVR/AVR8/TargetDescription/TargetDescriptionFile.cpp b/src/Targets/Microchip/AVR/AVR8/TargetDescription/TargetDescriptionFile.cpp index f12bdaff..19a9208a 100644 --- a/src/Targets/Microchip/AVR/AVR8/TargetDescription/TargetDescriptionFile.cpp +++ b/src/Targets/Microchip/AVR/AVR8/TargetDescription/TargetDescriptionFile.cpp @@ -376,6 +376,14 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit::TargetDescription return output; } + std::optional TargetDescriptionFile::getDwenFuseBitDescriptor() const { + return this->getFuseBitDescriptorByName("dwen"); + } + + std::optional TargetDescriptionFile::getSpienFuseBitDescriptor() const { + return this->getFuseBitDescriptorByName("spien"); + } + void TargetDescriptionFile::loadDebugPhysicalInterfaces() { auto interfaceNamesToInterfaces = std::map({ {"updi", PhysicalInterface::UPDI}, @@ -619,6 +627,45 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit::TargetDescription } } + std::optional TargetDescriptionFile::getFuseBitDescriptorByName( + const std::string& fuseBitName + ) const { + if (!this->modulesMappedByName.contains("fuse")) { + return std::nullopt; + } + + const auto& fuseModule = this->modulesMappedByName.at("fuse"); + + if (!fuseModule.registerGroupsMappedByName.contains("fuse")) { + return std::nullopt; + } + + const auto& fuseRegisterGroup = fuseModule.registerGroupsMappedByName.at("fuse"); + + static const auto fuseTypesByName = std::map( + { + {"low", FuseType::LOW}, + {"high", FuseType::HIGH}, + {"extended", FuseType::EXTENDED}, + } + ); + + for (const auto&[fuseTypeName, fuse] : fuseRegisterGroup.registersMappedByName) { + if (!fuseTypesByName.contains(fuseTypeName)) { + // Unknown fuse type name + continue; + } + + if (fuse.bitFieldsMappedByName.contains(fuseBitName)) { + return FuseBitDescriptor( + fuseTypesByName.at(fuseTypeName), + fuse.bitFieldsMappedByName.at(fuseBitName).mask + ); + } + } + + return std::nullopt; + } std::optional TargetDescriptionFile::getFlashMemorySegment() const { auto& addressMapping = this->addressSpacesMappedById; auto programAddressSpaceIt = addressMapping.find("prog"); diff --git a/src/Targets/Microchip/AVR/AVR8/TargetDescription/TargetDescriptionFile.hpp b/src/Targets/Microchip/AVR/AVR8/TargetDescription/TargetDescriptionFile.hpp index c65098ae..49268144 100644 --- a/src/Targets/Microchip/AVR/AVR8/TargetDescription/TargetDescriptionFile.hpp +++ b/src/Targets/Microchip/AVR/AVR8/TargetDescription/TargetDescriptionFile.hpp @@ -9,6 +9,7 @@ #include "src/Targets/Microchip/AVR/TargetSignature.hpp" #include "src/Targets/Microchip/AVR/IspParameters.hpp" +#include "src/Targets/Microchip/AVR/Fuse.hpp" #include "src/Targets/Microchip/AVR/AVR8/Family.hpp" #include "src/Targets/Microchip/AVR/AVR8/PhysicalInterface.hpp" @@ -82,6 +83,24 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit::TargetDescription */ [[nodiscard]] IspParameters getIspParameters() const; + /** + * Constructs a FuseBitDescriptor for the debugWire enable (DWEN) fuse bit, with information extracted from + * the TDF. + * + * @return + * std::nullopt if the DWEN bit field could not be found in the TDF. + */ + [[nodiscard]] std::optional getDwenFuseBitDescriptor() const; + + /** + * Constructs a FuseBitDescriptor for the SPI enable (SPIEN) fuse bit, with information extracted from + * the TDF. + * + * @return + * std::nullopt if the SPIEN bit field could not be found in the TDF. + */ + [[nodiscard]] std::optional getSpienFuseBitDescriptor() const; + /** * Returns a set of all supported physical interfaces for debugging. * @@ -169,6 +188,8 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit::TargetDescription */ void loadTargetRegisterDescriptors(); + [[nodiscard]] std::optional getFuseBitDescriptorByName(const std::string& fuseBitName) const; + [[nodiscard]] std::optional getFlashMemorySegment() const; [[nodiscard]] std::optional getRamMemorySegment() const; [[nodiscard]] std::optional getIoMemorySegment() const;