#pragma once #include #include #include "src/Targets/TargetDescription/TargetDescriptionFile.hpp" #include "src/Targets/TargetVariant.hpp" #include "src/Targets/TargetRegisterDescriptor.hpp" #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/TargetParameters.hpp" #include "src/Targets/Microchip/AVR/AVR8/PadDescriptor.hpp" namespace Targets::Microchip::Avr::Avr8Bit { /** * Represents an AVR8 TDF. See the Targets::TargetDescription::TargetDescriptionFile close for more on TDFs. * * During the build process, we generate a JSON file containing a mapping of AVR8 target signatures to target * description file paths. Bloom uses this mapping to find a particular target description file, for AVR8 targets, * given a target signature. See directory "build/resources/TargetDescriptionFiles". * The generation of the JSON mapping, is done by a PHP script: * "build/scripts/CopyAvrPartFilesAndCreateMapping.php". This script is invoked via a custom command, at build time. * * For more information of TDFs, see src/Targets/TargetDescription/README.md */ class TargetDescriptionFile: public Targets::TargetDescription::TargetDescriptionFile { public: /** * Extends TDF initialisation to include the loading of physical interfaces for debugging AVR8 targets, among * other things. * * @param xml */ explicit TargetDescriptionFile(const std::string& xmlFilePath); /** * Extracts the AVR8 target signature from the TDF. * * @return */ [[nodiscard]] TargetSignature getTargetSignature() const; /** * Extracts the AVR8 target family from the TDF. * * @return */ [[nodiscard]] Family getAvrFamily() const; [[nodiscard]] const Targets::TargetDescription::AddressSpace& getProgramAddressSpace() const; [[nodiscard]] const Targets::TargetDescription::AddressSpace& getRamAddressSpace() const; [[nodiscard]] const Targets::TargetDescription::AddressSpace& getEepromAddressSpace() const; [[nodiscard]] const Targets::TargetDescription::AddressSpace& getIoAddressSpace() const; [[nodiscard]] const Targets::TargetDescription::AddressSpace& getSignatureAddressSpace() const; [[nodiscard]] const Targets::TargetDescription::AddressSpace& getFuseAddressSpace() const; [[nodiscard]] const Targets::TargetDescription::AddressSpace& getLockbitAddressSpace() const; [[nodiscard]] const Targets::TargetDescription::MemorySegment& getProgramMemorySegment() const; [[nodiscard]] const Targets::TargetDescription::MemorySegment& getRamMemorySegment() const; [[nodiscard]] const Targets::TargetDescription::MemorySegment& getEepromMemorySegment() const; [[nodiscard]] const Targets::TargetDescription::MemorySegment& getIoMemorySegment() const; [[nodiscard]] const Targets::TargetDescription::MemorySegment& getSignatureMemorySegment() const; [[nodiscard]] const Targets::TargetDescription::MemorySegment& getFuseMemorySegment() const; [[nodiscard]] const Targets::TargetDescription::MemorySegment& getLockbitMemorySegment() const; /** * Constructs an instance of TargetParameters, for the AVR8 target, with data from the TDF. * * @return */ [[nodiscard]] TargetParameters getTargetParameters() const; /** * Extracts the target's ISP parameters from the TDF. * * @return */ [[nodiscard]] IspParameters getIspParameters() const; /** * Extracts the target's fuse enable strategy. * * @return * std::nullopt if the TDF doesn't contain a fuse enable strategy. */ [[nodiscard]] std::optional getFuseEnableStrategy() 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 getDwenFuseBitsDescriptor() 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 getSpienFuseBitsDescriptor() const; /** * Constructs a FuseBitDescriptor for the OCD enable (OCDEN) fuse bit, with information extracted from * the TDF. * * @return * std::nullopt if the OCDEN bit field could not be found in the TDF. */ [[nodiscard]] std::optional getOcdenFuseBitsDescriptor() const; /** * Constructs a FuseBitDescriptor for the JTAG enable (JTAGEN) fuse bit, with information extracted from * the TDF. * * @return * std::nullopt if the JTAGEN bit field could not be found in the TDF. */ [[nodiscard]] std::optional getJtagenFuseBitsDescriptor() const; /** * Constructs a FuseBitDescriptor for the "Preserve EEPROM" (EESAVE) fuse bit, with information extracted from * the TDF. * * @return * std::nullopt if the EESAVE bit field could not be found in the TDF. */ [[nodiscard]] std::optional getEesaveFuseBitsDescriptor() const; /** * Returns a mapping of all pad descriptors extracted from TDF, mapped by name. * * @return */ [[nodiscard]] const auto& getPadDescriptorsMappedByName() const { return this->padDescriptorsByName; } /** * Returns a mapping of all target variants extracted from the TDF, mapped by ID. * * @return */ [[nodiscard]] const auto& getVariantsMappedById() const { return this->targetVariantsById; } /** * Returns a mapping of all target register descriptors extracted from the TDF, by ID. * * @return */ [[nodiscard]] const auto& getRegisterDescriptorsMappedById() const { return this->targetRegisterDescriptorsById; } private: /**` * AVR8 target description files include the target family name. This method returns a mapping of part * description family name strings to Family enum values. * * TODO: the difference in AVR8 family variations, like "tinyAVR" and "tinyAVR 2" may require attention. * * @return */ static inline auto getFamilyNameToEnumMapping() { // All keys should be lower-case. return std::map { {"megaavr", Family::MEGA}, {"avr mega", Family::MEGA}, {"avr xmega", Family::XMEGA}, {"avr tiny", Family::TINY}, {"tinyavr", Family::TINY}, {"tinyavr 2", Family::TINY}, {"avr da", Family::DA}, {"avr db", Family::DB}, {"avr dd", Family::DD}, {"avr ea", Family::EA}, }; }; std::string avrFamilyName; std::map padDescriptorsByName; std::map targetVariantsById; std::map targetRegisterDescriptorsById; /** * Populates this->supportedPhysicalInterfaces with physical interfaces defined in the TDF. */ void loadSupportedPhysicalInterfaces(); /** * Generates a collection of PadDescriptor objects from data in the TDF and populates this->padDescriptorsByName. */ void loadPadDescriptors(); /** * Loads all variants for the AVR8 target, from the TDF, and populates this->targetVariantsById. */ void loadTargetVariants(); /** * Loads all register descriptors from the TDF, and populates this->targetRegisterDescriptorsById. */ void loadTargetRegisterDescriptors(); /** * Gets the register address offset for a specific peripheral module. * * @param moduleName * @param instanceName * @param registerGroupName * @return */ Targets::TargetMemoryAddress getPeripheralModuleRegisterAddressOffset( const std::string& moduleName, const std::string& instanceName, const std::string& registerGroupName ) const; [[nodiscard]] std::optional getFuseBitsDescriptorByName( const std::string& fuseBitName ) const; [[nodiscard]] std::optional getProgramMemoryAddressSpace() const; [[nodiscard]] std::optional getFlashApplicationMemorySegment( const Targets::TargetDescription::AddressSpace& programAddressSpace ) const; [[nodiscard]] std::optional getRegisterMemorySegment() const; [[nodiscard]] std::optional getFirstBootSectionMemorySegment() const; [[nodiscard]] std::optional getLockbitsMemorySegment() const; [[nodiscard]] std::optional getCpuRegisterGroup() const; [[nodiscard]] std::optional getBootLoadRegisterGroup() const; [[nodiscard]] std::optional getEepromRegisterGroup() const; [[nodiscard]] std::optional getStatusRegister() const; [[nodiscard]] std::optional getStackPointerRegister() const; [[nodiscard]] std::optional getStackPointerHighRegister() const; [[nodiscard]] std::optional getStackPointerLowRegister() const; [[nodiscard]] std::optional getOscillatorCalibrationRegister() const; [[nodiscard]] std::optional getSpmcsRegister() const; [[nodiscard]] std::optional getSpmcRegister() const; [[nodiscard]] std::optional getEepromAddressRegister() const; [[nodiscard]] std::optional getEepromAddressLowRegister() const; [[nodiscard]] std::optional getEepromAddressHighRegister() const; [[nodiscard]] std::optional getEepromDataRegister() const; [[nodiscard]] std::optional getEepromControlRegister() const; /** * Loads target parameters that are specific to debugWire and mega JTAG sessions. * * @param targetParameters */ virtual void loadDebugWireAndJtagTargetParameters(TargetParameters& targetParameters) const; /** * Loads target parameters that are specific to PDI sessions. * * @param targetParameters */ virtual void loadPdiTargetParameters(TargetParameters& targetParameters) const; /** * Loads target parameters that are specific to UPDI sessions. * * @param targetParameters */ virtual void loadUpdiTargetParameters(TargetParameters& targetParameters) const; }; }