Created EdbgAvr8Session struct and moved EDBG target info to it
This commit is contained in:
@@ -24,6 +24,7 @@ target_sources(
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/Microchip/Protocols/EDBG/AVR/Parameters/AVR8Generic/UpdiParameters.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/Microchip/Protocols/EDBG/AVR/Parameters/AVR8Generic/UpdiParameters.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/Microchip/Protocols/EDBG/EdbgInterface.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/Microchip/Protocols/EDBG/EdbgInterface.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/Microchip/Protocols/EDBG/EdbgTargetPowerManagementInterface.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/Microchip/Protocols/EDBG/EdbgTargetPowerManagementInterface.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/Microchip/Protocols/EDBG/AVR/EdbgAvr8Session.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/Microchip/Protocols/EDBG/AVR/EdbgAvr8Interface.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/Microchip/Protocols/EDBG/AVR/EdbgAvr8Interface.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/Microchip/Protocols/EDBG/AVR/EdbgAvrIspInterface.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/Microchip/Protocols/EDBG/AVR/EdbgAvrIspInterface.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/Microchip/EdbgDevice.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/Microchip/EdbgDevice.cpp
|
||||||
|
|||||||
@@ -79,6 +79,8 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
using CommandFrames::Avr8Generic::EraseMemory;
|
using CommandFrames::Avr8Generic::EraseMemory;
|
||||||
using CommandFrames::Avr8Generic::DisableDebugWire;
|
using CommandFrames::Avr8Generic::DisableDebugWire;
|
||||||
|
|
||||||
|
using Targets::TargetAddressSpaceDescriptor;
|
||||||
|
using Targets::TargetMemorySegmentType;
|
||||||
using Targets::TargetState;
|
using Targets::TargetState;
|
||||||
using Targets::TargetPhysicalInterface;
|
using Targets::TargetPhysicalInterface;
|
||||||
using Targets::TargetMemoryType;
|
using Targets::TargetMemoryType;
|
||||||
@@ -90,38 +92,31 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
using Targets::TargetRegisterDescriptors;
|
using Targets::TargetRegisterDescriptors;
|
||||||
using Targets::TargetRegisterDescriptorId;
|
using Targets::TargetRegisterDescriptorId;
|
||||||
using Targets::TargetRegisterDescriptorIds;
|
using Targets::TargetRegisterDescriptorIds;
|
||||||
using Targets::TargetRegisterType;
|
|
||||||
using Targets::TargetRegisters;
|
using Targets::TargetRegisters;
|
||||||
|
|
||||||
EdbgAvr8Interface::EdbgAvr8Interface(
|
EdbgAvr8Interface::EdbgAvr8Interface(
|
||||||
EdbgInterface* edbgInterface,
|
EdbgInterface* edbgInterface,
|
||||||
const Targets::Microchip::Avr::Avr8Bit::Avr8TargetConfig& targetConfig,
|
const Targets::Microchip::Avr::Avr8Bit::TargetDescriptionFile& targetDescriptionFile,
|
||||||
Targets::Microchip::Avr::Avr8Bit::Family targetFamily,
|
const Targets::Microchip::Avr::Avr8Bit::Avr8TargetConfig& targetConfig
|
||||||
const Targets::Microchip::Avr::Avr8Bit::TargetParameters& targetParameters,
|
|
||||||
const Targets::TargetRegisterDescriptorMapping& targetRegisterDescriptorsById
|
|
||||||
)
|
)
|
||||||
: edbgInterface(edbgInterface)
|
: edbgInterface(edbgInterface)
|
||||||
, targetConfig(targetConfig)
|
, session(EdbgAvr8Session(targetDescriptionFile, targetConfig))
|
||||||
, family(targetFamily)
|
|
||||||
, configVariant(EdbgAvr8Interface::resolveConfigVariant(targetFamily, targetConfig.physicalInterface))
|
|
||||||
, targetParameters(targetParameters)
|
|
||||||
, targetRegisterDescriptorsById(targetRegisterDescriptorsById)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void EdbgAvr8Interface::init() {
|
void EdbgAvr8Interface::init() {
|
||||||
if (this->configVariant == Avr8ConfigVariant::XMEGA) {
|
if (this->session.configVariant == Avr8ConfigVariant::XMEGA) {
|
||||||
// Default PDI clock to 4MHz
|
// Default PDI clock to 4MHz
|
||||||
// TODO: Make this adjustable via a target config parameter
|
// TODO: Make this adjustable via a target config parameter
|
||||||
this->setParameter(Avr8EdbgParameters::PDI_CLOCK_SPEED, static_cast<std::uint16_t>(4000));
|
this->setParameter(Avr8EdbgParameters::PDI_CLOCK_SPEED, static_cast<std::uint16_t>(4000));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->configVariant == Avr8ConfigVariant::UPDI) {
|
if (this->session.configVariant == Avr8ConfigVariant::UPDI) {
|
||||||
// Default UPDI clock to 1.8MHz
|
// Default UPDI clock to 1.8MHz
|
||||||
this->setParameter(Avr8EdbgParameters::PDI_CLOCK_SPEED, static_cast<std::uint16_t>(1800));
|
this->setParameter(Avr8EdbgParameters::PDI_CLOCK_SPEED, static_cast<std::uint16_t>(1800));
|
||||||
this->setParameter(Avr8EdbgParameters::ENABLE_HIGH_VOLTAGE_UPDI, static_cast<std::uint8_t>(0));
|
this->setParameter(Avr8EdbgParameters::ENABLE_HIGH_VOLTAGE_UPDI, static_cast<std::uint8_t>(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->configVariant == Avr8ConfigVariant::MEGAJTAG) {
|
if (this->session.configVariant == Avr8ConfigVariant::MEGAJTAG) {
|
||||||
// Default clock value for mega debugging is 200KHz
|
// Default clock value for mega debugging is 200KHz
|
||||||
// TODO: Make this adjustable via a target config parameter
|
// TODO: Make this adjustable via a target config parameter
|
||||||
this->setParameter(Avr8EdbgParameters::MEGA_DEBUG_CLOCK, static_cast<std::uint16_t>(200));
|
this->setParameter(Avr8EdbgParameters::MEGA_DEBUG_CLOCK, static_cast<std::uint16_t>(200));
|
||||||
@@ -130,17 +125,17 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
|
|
||||||
this->setParameter(
|
this->setParameter(
|
||||||
Avr8EdbgParameters::CONFIG_VARIANT,
|
Avr8EdbgParameters::CONFIG_VARIANT,
|
||||||
static_cast<std::uint8_t>(this->configVariant)
|
static_cast<std::uint8_t>(this->session.configVariant)
|
||||||
);
|
);
|
||||||
|
|
||||||
this->setParameter(
|
this->setParameter(
|
||||||
Avr8EdbgParameters::CONFIG_FUNCTION,
|
Avr8EdbgParameters::CONFIG_FUNCTION,
|
||||||
static_cast<std::uint8_t>(this->configFunction)
|
static_cast<std::uint8_t>(Avr8ConfigFunction::DEBUGGING)
|
||||||
);
|
);
|
||||||
|
|
||||||
this->setParameter(
|
this->setParameter(
|
||||||
Avr8EdbgParameters::PHYSICAL_INTERFACE,
|
Avr8EdbgParameters::PHYSICAL_INTERFACE,
|
||||||
getPhysicalInterfaceToAvr8IdMapping().at(this->targetConfig.physicalInterface)
|
getPhysicalInterfaceToAvr8IdMapping().at(this->session.targetConfig.physicalInterface)
|
||||||
);
|
);
|
||||||
|
|
||||||
this->setTargetParameters();
|
this->setTargetParameters();
|
||||||
@@ -232,7 +227,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
|
|
||||||
} catch (const Avr8CommandFailure& activationException) {
|
} catch (const Avr8CommandFailure& activationException) {
|
||||||
if (
|
if (
|
||||||
this->targetConfig.physicalInterface == TargetPhysicalInterface::DEBUG_WIRE
|
this->session.targetConfig.physicalInterface == TargetPhysicalInterface::DEBUG_WIRE
|
||||||
&& (
|
&& (
|
||||||
activationException.code == Avr8CommandFailureCode::DEBUGWIRE_PHYSICAL_ERROR
|
activationException.code == Avr8CommandFailureCode::DEBUGWIRE_PHYSICAL_ERROR
|
||||||
|| activationException.code == Avr8CommandFailureCode::FAILED_TO_ENABLE_OCD
|
|| activationException.code == Avr8CommandFailureCode::FAILED_TO_ENABLE_OCD
|
||||||
@@ -257,8 +252,8 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
void EdbgAvr8Interface::deactivate() {
|
void EdbgAvr8Interface::deactivate() {
|
||||||
if (this->targetAttached) {
|
if (this->targetAttached) {
|
||||||
if (
|
if (
|
||||||
this->targetConfig.physicalInterface == TargetPhysicalInterface::DEBUG_WIRE
|
this->session.targetConfig.physicalInterface == TargetPhysicalInterface::DEBUG_WIRE
|
||||||
&& this->targetConfig.disableDebugWireOnDeactivate
|
&& this->session.targetConfig.disableDebugWireOnDeactivate
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
this->disableDebugWire();
|
this->disableDebugWire();
|
||||||
@@ -317,7 +312,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
}
|
}
|
||||||
|
|
||||||
TargetSignature EdbgAvr8Interface::getDeviceId() {
|
TargetSignature EdbgAvr8Interface::getDeviceId() {
|
||||||
if (this->configVariant == Avr8ConfigVariant::UPDI) {
|
if (this->session.configVariant == Avr8ConfigVariant::UPDI) {
|
||||||
/*
|
/*
|
||||||
* When using the UPDI physical interface, the 'Get device ID' command behaves in an odd manner, where it
|
* When using the UPDI physical interface, the 'Get device ID' command behaves in an odd manner, where it
|
||||||
* doesn't actually return the target signature, but instead a fixed four byte string reading:
|
* doesn't actually return the target signature, but instead a fixed four byte string reading:
|
||||||
@@ -331,7 +326,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
*/
|
*/
|
||||||
const auto signatureMemory = this->readMemory(
|
const auto signatureMemory = this->readMemory(
|
||||||
Avr8MemoryType::SRAM,
|
Avr8MemoryType::SRAM,
|
||||||
this->targetParameters.signatureSegmentStartAddress.value(),
|
this->session.signatureMemorySegment.startAddress,
|
||||||
3
|
3
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -339,7 +334,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
throw Exception("Failed to read AVR8 signature from target - unexpected response size");
|
throw Exception("Failed to read AVR8 signature from target - unexpected response size");
|
||||||
}
|
}
|
||||||
|
|
||||||
return TargetSignature(signatureMemory[0], signatureMemory[1], signatureMemory[2]);
|
return {signatureMemory[0], signatureMemory[1], signatureMemory[2]};
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto responseFrame = this->edbgInterface->sendAvrCommandFrameAndWaitForResponseFrame(
|
const auto responseFrame = this->edbgInterface->sendAvrCommandFrameAndWaitForResponseFrame(
|
||||||
@@ -350,7 +345,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
throw Avr8CommandFailure("AVR8 Get device ID command failed", responseFrame);
|
throw Avr8CommandFailure("AVR8 Get device ID command failed", responseFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
return responseFrame.extractSignature(this->targetConfig.physicalInterface);
|
return responseFrame.extractSignature(this->session.targetConfig.physicalInterface);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EdbgAvr8Interface::setSoftwareBreakpoint(TargetMemoryAddress address) {
|
void EdbgAvr8Interface::setSoftwareBreakpoint(TargetMemoryAddress address) {
|
||||||
@@ -518,7 +513,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
|
|
||||||
const auto memoryType = (registerType != TargetRegisterType::GENERAL_PURPOSE_REGISTER)
|
const auto memoryType = (registerType != TargetRegisterType::GENERAL_PURPOSE_REGISTER)
|
||||||
? Avr8MemoryType::SRAM
|
? Avr8MemoryType::SRAM
|
||||||
: (this->configVariant == Avr8ConfigVariant::XMEGA || this->configVariant == Avr8ConfigVariant::UPDI
|
: (this->session.configVariant == Avr8ConfigVariant::XMEGA || this->session.configVariant == Avr8ConfigVariant::UPDI
|
||||||
? Avr8MemoryType::REGISTER_FILE
|
? Avr8MemoryType::REGISTER_FILE
|
||||||
: Avr8MemoryType::SRAM);
|
: Avr8MemoryType::SRAM);
|
||||||
|
|
||||||
@@ -622,7 +617,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
auto memoryType = Avr8MemoryType::SRAM;
|
auto memoryType = Avr8MemoryType::SRAM;
|
||||||
if (
|
if (
|
||||||
registerDescriptor.type == TargetRegisterType::GENERAL_PURPOSE_REGISTER
|
registerDescriptor.type == TargetRegisterType::GENERAL_PURPOSE_REGISTER
|
||||||
&& (this->configVariant == Avr8ConfigVariant::XMEGA || this->configVariant == Avr8ConfigVariant::UPDI)
|
&& (this->session.configVariant == Avr8ConfigVariant::XMEGA || this->session.configVariant == Avr8ConfigVariant::UPDI)
|
||||||
) {
|
) {
|
||||||
memoryType = Avr8MemoryType::REGISTER_FILE;
|
memoryType = Avr8MemoryType::REGISTER_FILE;
|
||||||
}
|
}
|
||||||
@@ -743,14 +738,14 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
}
|
}
|
||||||
case TargetMemoryType::FLASH: {
|
case TargetMemoryType::FLASH: {
|
||||||
if (
|
if (
|
||||||
this->configVariant == Avr8ConfigVariant::DEBUG_WIRE
|
this->session.configVariant == Avr8ConfigVariant::DEBUG_WIRE
|
||||||
|| this->configVariant == Avr8ConfigVariant::UPDI
|
|| this->session.configVariant == Avr8ConfigVariant::UPDI
|
||||||
|| this->configVariant == Avr8ConfigVariant::MEGAJTAG
|
|| this->session.configVariant == Avr8ConfigVariant::MEGAJTAG
|
||||||
) {
|
) {
|
||||||
avr8MemoryType = Avr8MemoryType::FLASH_PAGE;
|
avr8MemoryType = Avr8MemoryType::FLASH_PAGE;
|
||||||
|
|
||||||
} else if (this->configVariant == Avr8ConfigVariant::XMEGA) {
|
} else if (this->session.configVariant == Avr8ConfigVariant::XMEGA) {
|
||||||
const auto bootSectionStartAddress = this->targetParameters.bootSectionStartAddress.value();
|
const auto bootSectionStartAddress = this->session.programBootSection.value().get().startAddress;
|
||||||
if (startAddress >= bootSectionStartAddress) {
|
if (startAddress >= bootSectionStartAddress) {
|
||||||
avr8MemoryType = Avr8MemoryType::BOOT_FLASH;
|
avr8MemoryType = Avr8MemoryType::BOOT_FLASH;
|
||||||
|
|
||||||
@@ -765,21 +760,21 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
* When using the APPL_FLASH memory type, the address should be relative to the start of the
|
* When using the APPL_FLASH memory type, the address should be relative to the start of the
|
||||||
* application section.
|
* application section.
|
||||||
*/
|
*/
|
||||||
startAddress -= this->targetParameters.appSectionStartAddress.value();
|
startAddress -= this->session.programAppSection.value().get().startAddress;
|
||||||
avr8MemoryType = Avr8MemoryType::APPL_FLASH;
|
avr8MemoryType = Avr8MemoryType::APPL_FLASH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TargetMemoryType::EEPROM: {
|
case TargetMemoryType::EEPROM: {
|
||||||
switch (this->configVariant) {
|
switch (this->session.configVariant) {
|
||||||
case Avr8ConfigVariant::UPDI:
|
case Avr8ConfigVariant::UPDI:
|
||||||
case Avr8ConfigVariant::XMEGA: {
|
case Avr8ConfigVariant::XMEGA: {
|
||||||
avr8MemoryType = Avr8MemoryType::EEPROM_ATOMIC;
|
avr8MemoryType = Avr8MemoryType::EEPROM_ATOMIC;
|
||||||
|
|
||||||
if (this->configVariant == Avr8ConfigVariant::XMEGA) {
|
if (this->session.configVariant == Avr8ConfigVariant::XMEGA) {
|
||||||
// EEPROM addresses should be in relative form, for XMEGA (PDI) targets
|
// EEPROM addresses should be in relative form, for XMEGA (PDI) targets
|
||||||
startAddress -= this->targetParameters.eepromStartAddress.value();
|
startAddress -= this->session.eepromMemorySegment.startAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -810,16 +805,16 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EdbgAvr8Interface::eraseProgramMemory(std::optional<Avr8Bit::ProgramMemorySection> section) {
|
void EdbgAvr8Interface::eraseProgramMemory(std::optional<Avr8Bit::ProgramMemorySection> section) {
|
||||||
if (this->configVariant == Avr8ConfigVariant::DEBUG_WIRE) {
|
if (this->session.configVariant == Avr8ConfigVariant::DEBUG_WIRE) {
|
||||||
// The EDBG erase command does not work on debugWire targets - we'll just write to the memory instead
|
// The EDBG erase command does not work on debugWire targets - we'll just write to the memory instead
|
||||||
return this->writeMemory(
|
return this->writeMemory(
|
||||||
TargetMemoryType::FLASH,
|
TargetMemoryType::FLASH,
|
||||||
this->targetParameters.flashStartAddress.value(),
|
this->session.programMemorySegment.startAddress,
|
||||||
TargetMemoryBuffer(this->targetParameters.flashSize.value(), 0xFF)
|
TargetMemoryBuffer(this->session.programMemorySegment.size, 0xFF)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->configVariant == Avr8ConfigVariant::XMEGA) {
|
if (this->session.configVariant == Avr8ConfigVariant::XMEGA) {
|
||||||
// For PDI (XMEGA) targets, we can erase flash memory without erasing EEPROM
|
// For PDI (XMEGA) targets, we can erase flash memory without erasing EEPROM
|
||||||
|
|
||||||
if (!section.has_value() || *section == Avr8Bit::ProgramMemorySection::BOOT) {
|
if (!section.has_value() || *section == Avr8Bit::ProgramMemorySection::BOOT) {
|
||||||
@@ -908,7 +903,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
|
|
||||||
this->programmingModeEnabled = false;
|
this->programmingModeEnabled = false;
|
||||||
|
|
||||||
if (this->configVariant == Avr8ConfigVariant::MEGAJTAG && this->reactivateJtagTargetPostProgrammingMode) {
|
if (this->session.configVariant == Avr8ConfigVariant::MEGAJTAG && this->reactivateJtagTargetPostProgrammingMode) {
|
||||||
this->deactivatePhysical();
|
this->deactivatePhysical();
|
||||||
this->targetAttached = false;
|
this->targetAttached = false;
|
||||||
this->activate();
|
this->activate();
|
||||||
@@ -916,23 +911,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EdbgAvr8Interface::setTargetParameters() {
|
void EdbgAvr8Interface::setTargetParameters() {
|
||||||
if (!this->targetParameters.stackPointerRegisterLowAddress.has_value()) {
|
switch (this->session.configVariant) {
|
||||||
throw DeviceInitializationFailure("Failed to find stack pointer register start address");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this->targetParameters.stackPointerRegisterSize.has_value()) {
|
|
||||||
throw DeviceInitializationFailure("Failed to find stack pointer register size");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this->targetParameters.statusRegisterStartAddress.has_value()) {
|
|
||||||
throw DeviceInitializationFailure("Failed to find status register start address");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this->targetParameters.statusRegisterSize.has_value()) {
|
|
||||||
throw DeviceInitializationFailure("Failed to find status register size");
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (this->configVariant) {
|
|
||||||
case Avr8ConfigVariant::DEBUG_WIRE:
|
case Avr8ConfigVariant::DEBUG_WIRE:
|
||||||
case Avr8ConfigVariant::MEGAJTAG: {
|
case Avr8ConfigVariant::MEGAJTAG: {
|
||||||
this->setDebugWireAndJtagParameters();
|
this->setDebugWireAndJtagParameters();
|
||||||
@@ -952,76 +931,6 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<Family, std::map<TargetPhysicalInterface, Avr8ConfigVariant>>
|
|
||||||
EdbgAvr8Interface::getConfigVariantsByFamilyAndPhysicalInterface() {
|
|
||||||
return std::map<Family, std::map<TargetPhysicalInterface, Avr8ConfigVariant>>({
|
|
||||||
{
|
|
||||||
Family::MEGA,
|
|
||||||
{
|
|
||||||
{TargetPhysicalInterface::JTAG, Avr8ConfigVariant::MEGAJTAG},
|
|
||||||
{TargetPhysicalInterface::DEBUG_WIRE, Avr8ConfigVariant::DEBUG_WIRE},
|
|
||||||
{TargetPhysicalInterface::UPDI, Avr8ConfigVariant::UPDI},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Family::TINY,
|
|
||||||
{
|
|
||||||
{TargetPhysicalInterface::JTAG, Avr8ConfigVariant::MEGAJTAG},
|
|
||||||
{TargetPhysicalInterface::DEBUG_WIRE, Avr8ConfigVariant::DEBUG_WIRE},
|
|
||||||
{TargetPhysicalInterface::UPDI, Avr8ConfigVariant::UPDI},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Family::XMEGA,
|
|
||||||
{
|
|
||||||
{TargetPhysicalInterface::JTAG, Avr8ConfigVariant::XMEGA},
|
|
||||||
{TargetPhysicalInterface::PDI, Avr8ConfigVariant::XMEGA},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Family::DA,
|
|
||||||
{
|
|
||||||
{TargetPhysicalInterface::UPDI, Avr8ConfigVariant::UPDI},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Family::DB,
|
|
||||||
{
|
|
||||||
{TargetPhysicalInterface::UPDI, Avr8ConfigVariant::UPDI},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Family::DD,
|
|
||||||
{
|
|
||||||
{TargetPhysicalInterface::UPDI, Avr8ConfigVariant::UPDI},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Family::EA,
|
|
||||||
{
|
|
||||||
{TargetPhysicalInterface::UPDI, Avr8ConfigVariant::UPDI},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Avr8ConfigVariant EdbgAvr8Interface::resolveConfigVariant(
|
|
||||||
Targets::Microchip::Avr::Avr8Bit::Family targetFamily,
|
|
||||||
TargetPhysicalInterface physicalInterface
|
|
||||||
) {
|
|
||||||
const auto configVariantsByFamily = EdbgAvr8Interface::getConfigVariantsByFamilyAndPhysicalInterface();
|
|
||||||
const auto configVariantsByPhysicalInterfaceIt = configVariantsByFamily.find(targetFamily);
|
|
||||||
|
|
||||||
assert(configVariantsByPhysicalInterfaceIt != configVariantsByFamily.end());
|
|
||||||
|
|
||||||
const auto& configVariantsByPhysicalInterface = configVariantsByPhysicalInterfaceIt->second;
|
|
||||||
const auto configVariantIt = configVariantsByPhysicalInterface.find(physicalInterface);
|
|
||||||
|
|
||||||
assert(configVariantIt != configVariantsByPhysicalInterface.end());
|
|
||||||
|
|
||||||
return configVariantIt->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EdbgAvr8Interface::setParameter(const Avr8EdbgParameter& parameter, const std::vector<unsigned char>& value) {
|
void EdbgAvr8Interface::setParameter(const Avr8EdbgParameter& parameter, const std::vector<unsigned char>& value) {
|
||||||
using Services::StringService;
|
using Services::StringService;
|
||||||
|
|
||||||
@@ -1052,7 +961,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EdbgAvr8Interface::setDebugWireAndJtagParameters() {
|
void EdbgAvr8Interface::setDebugWireAndJtagParameters() {
|
||||||
const auto parameters = Parameters::Avr8Generic::DebugWireJtagParameters(this->targetDescriptionFile);
|
const auto parameters = Parameters::Avr8Generic::DebugWireJtagParameters(this->session.targetDescriptionFile);
|
||||||
|
|
||||||
Logger::debug("Setting FLASH_PAGE_SIZE AVR8 device parameter");
|
Logger::debug("Setting FLASH_PAGE_SIZE AVR8 device parameter");
|
||||||
this->setParameter(Avr8EdbgParameters::DEVICE_FLASH_PAGE_SIZE, parameters.flashPageSize);
|
this->setParameter(Avr8EdbgParameters::DEVICE_FLASH_PAGE_SIZE, parameters.flashPageSize);
|
||||||
@@ -1103,7 +1012,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EdbgAvr8Interface::setPdiParameters() {
|
void EdbgAvr8Interface::setPdiParameters() {
|
||||||
const auto parameters = Parameters::Avr8Generic::PdiParameters(this->targetDescriptionFile);
|
const auto parameters = Parameters::Avr8Generic::PdiParameters(this->session.targetDescriptionFile);
|
||||||
|
|
||||||
Logger::debug("Setting APPL_BASE_ADDR AVR8 parameter");
|
Logger::debug("Setting APPL_BASE_ADDR AVR8 parameter");
|
||||||
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_APPL_BASE_ADDR, parameters.appSectionPdiOffset);
|
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_APPL_BASE_ADDR, parameters.appSectionPdiOffset);
|
||||||
@@ -1152,7 +1061,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EdbgAvr8Interface::setUpdiParameters() {
|
void EdbgAvr8Interface::setUpdiParameters() {
|
||||||
const auto parameters = Parameters::Avr8Generic::UpdiParameters(this->targetDescriptionFile);
|
const auto parameters = Parameters::Avr8Generic::UpdiParameters(this->session.targetDescriptionFile);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The program memory base address field for UPDI sessions (DEVICE_UPDI_PROGMEM_BASE_ADDR) seems to be
|
* The program memory base address field for UPDI sessions (DEVICE_UPDI_PROGMEM_BASE_ADDR) seems to be
|
||||||
@@ -1202,55 +1111,35 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
static_cast<std::uint8_t>(parameters.flashPageSize >> 8)
|
static_cast<std::uint8_t>(parameters.flashPageSize >> 8)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (this->targetParameters.eepromPageSize.has_value()) {
|
Logger::debug("Setting UPDI_EEPROM_PAGE_SIZE AVR8 device parameter");
|
||||||
Logger::debug("Setting UPDI_EEPROM_PAGE_SIZE AVR8 device parameter");
|
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_EEPROM_PAGE_SIZE, parameters.eepromPageSize);
|
||||||
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_EEPROM_PAGE_SIZE, parameters.eepromPageSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->targetParameters.nvmModuleBaseAddress.has_value()) {
|
Logger::debug("Setting UPDI_NVMCTRL_ADDR AVR8 device parameter");
|
||||||
Logger::debug("Setting UPDI_NVMCTRL_ADDR AVR8 device parameter");
|
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_NVMCTRL_ADDR, parameters.nvmModuleBaseAddress);
|
||||||
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_NVMCTRL_ADDR, parameters.nvmModuleBaseAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->targetParameters.ocdModuleAddress.has_value()) {
|
Logger::debug("Setting UPDI_OCD_ADDR AVR8 device parameter");
|
||||||
Logger::debug("Setting UPDI_OCD_ADDR AVR8 device parameter");
|
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_OCD_ADDR, parameters.ocdModuleAddress);
|
||||||
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_OCD_ADDR, parameters.ocdModuleAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->targetParameters.flashSize.has_value()) {
|
Logger::debug("Setting UPDI_FLASH_SIZE AVR8 device parameter");
|
||||||
Logger::debug("Setting UPDI_FLASH_SIZE AVR8 device parameter");
|
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_FLASH_SIZE, parameters.flashSize);
|
||||||
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_FLASH_SIZE, parameters.flashSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->targetParameters.eepromSize.has_value()) {
|
Logger::debug("Setting UPDI_EEPROM_SIZE AVR8 device parameter");
|
||||||
Logger::debug("Setting UPDI_EEPROM_SIZE AVR8 device parameter");
|
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_EEPROM_SIZE, parameters.eepromSize);
|
||||||
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_EEPROM_SIZE, parameters.eepromSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->targetParameters.eepromStartAddress.has_value()) {
|
Logger::debug("Setting UPDI_EEPROM_BASE_ADDR AVR8 device parameter");
|
||||||
Logger::debug("Setting UPDI_EEPROM_BASE_ADDR AVR8 device parameter");
|
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_EEPROM_BASE_ADDR, parameters.eepromStartAddress);
|
||||||
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_EEPROM_BASE_ADDR, parameters.eepromStartAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->targetParameters.signatureSegmentStartAddress.has_value()) {
|
Logger::debug("Setting UPDI_SIG_BASE_ADDR AVR8 device parameter");
|
||||||
Logger::debug("Setting UPDI_SIG_BASE_ADDR AVR8 device parameter");
|
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_SIG_BASE_ADDR, parameters.signatureSegmentStartAddress);
|
||||||
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_SIG_BASE_ADDR, parameters.signatureSegmentStartAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->targetParameters.fuseSegmentStartAddress.has_value()) {
|
Logger::debug("Setting UPDI_FUSE_BASE_ADDR AVR8 device parameter");
|
||||||
Logger::debug("Setting UPDI_FUSE_BASE_ADDR AVR8 device parameter");
|
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_FUSE_BASE_ADDR, parameters.fuseSegmentStartAddress);
|
||||||
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_FUSE_BASE_ADDR, parameters.fuseSegmentStartAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->targetParameters.fuseSegmentSize.has_value()) {
|
Logger::debug("Setting UPDI_FUSE_SIZE AVR8 device parameter");
|
||||||
Logger::debug("Setting UPDI_FUSE_SIZE AVR8 device parameter");
|
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_FUSE_SIZE, parameters.fuseSegmentSize);
|
||||||
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_FUSE_SIZE, parameters.fuseSegmentSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->targetParameters.lockbitsSegmentStartAddress.has_value()) {
|
Logger::debug("Setting UPDI_LOCK_BASE_ADDR AVR8 device parameter");
|
||||||
Logger::debug("Setting UPDI_LOCK_BASE_ADDR AVR8 device parameter");
|
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_LOCK_BASE_ADDR, parameters.lockbitSegmentStartAddress);
|
||||||
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_LOCK_BASE_ADDR, parameters.lockbitSegmentStartAddress);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EdbgAvr8Interface::activatePhysical(bool applyExternalReset) {
|
void EdbgAvr8Interface::activatePhysical(bool applyExternalReset) {
|
||||||
@@ -1295,7 +1184,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
*/
|
*/
|
||||||
const auto responseFrame = this->edbgInterface->sendAvrCommandFrameAndWaitForResponseFrame(
|
const auto responseFrame = this->edbgInterface->sendAvrCommandFrameAndWaitForResponseFrame(
|
||||||
Attach(
|
Attach(
|
||||||
this->configVariant != Avr8ConfigVariant::MEGAJTAG
|
this->session.configVariant != Avr8ConfigVariant::MEGAJTAG
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1384,12 +1273,12 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
* align them - we've tried only word aligning them - the debug tool reports a "Too many or too few
|
* align them - we've tried only word aligning them - the debug tool reports a "Too many or too few
|
||||||
* bytes" error.
|
* bytes" error.
|
||||||
*/
|
*/
|
||||||
alignTo = this->targetParameters.flashPageSize.value();
|
alignTo = static_cast<std::uint16_t>(this->session.programMemorySegment.pageSize.value());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Avr8MemoryType::EEPROM_ATOMIC:
|
case Avr8MemoryType::EEPROM_ATOMIC:
|
||||||
case Avr8MemoryType::EEPROM_PAGE: {
|
case Avr8MemoryType::EEPROM_PAGE: {
|
||||||
alignTo = this->targetParameters.eepromPageSize.value();
|
alignTo = static_cast<std::uint16_t>(this->session.eepromMemorySegment.pageSize.value());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
@@ -1418,12 +1307,12 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
case Avr8MemoryType::APPL_FLASH:
|
case Avr8MemoryType::APPL_FLASH:
|
||||||
case Avr8MemoryType::BOOT_FLASH: {
|
case Avr8MemoryType::BOOT_FLASH: {
|
||||||
// See comment in EdbgAvr8Interface::alignMemoryAddress()
|
// See comment in EdbgAvr8Interface::alignMemoryAddress()
|
||||||
alignTo = this->targetParameters.flashPageSize.value();
|
alignTo = static_cast<std::uint16_t>(this->session.programMemorySegment.pageSize.value());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Avr8MemoryType::EEPROM_ATOMIC:
|
case Avr8MemoryType::EEPROM_ATOMIC:
|
||||||
case Avr8MemoryType::EEPROM_PAGE: {
|
case Avr8MemoryType::EEPROM_PAGE: {
|
||||||
alignTo = this->targetParameters.eepromPageSize.value();
|
alignTo = static_cast<std::uint16_t>(this->session.eepromMemorySegment.pageSize.value());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
@@ -1445,10 +1334,10 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
memoryType == Avr8MemoryType::FLASH_PAGE
|
memoryType == Avr8MemoryType::FLASH_PAGE
|
||||||
|| memoryType == Avr8MemoryType::APPL_FLASH
|
|| memoryType == Avr8MemoryType::APPL_FLASH
|
||||||
|| memoryType == Avr8MemoryType::BOOT_FLASH
|
|| memoryType == Avr8MemoryType::BOOT_FLASH
|
||||||
|| (memoryType == Avr8MemoryType::SPM && this->configVariant == Avr8ConfigVariant::MEGAJTAG)
|
|| (memoryType == Avr8MemoryType::SPM && this->session.configVariant == Avr8ConfigVariant::MEGAJTAG)
|
||||||
) {
|
) {
|
||||||
// These flash memory types require single page access.
|
// These flash memory types require single page access.
|
||||||
return this->targetParameters.flashPageSize.value();
|
return this->session.programMemorySegment.pageSize.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@@ -1456,7 +1345,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
|| memoryType == Avr8MemoryType::EEPROM_PAGE
|
|| memoryType == Avr8MemoryType::EEPROM_PAGE
|
||||||
) {
|
) {
|
||||||
// These EEPROM memory types requires single page access.
|
// These EEPROM memory types requires single page access.
|
||||||
return this->targetParameters.eepromPageSize.value();
|
return this->session.eepromMemorySegment.pageSize.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->maximumMemoryAccessSizePerRequest.has_value()) {
|
if (this->maximumMemoryAccessSizePerRequest.has_value()) {
|
||||||
@@ -1485,7 +1374,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
const std::set<TargetMemoryAddress>& excludedAddresses
|
const std::set<TargetMemoryAddress>& excludedAddresses
|
||||||
) {
|
) {
|
||||||
if (type == Avr8MemoryType::FUSES) {
|
if (type == Avr8MemoryType::FUSES) {
|
||||||
if (this->configVariant == Avr8ConfigVariant::DEBUG_WIRE) {
|
if (this->session.configVariant == Avr8ConfigVariant::DEBUG_WIRE) {
|
||||||
throw Exception("Cannot access AVR fuses via the debugWire interface");
|
throw Exception("Cannot access AVR fuses via the debugWire interface");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1618,7 +1507,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
const TargetMemoryBuffer& buffer
|
const TargetMemoryBuffer& buffer
|
||||||
) {
|
) {
|
||||||
if (type == Avr8MemoryType::FUSES) {
|
if (type == Avr8MemoryType::FUSES) {
|
||||||
if (this->configVariant == Avr8ConfigVariant::DEBUG_WIRE) {
|
if (this->session.configVariant == Avr8ConfigVariant::DEBUG_WIRE) {
|
||||||
throw Exception("Cannot access AVR fuses via the debugWire interface");
|
throw Exception("Cannot access AVR fuses via the debugWire interface");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,11 +10,13 @@
|
|||||||
#include "src/DebugToolDrivers/Microchip/Protocols/EDBG/EdbgInterface.hpp"
|
#include "src/DebugToolDrivers/Microchip/Protocols/EDBG/EdbgInterface.hpp"
|
||||||
|
|
||||||
#include "Avr8Generic.hpp"
|
#include "Avr8Generic.hpp"
|
||||||
|
#include "EdbgAvr8Session.hpp"
|
||||||
|
|
||||||
#include "src/Targets/TargetPhysicalInterface.hpp"
|
#include "src/Targets/TargetPhysicalInterface.hpp"
|
||||||
#include "src/Targets/TargetMemory.hpp"
|
#include "src/Targets/TargetMemory.hpp"
|
||||||
#include "src/Targets/TargetRegisterDescriptor.hpp"
|
#include "src/Targets/TargetRegisterDescriptor.hpp"
|
||||||
#include "src/Targets/TargetRegister.hpp"
|
#include "src/Targets/TargetRegister.hpp"
|
||||||
|
#include "src/Targets/Microchip/AVR/AVR8/TargetDescriptionFile.hpp"
|
||||||
#include "src/Targets/Microchip/AVR/AVR8/Family.hpp"
|
#include "src/Targets/Microchip/AVR/AVR8/Family.hpp"
|
||||||
#include "src/Targets/Microchip/AVR/AVR8/TargetParameters.hpp"
|
#include "src/Targets/Microchip/AVR/AVR8/TargetParameters.hpp"
|
||||||
|
|
||||||
@@ -34,10 +36,8 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
public:
|
public:
|
||||||
explicit EdbgAvr8Interface(
|
explicit EdbgAvr8Interface(
|
||||||
EdbgInterface* edbgInterface,
|
EdbgInterface* edbgInterface,
|
||||||
const Targets::Microchip::Avr::Avr8Bit::Avr8TargetConfig& targetConfig,
|
const Targets::Microchip::Avr::Avr8Bit::TargetDescriptionFile& targetDescriptionFile,
|
||||||
Targets::Microchip::Avr::Avr8Bit::Family targetFamily,
|
const Targets::Microchip::Avr::Avr8Bit::Avr8TargetConfig& targetConfig
|
||||||
const Targets::Microchip::Avr::Avr8Bit::TargetParameters& targetParameters,
|
|
||||||
const Targets::TargetRegisterDescriptorMapping& targetRegisterDescriptorsById
|
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -294,42 +294,9 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
EdbgInterface* edbgInterface = nullptr;
|
EdbgInterface* edbgInterface = nullptr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Project's AVR8 target configuration.
|
* The active EDBG AVR8 session.
|
||||||
*/
|
*/
|
||||||
const Targets::Microchip::Avr::Avr8Bit::Avr8TargetConfig& targetConfig;
|
EdbgAvr8Session session;
|
||||||
|
|
||||||
/**
|
|
||||||
* The target family is taken into account when configuring the AVR8 Generic protocol on the EDBG device.
|
|
||||||
*
|
|
||||||
* We use this to determine which config variant to select.
|
|
||||||
* See EdbgAvr8Interface::resolveConfigVariant() for more.
|
|
||||||
*/
|
|
||||||
Targets::Microchip::Avr::Avr8Bit::Family family;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The AVR8 Generic protocol provides two functions: Debugging and programming. The desired function must be
|
|
||||||
* configured via the setting of the "AVR8_CONFIG_FUNCTION" parameter.
|
|
||||||
*/
|
|
||||||
Avr8ConfigFunction configFunction = Avr8ConfigFunction::DEBUGGING;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configuring of the AVR8 Generic protocol depends on some characteristics of the target.
|
|
||||||
* The "AVR8_CONFIG_VARIANT" parameter allows us to determine which target parameters are required by the
|
|
||||||
* debug tool.
|
|
||||||
*/
|
|
||||||
Avr8ConfigVariant configVariant = Avr8ConfigVariant::NONE;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* EDBG-based debug tools require target specific parameters such as memory locations, page sizes and
|
|
||||||
* register addresses. It is the AVR8 target's responsibility to obtain the required information and pass it
|
|
||||||
* to the Avr8Interface. See Avr8::getTargetParameters() and Avr8::postPromotionConfigure().
|
|
||||||
*
|
|
||||||
* For the EdbgAvr8Interface, we send the required parameters to the debug tool immediately upon receiving
|
|
||||||
* them. See EdbgAvr8Interface::setTargetParameters().
|
|
||||||
*/
|
|
||||||
const Targets::Microchip::Avr::Avr8Bit::TargetParameters& targetParameters;
|
|
||||||
|
|
||||||
const Targets::TargetRegisterDescriptorMapping& targetRegisterDescriptorsById;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See the comment for EdbgAvr8Interface::setAvoidMaskedMemoryRead().
|
* See the comment for EdbgAvr8Interface::setAvoidMaskedMemoryRead().
|
||||||
@@ -379,25 +346,6 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
*/
|
*/
|
||||||
void setTargetParameters();
|
void setTargetParameters();
|
||||||
|
|
||||||
/**
|
|
||||||
* This mapping allows us to determine which config variant to select, based on the target family and the
|
|
||||||
* selected physical interface.
|
|
||||||
*/
|
|
||||||
static std::map<
|
|
||||||
Targets::Microchip::Avr::Avr8Bit::Family,
|
|
||||||
std::map<Targets::TargetPhysicalInterface, Avr8ConfigVariant>
|
|
||||||
> getConfigVariantsByFamilyAndPhysicalInterface();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines the config variant given a target family and physical interface.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
static Avr8ConfigVariant resolveConfigVariant(
|
|
||||||
Targets::Microchip::Avr::Avr8Bit::Family targetFamily,
|
|
||||||
Targets::TargetPhysicalInterface physicalInterface
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets an AVR8 parameter on the debug tool. See the Avr8EdbgParameters class and protocol documentation
|
* Sets an AVR8 parameter on the debug tool. See the Avr8EdbgParameters class and protocol documentation
|
||||||
* for more on available parameters.
|
* for more on available parameters.
|
||||||
@@ -461,17 +409,15 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
* register addresses. These parameters can be sent to the tool before and during a session.
|
* register addresses. These parameters can be sent to the tool before and during a session.
|
||||||
*
|
*
|
||||||
* What parameters we need to send depend on the physical interface (and config variant) selected by the user.
|
* What parameters we need to send depend on the physical interface (and config variant) selected by the user.
|
||||||
* For target parameters, the address (ID) of the parameter also varies across config variants. This is why
|
* For target parameters, the address (ID) of the parameter also varies across config variants.
|
||||||
* we sometimes have separate parameters for sending the same data, where they differ only in parameter IDs
|
|
||||||
* (and sometimes size constraints). For example, the Avr8EdbgParameters::FLASH_PAGE_BYTES parameter is used
|
|
||||||
* to specify the size of a single page in flash memory. The parameter is assigned an address (ID) of 0x00. But
|
|
||||||
* the Avr8EdbgParameters::DEVICE_XMEGA_FLASH_PAGE_BYTES parameter is used to send the same data (flash page
|
|
||||||
* size), but only for sessions with the PDI physical interface. The address is 0x26.
|
|
||||||
*
|
*
|
||||||
* - The setDebugWireAndJtagParameters() function sends the required target parameters for debugWire and JTAG
|
* - The setDebugWireAndJtagParameters() function sends the required target parameters for debugWire and JTAG
|
||||||
* sessions. Both sessions are covered in a single function because they require the same parameters.
|
* sessions. Both sessions are covered in a single function because they require the same parameters.
|
||||||
* - The setPdiParameters() function sends the required target parameters for PDI sessions.
|
* - The setPdiParameters() function sends the required target parameters for PDI sessions.
|
||||||
* - The setUpdiParameters() function sends the required target parameters for UPDI sessions.
|
* - The setUpdiParameters() function sends the required target parameters for UPDI sessions.
|
||||||
|
*
|
||||||
|
* We extract the required parameters from the TDF. See the constructors for the `DebugWireJtagParameters`,
|
||||||
|
* `PdiParameters` and `UpdiParameters` structs for more.
|
||||||
*/
|
*/
|
||||||
void setDebugWireAndJtagParameters();
|
void setDebugWireAndJtagParameters();
|
||||||
void setPdiParameters();
|
void setPdiParameters();
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
#include "EdbgAvr8Session.hpp"
|
||||||
|
|
||||||
|
#include "src/Services/StringService.hpp"
|
||||||
|
|
||||||
|
#include "src/Exceptions/Exception.hpp"
|
||||||
|
|
||||||
|
namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||||
|
{
|
||||||
|
EdbgAvr8Session::EdbgAvr8Session(
|
||||||
|
const Targets::Microchip::Avr::Avr8Bit::TargetDescriptionFile& targetDescriptionFile,
|
||||||
|
const Targets::Microchip::Avr::Avr8Bit::Avr8TargetConfig& targetConfig
|
||||||
|
)
|
||||||
|
: targetDescriptionFile(targetDescriptionFile)
|
||||||
|
, targetConfig(targetConfig)
|
||||||
|
, programAddressSpace(this->targetDescriptionFile.getProgramAddressSpace())
|
||||||
|
, ramAddressSpace(this->targetDescriptionFile.getRamAddressSpace())
|
||||||
|
, eepromAddressSpace(this->targetDescriptionFile.getEepromAddressSpace())
|
||||||
|
, ioAddressSpace(this->targetDescriptionFile.getIoAddressSpace())
|
||||||
|
, signatureAddressSpace(this->targetDescriptionFile.getSignatureAddressSpace())
|
||||||
|
, programMemorySegment(this->targetDescriptionFile.getProgramMemorySegment())
|
||||||
|
, ramMemorySegment(this->targetDescriptionFile.getRamMemorySegment())
|
||||||
|
, eepromMemorySegment(this->targetDescriptionFile.getEepromMemorySegment())
|
||||||
|
, ioMemorySegment(this->targetDescriptionFile.getIoMemorySegment())
|
||||||
|
, signatureMemorySegment(this->targetDescriptionFile.getSignatureMemorySegment())
|
||||||
|
, programAppSection(this->programMemorySegment.tryGetSection("app_section"))
|
||||||
|
, programBootSection(this->programMemorySegment.tryGetSection("boot_section"))
|
||||||
|
{
|
||||||
|
using Services::StringService;
|
||||||
|
|
||||||
|
const auto ocdDataRegisterProperty = this->targetDescriptionFile.tryGetProperty("ocd", "ocd_datareg");
|
||||||
|
if (ocdDataRegisterProperty.has_value()) {
|
||||||
|
this->ocdDataRegister = StringService::toUint8(ocdDataRegisterProperty->get().value);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto resolvedConfigVariant = EdbgAvr8Session::tryResolveConfigVariant(
|
||||||
|
this->targetDescriptionFile.getAvrFamily(),
|
||||||
|
this->targetConfig.physicalInterface
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!resolvedConfigVariant.has_value()) {
|
||||||
|
throw Exceptions::Exception(
|
||||||
|
"Failed to resolve EDBG config variant from the selected physical interface and the AVR target family"
|
||||||
|
" - please review the selected physical interface"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->configVariant = *resolvedConfigVariant;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<Avr8ConfigVariant> EdbgAvr8Session::tryResolveConfigVariant(
|
||||||
|
Targets::Microchip::Avr::Avr8Bit::Family avrFamily,
|
||||||
|
Targets::TargetPhysicalInterface physicalInterface
|
||||||
|
) {
|
||||||
|
using Targets::Microchip::Avr::Avr8Bit::Family;
|
||||||
|
using Targets::TargetPhysicalInterface;
|
||||||
|
|
||||||
|
if (avrFamily == Family::MEGA || avrFamily == Family::TINY) {
|
||||||
|
switch (physicalInterface) {
|
||||||
|
case TargetPhysicalInterface::JTAG: {
|
||||||
|
return Avr8ConfigVariant::MEGAJTAG;
|
||||||
|
}
|
||||||
|
case TargetPhysicalInterface::DEBUG_WIRE: {
|
||||||
|
return Avr8ConfigVariant::DEBUG_WIRE;
|
||||||
|
}
|
||||||
|
case TargetPhysicalInterface::UPDI: {
|
||||||
|
return Avr8ConfigVariant::UPDI;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (avrFamily == Family::XMEGA) {
|
||||||
|
switch (physicalInterface) {
|
||||||
|
case TargetPhysicalInterface::JTAG:
|
||||||
|
case TargetPhysicalInterface::PDI: {
|
||||||
|
return Avr8ConfigVariant::XMEGA;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (avrFamily == Family::DA || avrFamily == Family::DB || avrFamily == Family::DD || avrFamily == Family::EA) {
|
||||||
|
switch (physicalInterface) {
|
||||||
|
case TargetPhysicalInterface::UPDI: {
|
||||||
|
return Avr8ConfigVariant::UPDI;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <optional>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#include "src/Targets/Microchip/AVR/AVR8/TargetDescriptionFile.hpp"
|
||||||
|
#include "src/Targets/Microchip/AVR/AVR8/Avr8TargetConfig.hpp"
|
||||||
|
#include "src/Targets/TargetMemorySegmentDescriptor.hpp"
|
||||||
|
#include "src/Targets/TargetRegisterDescriptor.hpp"
|
||||||
|
|
||||||
|
#include "Avr8Generic.hpp"
|
||||||
|
|
||||||
|
namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* This struct holds all required target info for an EDBG AVR8 session.
|
||||||
|
*/
|
||||||
|
struct EdbgAvr8Session
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* AVR8 TDF, from which we extract all target info to configure the EDBG debug tool.
|
||||||
|
*/
|
||||||
|
const Targets::Microchip::Avr::Avr8Bit::TargetDescriptionFile& targetDescriptionFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Project's AVR8 target configuration.
|
||||||
|
*/
|
||||||
|
const Targets::Microchip::Avr::Avr8Bit::Avr8TargetConfig& targetConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The EDBG config variant parameter.
|
||||||
|
*
|
||||||
|
* See the "AVR8_CONFIG_VARIANT" parameter in section 7.1.3.1 of Microchip's "EDBG-based Tools Protocols"
|
||||||
|
* document for more.
|
||||||
|
*/
|
||||||
|
Avr8ConfigVariant configVariant = Avr8ConfigVariant::NONE;
|
||||||
|
|
||||||
|
const Targets::TargetDescription::AddressSpace& programAddressSpace;
|
||||||
|
const Targets::TargetDescription::AddressSpace& ramAddressSpace;
|
||||||
|
const Targets::TargetDescription::AddressSpace& eepromAddressSpace;
|
||||||
|
const Targets::TargetDescription::AddressSpace& ioAddressSpace;
|
||||||
|
const Targets::TargetDescription::AddressSpace& signatureAddressSpace;
|
||||||
|
|
||||||
|
const Targets::TargetDescription::MemorySegment& programMemorySegment;
|
||||||
|
const Targets::TargetDescription::MemorySegment& ramMemorySegment;
|
||||||
|
const Targets::TargetDescription::MemorySegment& eepromMemorySegment;
|
||||||
|
const Targets::TargetDescription::MemorySegment& ioMemorySegment;
|
||||||
|
const Targets::TargetDescription::MemorySegment& signatureMemorySegment;
|
||||||
|
|
||||||
|
const std::optional<
|
||||||
|
std::reference_wrapper<const Targets::TargetDescription::MemorySegmentSection>
|
||||||
|
> programAppSection;
|
||||||
|
|
||||||
|
const std::optional<
|
||||||
|
std::reference_wrapper<const Targets::TargetDescription::MemorySegmentSection>
|
||||||
|
> programBootSection;
|
||||||
|
|
||||||
|
std::optional<std::uint8_t> ocdDataRegister;
|
||||||
|
|
||||||
|
EdbgAvr8Session(
|
||||||
|
const Targets::Microchip::Avr::Avr8Bit::TargetDescriptionFile& targetDescriptionFile,
|
||||||
|
const Targets::Microchip::Avr::Avr8Bit::Avr8TargetConfig& targetConfig
|
||||||
|
);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Attempts to determine the EDBG config variant for a given AVR family and physical interface.
|
||||||
|
*
|
||||||
|
* See the "AVR8_CONFIG_VARIANT" parameter in section 7.1.3.1 of Microchip's "EDBG-based Tools Protocols"
|
||||||
|
* document for more.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The resolved config variant, or std::nullopt if the given AVR family and physical interface do not map to
|
||||||
|
* any particular EDBG config variant.
|
||||||
|
*/
|
||||||
|
static std::optional<Avr8ConfigVariant> tryResolveConfigVariant(
|
||||||
|
Targets::Microchip::Avr::Avr8Bit::Family avrFamily,
|
||||||
|
Targets::TargetPhysicalInterface physicalInterface
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -50,27 +50,60 @@ namespace Targets::Microchip::Avr::Avr8Bit
|
|||||||
return familyIt->second;
|
return familyIt->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Targets::TargetDescription::AddressSpace& TargetDescriptionFile::getProgramAddressSpace() const {
|
||||||
|
return this->getAddressSpace("prog");
|
||||||
|
}
|
||||||
|
|
||||||
|
const Targets::TargetDescription::AddressSpace& TargetDescriptionFile::getRamAddressSpace() const {
|
||||||
|
return this->getAddressSpace("data");
|
||||||
|
}
|
||||||
|
|
||||||
|
const Targets::TargetDescription::AddressSpace& TargetDescriptionFile::getEepromAddressSpace() const {
|
||||||
|
const auto addressSpace = this->tryGetAddressSpace("eeprom");
|
||||||
|
return addressSpace.has_value()
|
||||||
|
? addressSpace->get()
|
||||||
|
: this->getAddressSpace("data");
|
||||||
|
}
|
||||||
|
|
||||||
|
const Targets::TargetDescription::AddressSpace& TargetDescriptionFile::getIoAddressSpace() const {
|
||||||
|
return this->getAddressSpace("data");
|
||||||
|
}
|
||||||
|
|
||||||
|
const Targets::TargetDescription::AddressSpace& TargetDescriptionFile::getSignatureAddressSpace() const {
|
||||||
|
const auto addressSpace = this->tryGetAddressSpace("signatures");
|
||||||
|
return addressSpace.has_value()
|
||||||
|
? addressSpace->get()
|
||||||
|
: this->getAddressSpace("data");
|
||||||
|
}
|
||||||
|
|
||||||
|
const Targets::TargetDescription::AddressSpace& TargetDescriptionFile::getFuseAddressSpace() const {
|
||||||
|
const auto addressSpace = this->tryGetAddressSpace("fuses");
|
||||||
|
return addressSpace.has_value()
|
||||||
|
? addressSpace->get()
|
||||||
|
: this->getAddressSpace("data");
|
||||||
|
}
|
||||||
|
|
||||||
|
const Targets::TargetDescription::AddressSpace& TargetDescriptionFile::getLockbitAddressSpace() const {
|
||||||
|
const auto addressSpace = this->tryGetAddressSpace("lockbits");
|
||||||
|
return addressSpace.has_value()
|
||||||
|
? addressSpace->get()
|
||||||
|
: this->getAddressSpace("data");
|
||||||
|
}
|
||||||
|
|
||||||
const Targets::TargetDescription::MemorySegment& TargetDescriptionFile::getProgramMemorySegment() const {
|
const Targets::TargetDescription::MemorySegment& TargetDescriptionFile::getProgramMemorySegment() const {
|
||||||
return this->getAddressSpace("prog").getMemorySegment("internal_program_memory");
|
return this->getProgramAddressSpace().getMemorySegment("internal_program_memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
const Targets::TargetDescription::MemorySegment& TargetDescriptionFile::getRamMemorySegment() const {
|
const Targets::TargetDescription::MemorySegment& TargetDescriptionFile::getRamMemorySegment() const {
|
||||||
return this->getAddressSpace("data").getMemorySegment("internal_ram");
|
return this->getRamAddressSpace().getMemorySegment("internal_ram");
|
||||||
}
|
}
|
||||||
|
|
||||||
const Targets::TargetDescription::MemorySegment& TargetDescriptionFile::getEepromMemorySegment() const {
|
const Targets::TargetDescription::MemorySegment& TargetDescriptionFile::getEepromMemorySegment() const {
|
||||||
/*
|
return this->getEepromAddressSpace().getMemorySegment("internal_eeprom");
|
||||||
* The EEPROM segment can sometimes be found within a dedicated address space, or within the data address
|
|
||||||
* space.
|
|
||||||
*/
|
|
||||||
const auto addressSpace = this->tryGetAddressSpace("eeprom");
|
|
||||||
return addressSpace.has_value()
|
|
||||||
? addressSpace->get().getMemorySegment("internal_eeprom")
|
|
||||||
: this->getAddressSpace("data").getMemorySegment("internal_eeprom");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Targets::TargetDescription::MemorySegment& TargetDescriptionFile::getIoMemorySegment() const {
|
const Targets::TargetDescription::MemorySegment& TargetDescriptionFile::getIoMemorySegment() const {
|
||||||
const auto addressSpace = this->getAddressSpace("data");
|
const auto addressSpace = this->getIoAddressSpace();
|
||||||
const auto segment = addressSpace.tryGetMemorySegment("io");
|
const auto segment = addressSpace.tryGetMemorySegment("io");
|
||||||
return segment.has_value()
|
return segment.has_value()
|
||||||
? segment->get()
|
? segment->get()
|
||||||
@@ -78,36 +111,15 @@ namespace Targets::Microchip::Avr::Avr8Bit
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Targets::TargetDescription::MemorySegment& TargetDescriptionFile::getSignatureMemorySegment() const {
|
const Targets::TargetDescription::MemorySegment& TargetDescriptionFile::getSignatureMemorySegment() const {
|
||||||
/*
|
return this->getSignatureAddressSpace().getMemorySegment("signatures");
|
||||||
* The signatures segment can sometimes be found within a dedicated address space, or within the data address
|
|
||||||
* space.
|
|
||||||
*/
|
|
||||||
const auto addressSpace = this->tryGetAddressSpace("signatures");
|
|
||||||
return addressSpace.has_value()
|
|
||||||
? addressSpace->get().getMemorySegment("signatures")
|
|
||||||
: this->getAddressSpace("data").getMemorySegment("signatures");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Targets::TargetDescription::MemorySegment& TargetDescriptionFile::getFuseMemorySegment() const {
|
const Targets::TargetDescription::MemorySegment& TargetDescriptionFile::getFuseMemorySegment() const {
|
||||||
/*
|
return this->getFuseAddressSpace().getMemorySegment("fuses");
|
||||||
* The fuses segment can sometimes be found within a dedicated address space, or within the data address
|
|
||||||
* space.
|
|
||||||
*/
|
|
||||||
const auto addressSpace = this->tryGetAddressSpace("fuses");
|
|
||||||
return addressSpace.has_value()
|
|
||||||
? addressSpace->get().getMemorySegment("fuses")
|
|
||||||
: this->getAddressSpace("data").getMemorySegment("fuses");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Targets::TargetDescription::MemorySegment& TargetDescriptionFile::getLockbitMemorySegment() const {
|
const Targets::TargetDescription::MemorySegment& TargetDescriptionFile::getLockbitMemorySegment() const {
|
||||||
/*
|
return this->getLockbitAddressSpace().getMemorySegment("lockbits");
|
||||||
* The lockbits segment can sometimes be found within a dedicated address space, or within the data address
|
|
||||||
* space.
|
|
||||||
*/
|
|
||||||
const auto addressSpace = this->tryGetAddressSpace("lockbits");
|
|
||||||
return addressSpace.has_value()
|
|
||||||
? addressSpace->get().getMemorySegment("lockbits")
|
|
||||||
: this->getAddressSpace("data").getMemorySegment("lockbits");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetParameters TargetDescriptionFile::getTargetParameters() const {
|
TargetParameters TargetDescriptionFile::getTargetParameters() const {
|
||||||
|
|||||||
@@ -54,6 +54,14 @@ namespace Targets::Microchip::Avr::Avr8Bit
|
|||||||
*/
|
*/
|
||||||
[[nodiscard]] Family getAvrFamily() const;
|
[[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& getProgramMemorySegment() const;
|
||||||
[[nodiscard]] const Targets::TargetDescription::MemorySegment& getRamMemorySegment() const;
|
[[nodiscard]] const Targets::TargetDescription::MemorySegment& getRamMemorySegment() const;
|
||||||
[[nodiscard]] const Targets::TargetDescription::MemorySegment& getEepromMemorySegment() const;
|
[[nodiscard]] const Targets::TargetDescription::MemorySegment& getEepromMemorySegment() const;
|
||||||
|
|||||||
Reference in New Issue
Block a user