Refactored AVR8 TDF loading
Refactored EDBG AVR8 target parameter uploading Implemented UPDI parameter extraction (from TDF) and uploading to debug tool Introduced supported physical interfaces in AVR8 TDFs
This commit is contained in:
@@ -20,7 +20,7 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
|
||||
constexpr static Avr8EdbgParameter CONFIG_FUNCTION {0x00, 0x01};
|
||||
constexpr static Avr8EdbgParameter PHYSICAL_INTERFACE {0x01, 0x00};
|
||||
constexpr static Avr8EdbgParameter DW_CLOCK_DIVISION_FACTOR {0x01, 0x10};
|
||||
constexpr static Avr8EdbgParameter XMEGA_PDI_CLOCK {0x01, 0x31};
|
||||
constexpr static Avr8EdbgParameter PDI_CLOCK_SPEED {0x01, 0x31};
|
||||
constexpr static Avr8EdbgParameter MEGA_DEBUG_CLOCK {0x01, 0x21};
|
||||
constexpr static Avr8EdbgParameter JTAG_DAISY_CHAIN_SETTINGS {0x01, 0x01};
|
||||
|
||||
@@ -58,7 +58,28 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
|
||||
constexpr static Avr8EdbgParameter DEVICE_XMEGA_EEPROM_SIZE {0x02, 0x28};
|
||||
constexpr static Avr8EdbgParameter DEVICE_XMEGA_EEPROM_PAGE_SIZE {0x02, 0x2A};
|
||||
|
||||
// UPDI device parameters
|
||||
constexpr static Avr8EdbgParameter DEVICE_UPDI_PROGMEM_BASE_ADDR {0x02, 0x00};
|
||||
constexpr static Avr8EdbgParameter DEVICE_UPDI_FLASH_PAGE_SIZE {0x02, 0x02};
|
||||
constexpr static Avr8EdbgParameter DEVICE_UPDI_EEPROM_PAGE_SIZE {0x02, 0x03};
|
||||
constexpr static Avr8EdbgParameter DEVICE_UPDI_NVMCTRL_ADDR {0x02, 0x04};
|
||||
constexpr static Avr8EdbgParameter DEVICE_UPDI_OCD_ADDR {0x02, 0x06};
|
||||
constexpr static Avr8EdbgParameter DEVICE_UPDI_FLASH_SIZE {0x02, 0x12};
|
||||
constexpr static Avr8EdbgParameter DEVICE_UPDI_EEPROM_SIZE {0x02, 0x16};
|
||||
constexpr static Avr8EdbgParameter DEVICE_UPDI_USER_SIG_SIZE {0x02, 0x18};
|
||||
constexpr static Avr8EdbgParameter DEVICE_UPDI_FUSE_SIZE {0x02, 0x1A};
|
||||
constexpr static Avr8EdbgParameter DEVICE_UPDI_EEPROM_BASE_ADDR {0x02, 0x20};
|
||||
constexpr static Avr8EdbgParameter DEVICE_UPDI_USER_SIG_BASE_ADDR {0x02, 0x22};
|
||||
constexpr static Avr8EdbgParameter DEVICE_UPDI_SIG_BASE_ADDR {0x02, 0x24};
|
||||
constexpr static Avr8EdbgParameter DEVICE_UPDI_FUSE_BASE_ADDR {0x02, 0x26};
|
||||
constexpr static Avr8EdbgParameter DEVICE_UPDI_LOCK_BASE_ADDR {0x02, 0x28};
|
||||
constexpr static Avr8EdbgParameter DEVICE_UPDI_DEVICE_ID {0x02, 0x2A};
|
||||
constexpr static Avr8EdbgParameter DEVICE_UPDI_PROGMEM_BASE_ADDR_MSB {0x02, 0x2C};
|
||||
constexpr static Avr8EdbgParameter DEVICE_UPDI_FLASH_PAGE_SIZE_MSB {0x02, 0x2D};
|
||||
constexpr static Avr8EdbgParameter DEVICE_UPDI_24_BIT_ADDRESSING_ENABLE {0x02, 0x2E};
|
||||
|
||||
constexpr static Avr8EdbgParameter RUN_TIMERS_WHILST_STOPPED {0x03, 0x00};
|
||||
constexpr static Avr8EdbgParameter ENABLE_HIGH_VOLTAGE_UPDI {0x03, 0x06};
|
||||
};
|
||||
|
||||
enum class Avr8ConfigVariant: unsigned char
|
||||
@@ -148,4 +169,12 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
|
||||
DATA = 0x84,
|
||||
FAILED = 0xA0,
|
||||
};
|
||||
|
||||
inline bool operator == (unsigned char rawId, Avr8ResponseId id) {
|
||||
return static_cast<unsigned char>(id) == rawId;
|
||||
}
|
||||
|
||||
inline bool operator == (Avr8ResponseId id, unsigned char rawId) {
|
||||
return rawId == id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,6 +66,408 @@ std::vector<unsigned char> EdbgAvr8Interface::getParameter(const Avr8EdbgParamet
|
||||
return response.getPayloadData();
|
||||
}
|
||||
|
||||
void EdbgAvr8Interface::setDebugWireAndJtagParameters() {
|
||||
if (this->targetParameters.flashPageSize.has_value()) {
|
||||
Logger::debug("Setting DEVICE_FLASH_PAGE_SIZE AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_FLASH_PAGE_SIZE,
|
||||
this->targetParameters.flashPageSize.value()
|
||||
);
|
||||
}
|
||||
|
||||
if (this->targetParameters.flashSize.has_value()) {
|
||||
Logger::debug("Setting DEVICE_FLASH_SIZE AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_FLASH_SIZE,
|
||||
this->targetParameters.flashSize.value()
|
||||
);
|
||||
}
|
||||
|
||||
if (this->targetParameters.flashStartAddress.has_value()) {
|
||||
Logger::debug("Setting DEVICE_FLASH_BASE AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_FLASH_BASE,
|
||||
this->targetParameters.flashStartAddress.value()
|
||||
);
|
||||
}
|
||||
|
||||
if (this->targetParameters.ramStartAddress.has_value()) {
|
||||
Logger::debug("Setting DEVICE_SRAM_START AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_SRAM_START,
|
||||
this->targetParameters.ramStartAddress.value()
|
||||
);
|
||||
}
|
||||
|
||||
if (this->targetParameters.eepromSize.has_value()) {
|
||||
Logger::debug("Setting DEVICE_EEPROM_SIZE AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_EEPROM_SIZE,
|
||||
this->targetParameters.eepromSize.value()
|
||||
);
|
||||
}
|
||||
|
||||
if (this->targetParameters.eepromPageSize.has_value()) {
|
||||
Logger::debug("Setting DEVICE_EEPROM_PAGE_SIZE AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_EEPROM_PAGE_SIZE,
|
||||
this->targetParameters.eepromPageSize.value()
|
||||
);
|
||||
}
|
||||
|
||||
if (this->targetParameters.ocdRevision.has_value()) {
|
||||
Logger::debug("Setting DEVICE_OCD_REVISION AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_OCD_REVISION,
|
||||
this->targetParameters.ocdRevision.value()
|
||||
);
|
||||
}
|
||||
|
||||
if (this->targetParameters.ocdDataRegister.has_value()) {
|
||||
Logger::debug("Setting DEVICE_OCD_DATA_REGISTER AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_OCD_DATA_REGISTER,
|
||||
this->targetParameters.ocdDataRegister.value()
|
||||
);
|
||||
}
|
||||
|
||||
if (this->targetParameters.spmcRegisterStartAddress.has_value()) {
|
||||
Logger::debug("Setting DEVICE_SPMCR_REGISTER AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_SPMCR_REGISTER,
|
||||
this->targetParameters.spmcRegisterStartAddress.value()
|
||||
);
|
||||
}
|
||||
|
||||
if (this->targetParameters.osccalAddress.has_value()) {
|
||||
Logger::debug("Setting DEVICE_OSCCAL_ADDR AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_OSCCAL_ADDR,
|
||||
this->targetParameters.osccalAddress.value()
|
||||
);
|
||||
}
|
||||
|
||||
if (this->targetParameters.eepromAddressRegisterLow.has_value()) {
|
||||
Logger::debug("Setting DEVICE_EEARL_ADDR AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_EEARL_ADDR,
|
||||
this->targetParameters.eepromAddressRegisterLow.value()
|
||||
);
|
||||
}
|
||||
|
||||
if (this->targetParameters.eepromAddressRegisterHigh.has_value()) {
|
||||
Logger::debug("Setting DEVICE_EEARH_ADDR AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_EEARH_ADDR,
|
||||
this->targetParameters.eepromAddressRegisterHigh.value()
|
||||
);
|
||||
}
|
||||
|
||||
if (this->targetParameters.eepromControlRegisterAddress.has_value()) {
|
||||
Logger::debug("Setting DEVICE_EECR_ADDR AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_EECR_ADDR,
|
||||
this->targetParameters.eepromControlRegisterAddress.value()
|
||||
);
|
||||
}
|
||||
|
||||
if (this->targetParameters.eepromDataRegisterAddress.has_value()) {
|
||||
Logger::debug("Setting DEVICE_EEDR_ADDR AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_EEDR_ADDR,
|
||||
this->targetParameters.eepromDataRegisterAddress.value()
|
||||
);
|
||||
}
|
||||
|
||||
if (this->targetParameters.bootSectionStartAddress.has_value()) {
|
||||
Logger::debug("Setting DEVICE_BOOT_START_ADDR AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_BOOT_START_ADDR,
|
||||
this->targetParameters.bootSectionStartAddress.value()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void EdbgAvr8Interface::setPdiParameters() {
|
||||
if (!this->targetParameters.appSectionPdiOffset.has_value()) {
|
||||
throw Exception("Missing required parameter: APPL_BASE_ADDR");
|
||||
}
|
||||
|
||||
if (!this->targetParameters.bootSectionPdiOffset.has_value()) {
|
||||
throw Exception("Missing required parameter: BOOT_BASE_ADDR");
|
||||
}
|
||||
|
||||
if (!this->targetParameters.bootSectionSize.has_value()) {
|
||||
throw Exception("Missing required parameter: BOOT_BYTES");
|
||||
}
|
||||
|
||||
if (!this->targetParameters.flashSize.has_value()) {
|
||||
throw Exception("Missing required parameter: APPLICATION_BYTES");
|
||||
}
|
||||
|
||||
if (!this->targetParameters.eepromPdiOffset.has_value()) {
|
||||
throw Exception("Missing required parameter: EEPROM_BASE_ADDR");
|
||||
}
|
||||
|
||||
if (!this->targetParameters.fuseRegistersPdiOffset.has_value()) {
|
||||
throw Exception("Missing required parameter: FUSE_BASE_ADDR");
|
||||
}
|
||||
|
||||
if (!this->targetParameters.lockRegistersPdiOffset.has_value()) {
|
||||
throw Exception("Missing required parameter: LOCKBIT_BASE_ADDR");
|
||||
}
|
||||
|
||||
if (!this->targetParameters.userSignaturesPdiOffset.has_value()) {
|
||||
throw Exception("Missing required parameter: USER_SIGN_BASE_ADDR");
|
||||
}
|
||||
|
||||
if (!this->targetParameters.productSignaturesPdiOffset.has_value()) {
|
||||
throw Exception("Missing required parameter: PROD_SIGN_BASE_ADDR");
|
||||
}
|
||||
|
||||
if (!this->targetParameters.ramPdiOffset.has_value()) {
|
||||
throw Exception("Missing required parameter: DATA_BASE_ADDR");
|
||||
}
|
||||
|
||||
if (!this->targetParameters.flashPageSize.has_value()) {
|
||||
throw Exception("Missing required parameter: FLASH_PAGE_BYTES");
|
||||
}
|
||||
|
||||
if (!this->targetParameters.eepromSize.has_value()) {
|
||||
throw Exception("Missing required parameter: EEPROM_SIZE");
|
||||
}
|
||||
|
||||
if (!this->targetParameters.eepromPageSize.has_value()) {
|
||||
throw Exception("Missing required parameter: EEPROM_PAGE_SIZE");
|
||||
}
|
||||
|
||||
if (!this->targetParameters.nvmBaseAddress.has_value()) {
|
||||
throw Exception("Missing required parameter: NVM_BASE");
|
||||
}
|
||||
|
||||
Logger::debug("Setting APPL_BASE_ADDR AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_XMEGA_APPL_BASE_ADDR,
|
||||
this->targetParameters.appSectionPdiOffset.value()
|
||||
);
|
||||
|
||||
Logger::debug("Setting BOOT_BASE_ADDR AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_XMEGA_BOOT_BASE_ADDR,
|
||||
this->targetParameters.bootSectionPdiOffset.value()
|
||||
);
|
||||
|
||||
Logger::debug("Setting EEPROM_BASE_ADDR AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_XMEGA_EEPROM_BASE_ADDR,
|
||||
this->targetParameters.eepromPdiOffset.value()
|
||||
);
|
||||
|
||||
Logger::debug("Setting FUSE_BASE_ADDR AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_XMEGA_FUSE_BASE_ADDR,
|
||||
this->targetParameters.fuseRegistersPdiOffset.value()
|
||||
);
|
||||
|
||||
Logger::debug("Setting LOCKBIT_BASE_ADDR AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_XMEGA_LOCKBIT_BASE_ADDR,
|
||||
this->targetParameters.lockRegistersPdiOffset.value()
|
||||
);
|
||||
|
||||
Logger::debug("Setting USER_SIGN_BASE_ADDR AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_XMEGA_USER_SIGN_BASE_ADDR,
|
||||
this->targetParameters.userSignaturesPdiOffset.value()
|
||||
);
|
||||
|
||||
Logger::debug("Setting PROD_SIGN_BASE_ADDR AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_XMEGA_PROD_SIGN_BASE_ADDR,
|
||||
this->targetParameters.productSignaturesPdiOffset.value()
|
||||
);
|
||||
|
||||
Logger::debug("Setting DATA_BASE_ADDR AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_XMEGA_DATA_BASE_ADDR,
|
||||
this->targetParameters.ramPdiOffset.value()
|
||||
);
|
||||
|
||||
Logger::debug("Setting APPLICATION_BYTES AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_XMEGA_APPLICATION_BYTES,
|
||||
this->targetParameters.flashSize.value()
|
||||
);
|
||||
|
||||
Logger::debug("Setting BOOT_BYTES AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_XMEGA_BOOT_BYTES,
|
||||
this->targetParameters.bootSectionSize.value()
|
||||
);
|
||||
|
||||
Logger::debug("Setting FLASH_PAGE_BYTES AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_XMEGA_FLASH_PAGE_BYTES,
|
||||
this->targetParameters.flashPageSize.value()
|
||||
);
|
||||
|
||||
Logger::debug("Setting EEPROM_SIZE AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_XMEGA_EEPROM_SIZE,
|
||||
this->targetParameters.eepromSize.value()
|
||||
);
|
||||
|
||||
Logger::debug("Setting EEPROM_PAGE_SIZE AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_XMEGA_EEPROM_PAGE_SIZE,
|
||||
static_cast<unsigned char>(this->targetParameters.eepromPageSize.value())
|
||||
);
|
||||
|
||||
Logger::debug("Setting NVM_BASE AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_XMEGA_NVM_BASE,
|
||||
this->targetParameters.nvmBaseAddress.value()
|
||||
);
|
||||
}
|
||||
|
||||
void EdbgAvr8Interface::setUpdiParameters() {
|
||||
if (!this->targetParameters.signatureSegmentStartAddress.has_value()) {
|
||||
throw Exception("Missing required parameter: SIGNATURE BASE ADDRESS");
|
||||
}
|
||||
|
||||
if (this->targetParameters.programMemoryUpdiStartAddress.has_value()) {
|
||||
/*
|
||||
* The program memory base address field for UPDI sessions (DEVICE_UPDI_PROGMEM_BASE_ADDR) seems to be limited
|
||||
* to two bytes in size, as opposed to the four byte size for the debugWire, JTAG and PDI equivalent fields.
|
||||
* This is why, I suspect, another field was required for the most significant byte of the program memory base
|
||||
* address (DEVICE_UPDI_PROGMEM_BASE_ADDR_MSB).
|
||||
*
|
||||
* The additional DEVICE_UPDI_PROGMEM_BASE_ADDR_MSB field is only one byte in size, so it brings the total
|
||||
* capacity for the program memory base address to three bytes. Because of this, we ensure that all TDFs, for
|
||||
* targets that support UPDI, specify an address that does not exceed the maximum value of a 24 bit unsigned
|
||||
* integer. This is done in our TDF validation script (see src/Targets/TargetDescription/README.md for more).
|
||||
*/
|
||||
auto programMemBaseAddress = this->targetParameters.programMemoryUpdiStartAddress.value();
|
||||
Logger::debug("Setting DEVICE_UPDI_PROGMEM_BASE_ADDR AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_UPDI_PROGMEM_BASE_ADDR,
|
||||
static_cast<std::uint16_t>(programMemBaseAddress)
|
||||
);
|
||||
|
||||
Logger::debug("Setting DEVICE_UPDI_PROGMEM_BASE_ADDR_MSB AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_UPDI_PROGMEM_BASE_ADDR_MSB,
|
||||
static_cast<std::uint8_t>(programMemBaseAddress >> 16)
|
||||
);
|
||||
}
|
||||
|
||||
if (this->targetParameters.flashPageSize.has_value()) {
|
||||
/*
|
||||
* See the comment above regarding capacity limitations of the DEVICE_UPDI_PROGMEM_BASE_ADDR field.
|
||||
*
|
||||
* The same applies here, for the flash page size field (DEVICE_UPDI_FLASH_PAGE_SIZE).
|
||||
*/
|
||||
auto flashPageSize = this->targetParameters.flashPageSize.value();
|
||||
Logger::debug("Setting DEVICE_UPDI_FLASH_PAGE_SIZE AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_UPDI_FLASH_PAGE_SIZE,
|
||||
static_cast<std::uint8_t>(flashPageSize)
|
||||
);
|
||||
|
||||
Logger::debug("Setting DEVICE_UPDI_FLASH_PAGE_SIZE_MSB AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_UPDI_FLASH_PAGE_SIZE_MSB,
|
||||
static_cast<std::uint8_t>(flashPageSize >> 8)
|
||||
);
|
||||
}
|
||||
|
||||
if (this->targetParameters.eepromPageSize.has_value()) {
|
||||
Logger::debug("Setting DEVICE_UPDI_EEPROM_PAGE_SIZE AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_UPDI_EEPROM_PAGE_SIZE,
|
||||
this->targetParameters.eepromPageSize.value()
|
||||
);
|
||||
}
|
||||
|
||||
if (this->targetParameters.nvmBaseAddress.has_value()) {
|
||||
Logger::debug("Setting DEVICE_UPDI_NVMCTRL_ADDR AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_UPDI_NVMCTRL_ADDR,
|
||||
this->targetParameters.nvmBaseAddress.value()
|
||||
);
|
||||
}
|
||||
|
||||
if (this->targetParameters.ocdModuleAddress.has_value()) {
|
||||
Logger::debug("Setting DEVICE_UPDI_OCD_ADDR AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_UPDI_OCD_ADDR,
|
||||
this->targetParameters.ocdModuleAddress.value()
|
||||
);
|
||||
}
|
||||
|
||||
if (this->targetParameters.flashSize.has_value()) {
|
||||
Logger::debug("Setting DEVICE_UPDI_FLASH_SIZE AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_UPDI_FLASH_SIZE,
|
||||
this->targetParameters.flashSize.value()
|
||||
);
|
||||
}
|
||||
|
||||
if (this->targetParameters.eepromSize.has_value()) {
|
||||
Logger::debug("Setting DEVICE_UPDI_EEPROM_SIZE AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_UPDI_EEPROM_SIZE,
|
||||
this->targetParameters.eepromSize.value()
|
||||
);
|
||||
}
|
||||
|
||||
if (this->targetParameters.eepromStartAddress.has_value()) {
|
||||
Logger::debug("Setting DEVICE_UPDI_EEPROM_BASE_ADDR AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_UPDI_EEPROM_BASE_ADDR,
|
||||
this->targetParameters.eepromStartAddress.value()
|
||||
);
|
||||
}
|
||||
|
||||
if (this->targetParameters.signatureSegmentStartAddress.has_value()) {
|
||||
Logger::debug("Setting DEVICE_UPDI_SIG_BASE_ADDR AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_UPDI_SIG_BASE_ADDR,
|
||||
this->targetParameters.signatureSegmentStartAddress.value()
|
||||
);
|
||||
}
|
||||
|
||||
if (this->targetParameters.fuseSegmentStartAddress.has_value()) {
|
||||
Logger::debug("Setting DEVICE_UPDI_FUSE_BASE_ADDR AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_UPDI_FUSE_BASE_ADDR,
|
||||
this->targetParameters.fuseSegmentStartAddress.value()
|
||||
);
|
||||
}
|
||||
|
||||
if (this->targetParameters.fuseSegmentSize.has_value()) {
|
||||
Logger::debug("Setting DEVICE_UPDI_FUSE_SIZE AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_UPDI_FUSE_SIZE,
|
||||
this->targetParameters.fuseSegmentSize.value()
|
||||
);
|
||||
}
|
||||
|
||||
if (this->targetParameters.lockbitsSegmentStartAddress.has_value()) {
|
||||
Logger::debug("Setting DEVICE_UPDI_LOCK_BASE_ADDR AVR8 parameter");
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_UPDI_LOCK_BASE_ADDR,
|
||||
this->targetParameters.lockbitsSegmentStartAddress.value()
|
||||
);
|
||||
}
|
||||
|
||||
this->setParameter(
|
||||
Avr8EdbgParameters::DEVICE_UPDI_24_BIT_ADDRESSING_ENABLE,
|
||||
this->targetParameters.programMemoryUpdiStartAddress.value_or(0) > 0xFFFF ?
|
||||
static_cast<std::uint8_t>(1) : static_cast<std::uint8_t>(0)
|
||||
);
|
||||
}
|
||||
|
||||
void EdbgAvr8Interface::configure(const TargetConfig& targetConfig) {
|
||||
auto physicalInterface = targetConfig.jsonObject.find("physicalInterface")->toString().toLower().toStdString();
|
||||
|
||||
@@ -124,179 +526,22 @@ void EdbgAvr8Interface::setTargetParameters(const Avr8Bit::TargetParameters& con
|
||||
this->configVariant = configVariant.value();
|
||||
}
|
||||
|
||||
if (this->configVariant == Avr8ConfigVariant::XMEGA) {
|
||||
if (!config.appSectionPdiOffset.has_value()) {
|
||||
throw Exception("Missing required parameter: APPL_BASE_ADDR");
|
||||
switch (this->configVariant) {
|
||||
case Avr8ConfigVariant::DEBUG_WIRE:
|
||||
case Avr8ConfigVariant::MEGAJTAG: {
|
||||
this->setDebugWireAndJtagParameters();
|
||||
break;
|
||||
}
|
||||
|
||||
if (!config.bootSectionPdiOffset.has_value()) {
|
||||
throw Exception("Missing required parameter: BOOT_BASE_ADDR");
|
||||
case Avr8ConfigVariant::XMEGA: {
|
||||
this->setPdiParameters();
|
||||
break;
|
||||
}
|
||||
|
||||
if (!config.bootSectionSize.has_value()) {
|
||||
throw Exception("Missing required parameter: BOOT_BYTES");
|
||||
case Avr8ConfigVariant::UPDI: {
|
||||
this->setUpdiParameters();
|
||||
break;
|
||||
}
|
||||
|
||||
if (!config.flashSize.has_value()) {
|
||||
throw Exception("Missing required parameter: APPLICATION_BYTES");
|
||||
}
|
||||
|
||||
if (!config.eepromPdiOffset.has_value()) {
|
||||
throw Exception("Missing required parameter: EEPROM_BASE_ADDR");
|
||||
}
|
||||
|
||||
if (!config.fuseRegistersPdiOffset.has_value()) {
|
||||
throw Exception("Missing required parameter: FUSE_BASE_ADDR");
|
||||
}
|
||||
|
||||
if (!config.lockRegistersPdiOffset.has_value()) {
|
||||
throw Exception("Missing required parameter: LOCKBIT_BASE_ADDR");
|
||||
}
|
||||
|
||||
if (!config.userSignaturesPdiOffset.has_value()) {
|
||||
throw Exception("Missing required parameter: USER_SIGN_BASE_ADDR");
|
||||
}
|
||||
|
||||
if (!config.productSignaturesPdiOffset.has_value()) {
|
||||
throw Exception("Missing required parameter: PROD_SIGN_BASE_ADDR");
|
||||
}
|
||||
|
||||
if (!config.ramPdiOffset.has_value()) {
|
||||
throw Exception("Missing required parameter: DATA_BASE_ADDR");
|
||||
}
|
||||
|
||||
if (!config.flashPageSize.has_value()) {
|
||||
throw Exception("Missing required parameter: FLASH_PAGE_BYTES");
|
||||
}
|
||||
|
||||
if (!config.eepromSize.has_value()) {
|
||||
throw Exception("Missing required parameter: EEPROM_SIZE");
|
||||
}
|
||||
|
||||
if (!config.eepromPageSize.has_value()) {
|
||||
throw Exception("Missing required parameter: EEPROM_PAGE_SIZE");
|
||||
}
|
||||
|
||||
if (!config.nvmBaseAddress.has_value()) {
|
||||
throw Exception("Missing required parameter: NVM_BASE");
|
||||
}
|
||||
|
||||
Logger::debug("Setting APPL_BASE_ADDR AVR8 parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_APPL_BASE_ADDR, config.appSectionPdiOffset.value());
|
||||
|
||||
Logger::debug("Setting BOOT_BASE_ADDR AVR8 parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_BOOT_BASE_ADDR, config.bootSectionPdiOffset.value());
|
||||
|
||||
Logger::debug("Setting EEPROM_BASE_ADDR AVR8 parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_EEPROM_BASE_ADDR, config.eepromPdiOffset.value());
|
||||
|
||||
Logger::debug("Setting FUSE_BASE_ADDR AVR8 parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_FUSE_BASE_ADDR, config.fuseRegistersPdiOffset.value());
|
||||
|
||||
Logger::debug("Setting LOCKBIT_BASE_ADDR AVR8 parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_LOCKBIT_BASE_ADDR, config.lockRegistersPdiOffset.value());
|
||||
|
||||
Logger::debug("Setting USER_SIGN_BASE_ADDR AVR8 parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_USER_SIGN_BASE_ADDR, config.userSignaturesPdiOffset.value());
|
||||
|
||||
Logger::debug("Setting PROD_SIGN_BASE_ADDR AVR8 parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_PROD_SIGN_BASE_ADDR, config.productSignaturesPdiOffset.value());
|
||||
|
||||
Logger::debug("Setting DATA_BASE_ADDR AVR8 parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_DATA_BASE_ADDR, config.ramPdiOffset.value());
|
||||
|
||||
Logger::debug("Setting APPLICATION_BYTES AVR8 parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_APPLICATION_BYTES, config.flashSize.value());
|
||||
|
||||
Logger::debug("Setting BOOT_BYTES AVR8 parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_BOOT_BYTES, config.bootSectionSize.value());
|
||||
|
||||
Logger::debug("Setting FLASH_PAGE_BYTES AVR8 parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_FLASH_PAGE_BYTES, config.flashPageSize.value());
|
||||
|
||||
Logger::debug("Setting EEPROM_SIZE AVR8 parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_EEPROM_SIZE, config.eepromSize.value());
|
||||
|
||||
Logger::debug("Setting EEPROM_PAGE_SIZE AVR8 parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_EEPROM_PAGE_SIZE, static_cast<unsigned char>(config.eepromPageSize.value()));
|
||||
|
||||
Logger::debug("Setting NVM_BASE AVR8 parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_NVM_BASE, config.nvmBaseAddress.value());
|
||||
|
||||
} else {
|
||||
if (config.flashPageSize.has_value()) {
|
||||
Logger::debug("Setting DEVICE_FLASH_PAGE_SIZE AVR8 parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_FLASH_PAGE_SIZE, config.flashPageSize.value());
|
||||
}
|
||||
|
||||
if (config.flashSize.has_value()) {
|
||||
Logger::debug("Setting DEVICE_FLASH_SIZE AVR8 parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_FLASH_SIZE, config.flashSize.value());
|
||||
}
|
||||
|
||||
if (config.flashStartAddress.has_value()) {
|
||||
Logger::debug("Setting DEVICE_FLASH_BASE AVR8 parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_FLASH_BASE, config.flashStartAddress.value());
|
||||
}
|
||||
|
||||
if (config.ramStartAddress.has_value()) {
|
||||
Logger::debug("Setting DEVICE_SRAM_START AVR8 parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_SRAM_START, config.ramStartAddress.value());
|
||||
}
|
||||
|
||||
if (config.eepromSize.has_value()) {
|
||||
Logger::debug("Setting DEVICE_EEPROM_SIZE AVR8 parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_EEPROM_SIZE, config.eepromSize.value());
|
||||
}
|
||||
|
||||
if (config.eepromPageSize.has_value()) {
|
||||
Logger::debug("Setting DEVICE_EEPROM_PAGE_SIZE AVR8 parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_EEPROM_PAGE_SIZE, config.eepromPageSize.value());
|
||||
}
|
||||
|
||||
if (config.ocdRevision.has_value()) {
|
||||
Logger::debug("Setting DEVICE_OCD_REVISION AVR8 parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_OCD_REVISION, config.ocdRevision.value());
|
||||
}
|
||||
|
||||
if (config.ocdDataRegister.has_value()) {
|
||||
Logger::debug("Setting DEVICE_OCD_DATA_REGISTER AVR8 parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_OCD_DATA_REGISTER, config.ocdDataRegister.value());
|
||||
}
|
||||
|
||||
if (config.spmcRegisterStartAddress.has_value()) {
|
||||
Logger::debug("Setting DEVICE_SPMCR_REGISTER AVR8 parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_SPMCR_REGISTER, config.spmcRegisterStartAddress.value());
|
||||
}
|
||||
|
||||
if (config.osccalAddress.has_value()) {
|
||||
Logger::debug("Setting DEVICE_OSCCAL_ADDR AVR8 parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_OSCCAL_ADDR, config.osccalAddress.value());
|
||||
}
|
||||
|
||||
if (config.eepromAddressRegisterLow.has_value()) {
|
||||
Logger::debug("Setting DEVICE_EEARL_ADDR AVR8 parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_EEARL_ADDR, config.eepromAddressRegisterLow.value());
|
||||
}
|
||||
|
||||
if (config.eepromAddressRegisterHigh.has_value()) {
|
||||
Logger::debug("Setting DEVICE_EEARH_ADDR AVR8 parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_EEARH_ADDR, config.eepromAddressRegisterHigh.value());
|
||||
}
|
||||
|
||||
if (config.eepromControlRegisterAddress.has_value()) {
|
||||
Logger::debug("Setting DEVICE_EECR_ADDR AVR8 parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_EECR_ADDR, config.eepromControlRegisterAddress.value());
|
||||
}
|
||||
|
||||
if (config.eepromDataRegisterAddress.has_value()) {
|
||||
Logger::debug("Setting DEVICE_EEDR_ADDR AVR8 parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_EEDR_ADDR, config.eepromDataRegisterAddress.value());
|
||||
}
|
||||
|
||||
if (config.bootSectionStartAddress.has_value()) {
|
||||
Logger::debug("Setting DEVICE_BOOT_START_ADDR AVR8 parameter");
|
||||
this->setParameter(Avr8EdbgParameters::DEVICE_BOOT_START_ADDR, config.bootSectionStartAddress.value());
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -305,7 +550,13 @@ void EdbgAvr8Interface::init() {
|
||||
if (this->configVariant == Avr8ConfigVariant::XMEGA) {
|
||||
// Default PDI clock to 4MHz
|
||||
// TODO: Make this adjustable via a target config parameter
|
||||
this->setParameter(Avr8EdbgParameters::XMEGA_PDI_CLOCK, static_cast<std::uint16_t>(0x0FA0));
|
||||
this->setParameter(Avr8EdbgParameters::PDI_CLOCK_SPEED, static_cast<std::uint16_t>(0x0FA0));
|
||||
}
|
||||
|
||||
if (this->configVariant == Avr8ConfigVariant::UPDI) {
|
||||
// Default UPDI clock to 1.8MHz
|
||||
this->setParameter(Avr8EdbgParameters::PDI_CLOCK_SPEED, static_cast<std::uint16_t>(0x0708));
|
||||
this->setParameter(Avr8EdbgParameters::ENABLE_HIGH_VOLTAGE_UPDI, static_cast<unsigned char>(0x00));
|
||||
}
|
||||
|
||||
if (this->configVariant == Avr8ConfigVariant::MEGAJTAG) {
|
||||
|
||||
@@ -14,14 +14,6 @@
|
||||
|
||||
namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
|
||||
{
|
||||
inline bool operator==(unsigned char rawId, Avr8ResponseId id) {
|
||||
return static_cast<unsigned char>(id) == rawId;
|
||||
}
|
||||
|
||||
inline bool operator==(Avr8ResponseId id, unsigned char rawId) {
|
||||
return rawId == id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The EdbgAvr8Interface implements the AVR8 Generic EDBG/CMSIS-DAP protocol, as an Avr8Interface.
|
||||
*
|
||||
@@ -291,6 +283,27 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
|
||||
*/
|
||||
std::vector<unsigned char> getParameter(const Avr8EdbgParameter& parameter, std::uint8_t size);
|
||||
|
||||
/**
|
||||
* EDBG-based debug tools require target specific parameters such as memory locations, page sizes and
|
||||
* 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.
|
||||
* For target parameters, the address (ID) of the parameter also varies across config variants. This is why
|
||||
* we sometimes have separate parameters for sending the same data, where they differ only in parameter IDs.
|
||||
* For example, the Avr8EdbgParameters::DEVICE_FLASH_BASE parameter is used to send the base address for
|
||||
* the target's flash memory segment. The parameter is assigned an address (ID) of 0x06. But the
|
||||
* Avr8EdbgParameters::DEVICE_UPDI_PROG_BASE is used to send the same data (base address of the target's flash
|
||||
* segment), but only for sessions with the UPDI physical interface. The address is 0x00.
|
||||
*
|
||||
* - 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.
|
||||
* - The setPdiParameters() function sends the required target parameters for PDI sessions.
|
||||
* - The setUpdiParameters() function sends the required target parameters for UPDI sessions.
|
||||
*/
|
||||
void setDebugWireAndJtagParameters();
|
||||
void setPdiParameters();
|
||||
void setUpdiParameters();
|
||||
|
||||
/**
|
||||
* Sends the "Activate Physical" command to the debug tool, activating the physical interface and thus enabling
|
||||
* communication between the debug tool and the target.
|
||||
|
||||
Reference in New Issue
Block a user