#pragma once #include #include #include "AddressSpace.hpp" #include "MemorySegment.hpp" #include "PropertyGroup.hpp" #include "RegisterGroup.hpp" #include "Module.hpp" #include "Variant.hpp" #include "Pinout.hpp" #include "src/Targets/Microchip/AVR/TargetSignature.hpp" #include "src/Targets/Microchip/AVR/AVR8/Family.hpp" namespace Bloom::Targets::Microchip::Avr::Avr8Bit::PartDescription { /** * An AVR8 part description file is an XML file that describes a particular AVR8 target. * All supported AVR8 targets come with a part description file. * * Part description files are part of the Bloom codebase. * For AVR8 part description files, see directory "src/Targets/Microchip/AVR/PartDescriptionFiles/AVR8". * * During the build process, all part description files are copied to the distribution directory, ready * to be shipped with the Bloom binary. Alongside these files is a JSON file, containing a mapping of AVR8 target * signatures to part description file paths. Bloom uses this mapping to find a particular part description * file, given a target signature. See directory "build/resources/TargetPartDescriptions". * The copying of the part description files, and 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. * * All processing of AVR8 part description files is done in this class. */ class PartDescriptionFile { private: QDomDocument xml; QDomElement deviceElement; mutable std::optional> cachedPropertyGroupMapping; mutable std::optional> cachedModuleByNameMapping; mutable std::optional> cachedPeripheralModuleByNameMapping; mutable std::optional> cachedPinoutByNameMapping; /**` * AVR8 part 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}, }; }; void init(const QDomDocument& xml); void init(const QString& xmlFilePath); /** * Constructs an AddressSpace object from an XML element (in the form of a QDomElement), taken from * an AVR part description file. * * @param xmlElement * @return */ AddressSpace generateAddressSpaceFromXml(const QDomElement& xmlElement) const; /** * Constructs a MemorySegment from an XML element (in the form of a QDomElement) taken from * an AVR part description file. * * @param xmlElement * @return */ MemorySegment generateMemorySegmentFromXml(const QDomElement& xmlElement) const; RegisterGroup generateRegisterGroupFromXml(const QDomElement& xmlElement) const; Register generateRegisterFromXml(const QDomElement& xmlElement) const; public: /** * Will construct a PartDescription instance from the XML of a part description file, the path to which * is given via xmlFilePath. * * @param xmlFilePath */ PartDescriptionFile(const QString& xmlFilePath) { this->init(xmlFilePath); } /** * Will construct a PartDescription instance from pre-loaded XML. * * @param xml */ PartDescriptionFile(const QDomDocument& xml) { this->init(xml); } /** * Will resolve the part description file using the part description JSON mapping and a given target signature. * * @param targetSignatureHex * @param targetName */ PartDescriptionFile(const std::string& targetSignatureHex, std::optional targetName); /** * Loads the AVR8 target description JSON mapping file. * * @return */ static QJsonObject getPartDescriptionMapping(); std::string getTargetName() const; /** * Extracts the AVR8 target signature from the part description XML. * * @return */ TargetSignature getTargetSignature() const; /** * Extracts all address spaces for the AVR8 target, from the part description XML. * * Will return a mapping of the extracted address spaces, mapped by id. * * @return */ std::map getAddressSpacesMappedById() const; /** * Extracts the AVR8 target family from the part description XML. * * @return */ Family getFamily() const; const std::map& getPropertyGroupsMappedByName() const; const std::map& getModulesMappedByName() const; const std::map& getPeripheralModulesMappedByName() const; std::optional getFlashMemorySegment() const; std::optional getRamMemorySegment() const; std::optional getRegisterMemorySegment() const; std::optional getEepromMemorySegment() const; std::optional getFirstBootSectionMemorySegment() const; std::optional getCpuRegisterGroup() const; std::optional getBootLoadRegisterGroup() const; std::optional getEepromRegisterGroup() const; std::optional getStatusRegister() const; std::optional getStackPointerRegister() const; std::optional getStackPointerHighRegister() const; std::optional getStackPointerLowRegister() const; std::optional getOscillatorCalibrationRegister() const; std::optional getSpmcsRegister() const; std::optional getSpmcRegister() const; std::optional getEepromAddressRegister() const; std::optional getEepromDataRegister() const; std::optional getEepromControlRegister() const; std::vector getVariants() const; const std::map& getPinoutsMappedByName() const; }; }