2021-05-31 01:01:14 +01:00
|
|
|
#pragma once
|
|
|
|
|
|
2021-06-27 20:09:15 +01:00
|
|
|
#include <set>
|
2022-10-09 13:10:17 +01:00
|
|
|
#include <optional>
|
2021-06-27 20:09:15 +01:00
|
|
|
|
2021-05-31 01:01:14 +01:00
|
|
|
#include "src/Targets/TargetDescription/TargetDescriptionFile.hpp"
|
|
|
|
|
|
2022-03-02 22:42:55 +00:00
|
|
|
#include "src/Targets/TargetVariant.hpp"
|
|
|
|
|
#include "src/Targets/TargetRegister.hpp"
|
|
|
|
|
|
2021-05-31 01:01:14 +01:00
|
|
|
#include "src/Targets/Microchip/AVR/TargetSignature.hpp"
|
2022-03-02 22:42:28 +00:00
|
|
|
#include "src/Targets/Microchip/AVR/IspParameters.hpp"
|
2022-03-04 23:43:26 +00:00
|
|
|
#include "src/Targets/Microchip/AVR/Fuse.hpp"
|
2022-03-02 22:42:55 +00:00
|
|
|
|
2021-05-31 01:01:14 +01:00
|
|
|
#include "src/Targets/Microchip/AVR/AVR8/Family.hpp"
|
2021-07-06 20:07:41 +01:00
|
|
|
#include "src/Targets/Microchip/AVR/AVR8/TargetParameters.hpp"
|
|
|
|
|
#include "src/Targets/Microchip/AVR/AVR8/PadDescriptor.hpp"
|
2021-05-31 01:01:14 +01:00
|
|
|
|
2023-08-13 15:47:51 +01:00
|
|
|
namespace Targets::Microchip::Avr::Avr8Bit::TargetDescription
|
2021-05-31 01:01:14 +01:00
|
|
|
{
|
|
|
|
|
/**
|
|
|
|
|
* 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,
|
2021-06-03 00:49:08 +01:00
|
|
|
* given a target signature. See directory "build/resources/TargetDescriptionFiles".
|
2021-05-31 01:01:14 +01:00
|
|
|
* 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.
|
2021-06-20 17:41:47 +01:00
|
|
|
*
|
|
|
|
|
* For more information of TDFs, see src/Targets/TargetDescription/README.md
|
2021-05-31 01:01:14 +01:00
|
|
|
*/
|
|
|
|
|
class TargetDescriptionFile: public Targets::TargetDescription::TargetDescriptionFile
|
|
|
|
|
{
|
2021-10-06 21:12:31 +01:00
|
|
|
public:
|
|
|
|
|
/**
|
|
|
|
|
* Extends TDF initialisation to include the loading of physical interfaces for debugging AVR8 targets, among
|
|
|
|
|
* other things.
|
|
|
|
|
*
|
|
|
|
|
* @param xml
|
|
|
|
|
*/
|
2023-12-17 18:12:53 +00:00
|
|
|
explicit TargetDescriptionFile(const std::string& xmlFilePath);
|
2021-10-06 21:12:31 +01:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Extracts the AVR8 target signature from the TDF.
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] TargetSignature getTargetSignature() const;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Extracts the AVR8 target family from the TDF.
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
2023-12-13 00:50:10 +00:00
|
|
|
[[nodiscard]] Family getAvrFamily() const;
|
2021-10-06 21:12:31 +01:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Constructs an instance of TargetParameters, for the AVR8 target, with data from the TDF.
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] TargetParameters getTargetParameters() const;
|
|
|
|
|
|
2022-03-02 22:42:28 +00:00
|
|
|
/**
|
|
|
|
|
* Extracts the target's ISP parameters from the TDF.
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] IspParameters getIspParameters() const;
|
|
|
|
|
|
2023-05-26 22:36:43 +01:00
|
|
|
/**
|
|
|
|
|
* Extracts the target's fuse enable strategy.
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
* std::nullopt if the TDF doesn't contain a fuse enable strategy.
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] std::optional<FuseEnableStrategy> getFuseEnableStrategy() const;
|
|
|
|
|
|
2022-03-04 23:43:26 +00:00
|
|
|
/**
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
2022-03-05 14:08:27 +00:00
|
|
|
[[nodiscard]] std::optional<FuseBitsDescriptor> getDwenFuseBitsDescriptor() const;
|
2022-03-04 23:43:26 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
2022-03-05 14:08:27 +00:00
|
|
|
[[nodiscard]] std::optional<FuseBitsDescriptor> getSpienFuseBitsDescriptor() const;
|
2022-03-04 23:43:26 +00:00
|
|
|
|
2023-05-07 16:49:45 +01:00
|
|
|
/**
|
|
|
|
|
* 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<FuseBitsDescriptor> 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<FuseBitsDescriptor> getJtagenFuseBitsDescriptor() const;
|
|
|
|
|
|
2023-05-26 22:42:48 +01:00
|
|
|
/**
|
|
|
|
|
* 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<FuseBitsDescriptor> getEesaveFuseBitsDescriptor() const;
|
|
|
|
|
|
2021-10-06 21:12:31 +01:00
|
|
|
/**
|
|
|
|
|
* 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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2023-05-21 21:08:25 +01:00
|
|
|
* Returns a mapping of all target register descriptors extracted from the TDF, by ID.
|
2021-10-06 21:12:31 +01:00
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
2023-05-21 21:08:25 +01:00
|
|
|
[[nodiscard]] const auto& getRegisterDescriptorsMappedById() const {
|
|
|
|
|
return this->targetRegisterDescriptorsById;
|
2021-10-06 21:12:31 +01:00
|
|
|
}
|
|
|
|
|
|
2021-05-31 01:01:14 +01:00
|
|
|
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() {
|
2023-05-21 21:08:25 +01:00
|
|
|
// All keys should be lower-case.
|
2021-05-31 01:01:14 +01:00
|
|
|
return std::map<std::string, Family> {
|
|
|
|
|
{"megaavr", Family::MEGA},
|
|
|
|
|
{"avr mega", Family::MEGA},
|
|
|
|
|
{"avr xmega", Family::XMEGA},
|
|
|
|
|
{"avr tiny", Family::TINY},
|
|
|
|
|
{"tinyavr", Family::TINY},
|
|
|
|
|
{"tinyavr 2", Family::TINY},
|
2021-06-06 17:44:13 +01:00
|
|
|
{"avr da", Family::DA},
|
|
|
|
|
{"avr db", Family::DB},
|
|
|
|
|
{"avr dd", Family::DD},
|
2023-05-12 19:08:52 +01:00
|
|
|
{"avr ea", Family::EA},
|
2021-05-31 01:01:14 +01:00
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2023-12-13 00:50:10 +00:00
|
|
|
std::string avrFamilyName;
|
2021-06-27 20:09:15 +01:00
|
|
|
|
2021-07-06 20:07:41 +01:00
|
|
|
std::map<std::string, PadDescriptor> padDescriptorsByName;
|
|
|
|
|
std::map<int, TargetVariant> targetVariantsById;
|
|
|
|
|
|
2023-05-21 21:08:25 +01:00
|
|
|
std::map<TargetRegisterDescriptorId, TargetRegisterDescriptor> targetRegisterDescriptorsById;
|
2021-08-07 17:15:48 +01:00
|
|
|
|
2021-06-27 20:09:15 +01:00
|
|
|
/**
|
2022-08-04 21:06:13 +01:00
|
|
|
* Populates this->supportedPhysicalInterfaces with physical interfaces defined in the TDF.
|
2021-06-27 20:09:15 +01:00
|
|
|
*/
|
2022-08-04 21:06:13 +01:00
|
|
|
void loadSupportedPhysicalInterfaces();
|
2021-06-27 20:09:15 +01:00
|
|
|
|
2021-07-06 20:07:41 +01:00
|
|
|
/**
|
|
|
|
|
* 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();
|
|
|
|
|
|
2021-08-07 17:15:48 +01:00
|
|
|
/**
|
2023-05-21 21:08:25 +01:00
|
|
|
* Loads all register descriptors from the TDF, and populates this->targetRegisterDescriptorsById.
|
2021-08-07 17:15:48 +01:00
|
|
|
*/
|
|
|
|
|
void loadTargetRegisterDescriptors();
|
|
|
|
|
|
2023-05-27 13:41:02 +01:00
|
|
|
/**
|
|
|
|
|
* 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;
|
|
|
|
|
|
2022-03-05 14:08:27 +00:00
|
|
|
[[nodiscard]] std::optional<FuseBitsDescriptor> getFuseBitsDescriptorByName(
|
|
|
|
|
const std::string& fuseBitName
|
|
|
|
|
) const;
|
2022-03-04 23:43:26 +00:00
|
|
|
|
2022-06-03 11:53:03 +01:00
|
|
|
[[nodiscard]] std::optional<Targets::TargetDescription::AddressSpace> getProgramMemoryAddressSpace() const;
|
|
|
|
|
[[nodiscard]] std::optional<Targets::TargetDescription::MemorySegment> getFlashApplicationMemorySegment(
|
|
|
|
|
const Targets::TargetDescription::AddressSpace& programAddressSpace
|
|
|
|
|
) const;
|
2021-07-06 20:07:41 +01:00
|
|
|
[[nodiscard]] std::optional<Targets::TargetDescription::MemorySegment> getRamMemorySegment() const;
|
|
|
|
|
[[nodiscard]] std::optional<Targets::TargetDescription::MemorySegment> getIoMemorySegment() const;
|
|
|
|
|
[[nodiscard]] std::optional<Targets::TargetDescription::MemorySegment> getRegisterMemorySegment() const;
|
|
|
|
|
[[nodiscard]] std::optional<Targets::TargetDescription::MemorySegment> getEepromMemorySegment() const;
|
|
|
|
|
[[nodiscard]] std::optional<Targets::TargetDescription::MemorySegment> getFirstBootSectionMemorySegment() const;
|
|
|
|
|
[[nodiscard]] std::optional<Targets::TargetDescription::MemorySegment> getSignatureMemorySegment() const;
|
|
|
|
|
[[nodiscard]] std::optional<Targets::TargetDescription::MemorySegment> getFuseMemorySegment() const;
|
|
|
|
|
[[nodiscard]] std::optional<Targets::TargetDescription::MemorySegment> getLockbitsMemorySegment() const;
|
|
|
|
|
[[nodiscard]] std::optional<Targets::TargetDescription::RegisterGroup> getCpuRegisterGroup() const;
|
|
|
|
|
[[nodiscard]] std::optional<Targets::TargetDescription::RegisterGroup> getBootLoadRegisterGroup() const;
|
|
|
|
|
[[nodiscard]] std::optional<Targets::TargetDescription::RegisterGroup> getEepromRegisterGroup() const;
|
|
|
|
|
|
|
|
|
|
[[nodiscard]] std::optional<Targets::TargetDescription::Register> getStatusRegister() const;
|
|
|
|
|
[[nodiscard]] std::optional<Targets::TargetDescription::Register> getStackPointerRegister() const;
|
|
|
|
|
[[nodiscard]] std::optional<Targets::TargetDescription::Register> getStackPointerHighRegister() const;
|
|
|
|
|
[[nodiscard]] std::optional<Targets::TargetDescription::Register> getStackPointerLowRegister() const;
|
|
|
|
|
[[nodiscard]] std::optional<Targets::TargetDescription::Register> getOscillatorCalibrationRegister() const;
|
|
|
|
|
[[nodiscard]] std::optional<Targets::TargetDescription::Register> getSpmcsRegister() const;
|
|
|
|
|
[[nodiscard]] std::optional<Targets::TargetDescription::Register> getSpmcRegister() const;
|
|
|
|
|
[[nodiscard]] std::optional<Targets::TargetDescription::Register> getEepromAddressRegister() const;
|
|
|
|
|
[[nodiscard]] std::optional<Targets::TargetDescription::Register> getEepromAddressLowRegister() const;
|
|
|
|
|
[[nodiscard]] std::optional<Targets::TargetDescription::Register> getEepromAddressHighRegister() const;
|
|
|
|
|
[[nodiscard]] std::optional<Targets::TargetDescription::Register> getEepromDataRegister() const;
|
|
|
|
|
[[nodiscard]] std::optional<Targets::TargetDescription::Register> 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;
|
2021-05-31 01:01:14 +01:00
|
|
|
};
|
|
|
|
|
}
|