Added EDBG parameter structs with TDF-based initialisation
This commit is contained in:
@@ -19,6 +19,9 @@ target_sources(
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/Microchip/Protocols/EDBG/AVR/ResponseFrames/EDBGControl/EdbgControlResponseFrame.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/Microchip/Protocols/EDBG/AVR/ResponseFrames/EDBGControl/EdbgControlResponseFrame.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/Microchip/Protocols/EDBG/AVR/AvrEvent.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/Microchip/Protocols/EDBG/AVR/AvrEvent.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/Microchip/Protocols/EDBG/AVR/Events/AVR8Generic/BreakEvent.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/Microchip/Protocols/EDBG/AVR/Events/AVR8Generic/BreakEvent.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/Microchip/Protocols/EDBG/AVR/Parameters/AVR8Generic/DebugWireJtagParameters.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/Microchip/Protocols/EDBG/AVR/Parameters/AVR8Generic/PdiParameters.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/EdbgAvr8Interface.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/Microchip/Protocols/EDBG/AVR/EdbgAvr8Interface.cpp
|
||||||
|
|||||||
@@ -39,6 +39,10 @@
|
|||||||
#include "CommandFrames/AVR8Generic/LeaveProgrammingMode.hpp"
|
#include "CommandFrames/AVR8Generic/LeaveProgrammingMode.hpp"
|
||||||
#include "CommandFrames/AVR8Generic/EraseMemory.hpp"
|
#include "CommandFrames/AVR8Generic/EraseMemory.hpp"
|
||||||
|
|
||||||
|
#include "Parameters/AVR8Generic/DebugWireJtagParameters.hpp"
|
||||||
|
#include "Parameters/AVR8Generic/PdiParameters.hpp"
|
||||||
|
#include "Parameters/AVR8Generic/UpdiParameters.hpp"
|
||||||
|
|
||||||
// AVR events
|
// AVR events
|
||||||
#include "Events/AVR8Generic/BreakEvent.hpp"
|
#include "Events/AVR8Generic/BreakEvent.hpp"
|
||||||
|
|
||||||
@@ -1048,447 +1052,205 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EdbgAvr8Interface::setDebugWireAndJtagParameters() {
|
void EdbgAvr8Interface::setDebugWireAndJtagParameters() {
|
||||||
if (this->targetParameters.flashPageSize.has_value()) {
|
const auto parameters = Parameters::Avr8Generic::DebugWireJtagParameters(this->targetDescriptionFile);
|
||||||
Logger::debug("Setting FLASH_PAGE_SIZE AVR8 device parameter");
|
|
||||||
this->setParameter(
|
|
||||||
Avr8EdbgParameters::DEVICE_FLASH_PAGE_SIZE,
|
|
||||||
this->targetParameters.flashPageSize.value()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->targetParameters.flashSize.has_value()) {
|
Logger::debug("Setting FLASH_PAGE_SIZE AVR8 device parameter");
|
||||||
Logger::debug("Setting FLASH_SIZE AVR8 device parameter");
|
this->setParameter(Avr8EdbgParameters::DEVICE_FLASH_PAGE_SIZE, parameters.flashPageSize);
|
||||||
this->setParameter(
|
|
||||||
Avr8EdbgParameters::DEVICE_FLASH_SIZE,
|
|
||||||
this->targetParameters.flashSize.value()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->targetParameters.flashStartAddress.has_value()) {
|
Logger::debug("Setting FLASH_SIZE AVR8 device parameter");
|
||||||
Logger::debug("Setting FLASH_BASE AVR8 device parameter");
|
this->setParameter(Avr8EdbgParameters::DEVICE_FLASH_SIZE, parameters.flashSize);
|
||||||
this->setParameter(
|
|
||||||
Avr8EdbgParameters::DEVICE_FLASH_BASE,
|
|
||||||
this->targetParameters.flashStartAddress.value()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->targetParameters.ramStartAddress.has_value()) {
|
Logger::debug("Setting FLASH_BASE AVR8 device parameter");
|
||||||
Logger::debug("Setting SRAM_START AVR8 device parameter");
|
this->setParameter(Avr8EdbgParameters::DEVICE_FLASH_BASE, parameters.flashStartWordAddress);
|
||||||
this->setParameter(
|
|
||||||
Avr8EdbgParameters::DEVICE_SRAM_START,
|
|
||||||
this->targetParameters.ramStartAddress.value()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->targetParameters.eepromSize.has_value()) {
|
if (parameters.bootSectionStartWordAddress.has_value()) {
|
||||||
Logger::debug("Setting EEPROM_SIZE AVR8 device parameter");
|
|
||||||
this->setParameter(
|
|
||||||
Avr8EdbgParameters::DEVICE_EEPROM_SIZE,
|
|
||||||
this->targetParameters.eepromSize.value()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->targetParameters.eepromPageSize.has_value()) {
|
|
||||||
Logger::debug("Setting EEPROM_PAGE_SIZE AVR8 device parameter");
|
|
||||||
this->setParameter(
|
|
||||||
Avr8EdbgParameters::DEVICE_EEPROM_PAGE_SIZE,
|
|
||||||
this->targetParameters.eepromPageSize.value()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->targetParameters.ocdRevision.has_value()) {
|
|
||||||
Logger::debug("Setting OCD_REVISION AVR8 device parameter");
|
|
||||||
this->setParameter(
|
|
||||||
Avr8EdbgParameters::DEVICE_OCD_REVISION,
|
|
||||||
this->targetParameters.ocdRevision.value()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->targetParameters.ocdDataRegister.has_value()) {
|
|
||||||
Logger::debug("Setting OCD_DATA_REGISTER AVR8 device parameter");
|
|
||||||
this->setParameter(
|
|
||||||
Avr8EdbgParameters::DEVICE_OCD_DATA_REGISTER,
|
|
||||||
this->targetParameters.ocdDataRegister.value()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->targetParameters.spmcRegisterStartAddress.has_value()) {
|
|
||||||
Logger::debug("Setting SPMCR_REGISTER AVR8 device parameter");
|
|
||||||
this->setParameter(
|
|
||||||
Avr8EdbgParameters::DEVICE_SPMCR_REGISTER,
|
|
||||||
this->targetParameters.spmcRegisterStartAddress.value()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->targetParameters.bootSectionStartAddress.has_value()) {
|
|
||||||
Logger::debug("Setting BOOT_START_ADDR AVR8 device parameter");
|
Logger::debug("Setting BOOT_START_ADDR AVR8 device parameter");
|
||||||
this->setParameter(
|
this->setParameter(Avr8EdbgParameters::DEVICE_BOOT_START_ADDR, *(parameters.bootSectionStartWordAddress));
|
||||||
Avr8EdbgParameters::DEVICE_BOOT_START_ADDR,
|
|
||||||
this->targetParameters.bootSectionStartAddress.value()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
Logger::debug("Setting SRAM_START AVR8 device parameter");
|
||||||
* All addresses for registers that reside in the mapped IO memory segment include the mapped IO segment offset
|
this->setParameter(Avr8EdbgParameters::DEVICE_SRAM_START, parameters.ramStartAddress);
|
||||||
* (start address). But the EDBG protocol requires *some* of these addresses to be stripped of this offset
|
|
||||||
* before sending them as target parameters.
|
|
||||||
*
|
|
||||||
* This applies to the following addresses:
|
|
||||||
*
|
|
||||||
* - OSCALL Address
|
|
||||||
* - EEARL Address
|
|
||||||
* - EEARH Address
|
|
||||||
* - EECR Address
|
|
||||||
* - EEDR Address
|
|
||||||
*
|
|
||||||
* It *doesn't* seem to apply to the SPMCR or OCDDR address.
|
|
||||||
*/
|
|
||||||
auto mappedIoStartAddress = this->targetParameters.mappedIoSegmentStartAddress.value_or(0);
|
|
||||||
|
|
||||||
if (this->targetParameters.osccalAddress.has_value()) {
|
Logger::debug("Setting EEPROM_SIZE AVR8 device parameter");
|
||||||
Logger::debug("Setting OSCCAL_ADDR AVR8 device parameter");
|
this->setParameter(Avr8EdbgParameters::DEVICE_EEPROM_SIZE, parameters.eepromSize);
|
||||||
this->setParameter(
|
|
||||||
Avr8EdbgParameters::DEVICE_OSCCAL_ADDR,
|
|
||||||
static_cast<std::uint8_t>(
|
|
||||||
this->targetParameters.osccalAddress.value() - mappedIoStartAddress
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->targetParameters.eepromAddressRegisterLow.has_value()) {
|
Logger::debug("Setting EEPROM_PAGE_SIZE AVR8 device parameter");
|
||||||
Logger::debug("Setting EEARL_ADDR AVR8 device parameter");
|
this->setParameter(Avr8EdbgParameters::DEVICE_EEPROM_PAGE_SIZE, parameters.eepromPageSize);
|
||||||
this->setParameter(
|
|
||||||
Avr8EdbgParameters::DEVICE_EEARL_ADDR,
|
|
||||||
static_cast<std::uint8_t>(
|
|
||||||
this->targetParameters.eepromAddressRegisterLow.value() - mappedIoStartAddress
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->targetParameters.eepromAddressRegisterHigh.has_value()) {
|
Logger::debug("Setting OCD_REVISION AVR8 device parameter");
|
||||||
Logger::debug("Setting EEARH_ADDR AVR8 device parameter");
|
this->setParameter(Avr8EdbgParameters::DEVICE_OCD_REVISION, parameters.ocdRevision);
|
||||||
this->setParameter(
|
|
||||||
Avr8EdbgParameters::DEVICE_EEARH_ADDR,
|
|
||||||
static_cast<std::uint8_t>(
|
|
||||||
this->targetParameters.eepromAddressRegisterHigh.value() - mappedIoStartAddress
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->targetParameters.eepromControlRegisterAddress.has_value()) {
|
Logger::debug("Setting OCD_DATA_REGISTER AVR8 device parameter");
|
||||||
Logger::debug("Setting EECR_ADDR AVR8 device parameter");
|
this->setParameter(Avr8EdbgParameters::DEVICE_OCD_DATA_REGISTER, parameters.ocdDataRegister);
|
||||||
this->setParameter(
|
|
||||||
Avr8EdbgParameters::DEVICE_EECR_ADDR,
|
|
||||||
static_cast<std::uint8_t>(
|
|
||||||
this->targetParameters.eepromControlRegisterAddress.value() - mappedIoStartAddress
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->targetParameters.eepromDataRegisterAddress.has_value()) {
|
Logger::debug("Setting EEARL_ADDR AVR8 device parameter");
|
||||||
Logger::debug("Setting EEDR_ADDR AVR8 device parameter");
|
this->setParameter(Avr8EdbgParameters::DEVICE_EEARL_ADDR, parameters.eepromAddressRegisterLow);
|
||||||
this->setParameter(
|
|
||||||
Avr8EdbgParameters::DEVICE_EEDR_ADDR,
|
Logger::debug("Setting EEARH_ADDR AVR8 device parameter");
|
||||||
static_cast<std::uint8_t>(
|
this->setParameter(Avr8EdbgParameters::DEVICE_EEARH_ADDR, parameters.eepromAddressRegisterHigh);
|
||||||
this->targetParameters.eepromDataRegisterAddress.value() - mappedIoStartAddress
|
|
||||||
)
|
Logger::debug("Setting EECR_ADDR AVR8 device parameter");
|
||||||
);
|
this->setParameter(Avr8EdbgParameters::DEVICE_EECR_ADDR, parameters.eepromControlRegisterAddress);
|
||||||
}
|
|
||||||
|
Logger::debug("Setting EEDR_ADDR AVR8 device parameter");
|
||||||
|
this->setParameter(Avr8EdbgParameters::DEVICE_EEDR_ADDR, parameters.eepromDataRegisterAddress);
|
||||||
|
|
||||||
|
Logger::debug("Setting SPMCR_REGISTER AVR8 device parameter");
|
||||||
|
this->setParameter(Avr8EdbgParameters::DEVICE_SPMCR_REGISTER, parameters.spmcRegisterStartAddress);
|
||||||
|
|
||||||
|
Logger::debug("Setting OSCCAL_ADDR AVR8 device parameter");
|
||||||
|
this->setParameter(Avr8EdbgParameters::DEVICE_OSCCAL_ADDR, parameters.osccalAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EdbgAvr8Interface::setPdiParameters() {
|
void EdbgAvr8Interface::setPdiParameters() {
|
||||||
if (!this->targetParameters.appSectionPdiOffset.has_value()) {
|
const auto parameters = Parameters::Avr8Generic::PdiParameters(this->targetDescriptionFile);
|
||||||
throw DeviceInitializationFailure("Missing required parameter: APPL_BASE_ADDR");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this->targetParameters.bootSectionPdiOffset.has_value()) {
|
|
||||||
throw DeviceInitializationFailure("Missing required parameter: BOOT_BASE_ADDR");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this->targetParameters.appSectionSize.has_value()) {
|
|
||||||
throw DeviceInitializationFailure("Missing required parameter: APPLICATION_BYTES");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this->targetParameters.bootSectionSize.has_value()) {
|
|
||||||
throw DeviceInitializationFailure("Missing required parameter: BOOT_BYTES");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this->targetParameters.eepromPdiOffset.has_value()) {
|
|
||||||
throw DeviceInitializationFailure("Missing required parameter: EEPROM_BASE_ADDR");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this->targetParameters.fuseRegistersPdiOffset.has_value()) {
|
|
||||||
throw DeviceInitializationFailure("Missing required parameter: FUSE_BASE_ADDR");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this->targetParameters.lockRegistersPdiOffset.has_value()) {
|
|
||||||
throw DeviceInitializationFailure("Missing required parameter: LOCKBIT_BASE_ADDR");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this->targetParameters.userSignaturesPdiOffset.has_value()) {
|
|
||||||
throw DeviceInitializationFailure("Missing required parameter: USER_SIGN_BASE_ADDR");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this->targetParameters.productSignaturesPdiOffset.has_value()) {
|
|
||||||
throw DeviceInitializationFailure("Missing required parameter: PROD_SIGN_BASE_ADDR");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this->targetParameters.ramPdiOffset.has_value()) {
|
|
||||||
throw DeviceInitializationFailure("Missing required parameter: DATA_BASE_ADDR");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this->targetParameters.flashPageSize.has_value()) {
|
|
||||||
throw DeviceInitializationFailure("Missing required parameter: FLASH_PAGE_BYTES");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this->targetParameters.eepromSize.has_value()) {
|
|
||||||
throw DeviceInitializationFailure("Missing required parameter: EEPROM_SIZE");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this->targetParameters.eepromPageSize.has_value()) {
|
|
||||||
throw DeviceInitializationFailure("Missing required parameter: EEPROM_PAGE_SIZE");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this->targetParameters.nvmModuleBaseAddress.has_value()) {
|
|
||||||
throw DeviceInitializationFailure("Missing required parameter: NVM_BASE");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this->targetParameters.mcuModuleBaseAddress.has_value()) {
|
|
||||||
throw DeviceInitializationFailure("Missing required parameter: SIGNATURE_OFFSET (MCU module base address)");
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger::debug("Setting APPL_BASE_ADDR AVR8 parameter");
|
Logger::debug("Setting APPL_BASE_ADDR AVR8 parameter");
|
||||||
this->setParameter(
|
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_APPL_BASE_ADDR, parameters.appSectionPdiOffset);
|
||||||
Avr8EdbgParameters::DEVICE_XMEGA_APPL_BASE_ADDR,
|
|
||||||
this->targetParameters.appSectionPdiOffset.value()
|
|
||||||
);
|
|
||||||
|
|
||||||
Logger::debug("Setting BOOT_BASE_ADDR AVR8 parameter");
|
Logger::debug("Setting BOOT_BASE_ADDR AVR8 parameter");
|
||||||
this->setParameter(
|
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_BOOT_BASE_ADDR, parameters.bootSectionPdiOffset);
|
||||||
Avr8EdbgParameters::DEVICE_XMEGA_BOOT_BASE_ADDR,
|
|
||||||
this->targetParameters.bootSectionPdiOffset.value()
|
|
||||||
);
|
|
||||||
|
|
||||||
Logger::debug("Setting EEPROM_BASE_ADDR AVR8 parameter");
|
Logger::debug("Setting EEPROM_BASE_ADDR AVR8 parameter");
|
||||||
this->setParameter(
|
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_EEPROM_BASE_ADDR, parameters.eepromPdiOffset);
|
||||||
Avr8EdbgParameters::DEVICE_XMEGA_EEPROM_BASE_ADDR,
|
|
||||||
this->targetParameters.eepromPdiOffset.value()
|
|
||||||
);
|
|
||||||
|
|
||||||
Logger::debug("Setting FUSE_BASE_ADDR AVR8 parameter");
|
Logger::debug("Setting FUSE_BASE_ADDR AVR8 parameter");
|
||||||
this->setParameter(
|
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_FUSE_BASE_ADDR, parameters.fuseRegistersPdiOffset);
|
||||||
Avr8EdbgParameters::DEVICE_XMEGA_FUSE_BASE_ADDR,
|
|
||||||
this->targetParameters.fuseRegistersPdiOffset.value()
|
|
||||||
);
|
|
||||||
|
|
||||||
Logger::debug("Setting LOCKBIT_BASE_ADDR AVR8 parameter");
|
Logger::debug("Setting LOCKBIT_BASE_ADDR AVR8 parameter");
|
||||||
this->setParameter(
|
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_LOCKBIT_BASE_ADDR, parameters.lockRegistersPdiOffset);
|
||||||
Avr8EdbgParameters::DEVICE_XMEGA_LOCKBIT_BASE_ADDR,
|
|
||||||
this->targetParameters.lockRegistersPdiOffset.value()
|
|
||||||
);
|
|
||||||
|
|
||||||
Logger::debug("Setting USER_SIGN_BASE_ADDR AVR8 parameter");
|
Logger::debug("Setting USER_SIGN_BASE_ADDR AVR8 parameter");
|
||||||
this->setParameter(
|
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_USER_SIGN_BASE_ADDR, parameters.userSignaturesPdiOffset);
|
||||||
Avr8EdbgParameters::DEVICE_XMEGA_USER_SIGN_BASE_ADDR,
|
|
||||||
this->targetParameters.userSignaturesPdiOffset.value()
|
|
||||||
);
|
|
||||||
|
|
||||||
Logger::debug("Setting PROD_SIGN_BASE_ADDR AVR8 parameter");
|
Logger::debug("Setting PROD_SIGN_BASE_ADDR AVR8 parameter");
|
||||||
this->setParameter(
|
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_PROD_SIGN_BASE_ADDR, parameters.prodSignaturesPdiOffset);
|
||||||
Avr8EdbgParameters::DEVICE_XMEGA_PROD_SIGN_BASE_ADDR,
|
|
||||||
this->targetParameters.productSignaturesPdiOffset.value()
|
|
||||||
);
|
|
||||||
|
|
||||||
Logger::debug("Setting DATA_BASE_ADDR AVR8 parameter");
|
Logger::debug("Setting DATA_BASE_ADDR AVR8 parameter");
|
||||||
this->setParameter(
|
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_DATA_BASE_ADDR, parameters.ramPdiOffset);
|
||||||
Avr8EdbgParameters::DEVICE_XMEGA_DATA_BASE_ADDR,
|
|
||||||
this->targetParameters.ramPdiOffset.value()
|
|
||||||
);
|
|
||||||
|
|
||||||
Logger::debug("Setting APPLICATION_BYTES AVR8 parameter");
|
Logger::debug("Setting APPLICATION_BYTES AVR8 parameter");
|
||||||
this->setParameter(
|
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_APPLICATION_BYTES, parameters.appSectionSize);
|
||||||
Avr8EdbgParameters::DEVICE_XMEGA_APPLICATION_BYTES,
|
|
||||||
this->targetParameters.appSectionSize.value()
|
|
||||||
);
|
|
||||||
|
|
||||||
Logger::debug("Setting BOOT_BYTES AVR8 parameter");
|
Logger::debug("Setting BOOT_BYTES AVR8 parameter");
|
||||||
this->setParameter(
|
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_BOOT_BYTES, parameters.bootSectionSize);
|
||||||
Avr8EdbgParameters::DEVICE_XMEGA_BOOT_BYTES,
|
|
||||||
this->targetParameters.bootSectionSize.value()
|
|
||||||
);
|
|
||||||
|
|
||||||
Logger::debug("Setting FLASH_PAGE_BYTES AVR8 parameter");
|
Logger::debug("Setting FLASH_PAGE_BYTES AVR8 parameter");
|
||||||
this->setParameter(
|
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_FLASH_PAGE_BYTES, parameters.flashPageSize);
|
||||||
Avr8EdbgParameters::DEVICE_XMEGA_FLASH_PAGE_BYTES,
|
|
||||||
this->targetParameters.flashPageSize.value()
|
|
||||||
);
|
|
||||||
|
|
||||||
Logger::debug("Setting EEPROM_SIZE AVR8 parameter");
|
Logger::debug("Setting EEPROM_SIZE AVR8 parameter");
|
||||||
this->setParameter(
|
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_EEPROM_SIZE, parameters.eepromSize);
|
||||||
Avr8EdbgParameters::DEVICE_XMEGA_EEPROM_SIZE,
|
|
||||||
this->targetParameters.eepromSize.value()
|
|
||||||
);
|
|
||||||
|
|
||||||
Logger::debug("Setting EEPROM_PAGE_SIZE AVR8 parameter");
|
Logger::debug("Setting EEPROM_PAGE_SIZE AVR8 parameter");
|
||||||
this->setParameter(
|
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_EEPROM_PAGE_SIZE, parameters.eepromPageSize);
|
||||||
Avr8EdbgParameters::DEVICE_XMEGA_EEPROM_PAGE_SIZE,
|
|
||||||
static_cast<std::uint8_t>(this->targetParameters.eepromPageSize.value())
|
|
||||||
);
|
|
||||||
|
|
||||||
Logger::debug("Setting NVM_BASE AVR8 parameter");
|
Logger::debug("Setting NVM_BASE AVR8 parameter");
|
||||||
this->setParameter(
|
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_NVM_BASE, parameters.nvmModuleBaseAddress);
|
||||||
Avr8EdbgParameters::DEVICE_XMEGA_NVM_BASE,
|
|
||||||
this->targetParameters.nvmModuleBaseAddress.value()
|
|
||||||
);
|
|
||||||
|
|
||||||
Logger::debug("Setting SIGNATURE_OFFSET AVR8 parameter");
|
Logger::debug("Setting SIGNATURE_OFFSET AVR8 parameter");
|
||||||
this->setParameter(
|
this->setParameter(Avr8EdbgParameters::DEVICE_XMEGA_SIGNATURE_OFFSET, parameters.signaturesPdiOffset);
|
||||||
Avr8EdbgParameters::DEVICE_XMEGA_SIGNATURE_OFFSET,
|
|
||||||
this->targetParameters.mcuModuleBaseAddress.value()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EdbgAvr8Interface::setUpdiParameters() {
|
void EdbgAvr8Interface::setUpdiParameters() {
|
||||||
if (!this->targetParameters.signatureSegmentStartAddress.has_value()) {
|
const auto parameters = Parameters::Avr8Generic::UpdiParameters(this->targetDescriptionFile);
|
||||||
throw DeviceInitializationFailure("Missing required parameter: SIGNATURE BASE ADDRESS");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this->targetParameters.eepromPageSize.has_value()) {
|
/*
|
||||||
throw DeviceInitializationFailure("Missing required parameter: UPDI_EEPROM_PAGE_SIZE");
|
* 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).
|
||||||
|
*/
|
||||||
|
Logger::debug("Setting UPDI_PROGMEM_BASE_ADDR AVR8 device parameter");
|
||||||
|
this->setParameter(
|
||||||
|
Avr8EdbgParameters::DEVICE_UPDI_PROGMEM_BASE_ADDR,
|
||||||
|
static_cast<std::uint16_t>(parameters.programMemoryStartAddress)
|
||||||
|
);
|
||||||
|
|
||||||
if (this->targetParameters.programMemoryUpdiStartAddress.has_value()) {
|
Logger::debug("Setting UPDI_PROGMEM_BASE_ADDR_MSB AVR8 device parameter");
|
||||||
/*
|
this->setParameter(
|
||||||
* The program memory base address field for UPDI sessions (DEVICE_UPDI_PROGMEM_BASE_ADDR) seems to be
|
Avr8EdbgParameters::DEVICE_UPDI_PROGMEM_BASE_ADDR_MSB,
|
||||||
* limited to two bytes in size, as opposed to the four byte size for the debugWire, JTAG and PDI
|
static_cast<std::uint8_t>(parameters.programMemoryStartAddress >> 16)
|
||||||
* 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).
|
|
||||||
*/
|
|
||||||
const auto programMemBaseAddress = this->targetParameters.programMemoryUpdiStartAddress.value();
|
|
||||||
Logger::debug("Setting UPDI_PROGMEM_BASE_ADDR AVR8 device parameter");
|
|
||||||
this->setParameter(
|
|
||||||
Avr8EdbgParameters::DEVICE_UPDI_PROGMEM_BASE_ADDR,
|
|
||||||
static_cast<std::uint16_t>(programMemBaseAddress)
|
|
||||||
);
|
|
||||||
|
|
||||||
Logger::debug("Setting UPDI_PROGMEM_BASE_ADDR_MSB AVR8 device parameter");
|
this->setParameter(
|
||||||
this->setParameter(
|
Avr8EdbgParameters::DEVICE_UPDI_24_BIT_ADDRESSING_ENABLE,
|
||||||
Avr8EdbgParameters::DEVICE_UPDI_PROGMEM_BASE_ADDR_MSB,
|
parameters.programMemoryStartAddress > 0xFFFF
|
||||||
static_cast<std::uint8_t>(programMemBaseAddress >> 16)
|
? static_cast<std::uint8_t>(1)
|
||||||
);
|
: static_cast<std::uint8_t>(0)
|
||||||
}
|
);
|
||||||
|
|
||||||
if (this->targetParameters.flashPageSize.has_value()) {
|
/*
|
||||||
/*
|
* See the comment above regarding capacity limitations of the DEVICE_UPDI_PROGMEM_BASE_ADDR field.
|
||||||
* 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).
|
||||||
* The same applies here, for the flash page size field (DEVICE_UPDI_FLASH_PAGE_SIZE).
|
*/
|
||||||
*/
|
Logger::debug("Setting UPDI_FLASH_PAGE_SIZE AVR8 device parameter");
|
||||||
auto flashPageSize = this->targetParameters.flashPageSize.value();
|
this->setParameter(
|
||||||
Logger::debug("Setting UPDI_FLASH_PAGE_SIZE AVR8 device parameter");
|
Avr8EdbgParameters::DEVICE_UPDI_FLASH_PAGE_SIZE,
|
||||||
this->setParameter(
|
static_cast<std::uint8_t>(parameters.flashPageSize)
|
||||||
Avr8EdbgParameters::DEVICE_UPDI_FLASH_PAGE_SIZE,
|
);
|
||||||
static_cast<std::uint8_t>(flashPageSize)
|
|
||||||
);
|
|
||||||
|
|
||||||
Logger::debug("Setting UPDI_FLASH_PAGE_SIZE_MSB AVR8 device parameter");
|
Logger::debug("Setting UPDI_FLASH_PAGE_SIZE_MSB AVR8 device parameter");
|
||||||
this->setParameter(
|
this->setParameter(
|
||||||
Avr8EdbgParameters::DEVICE_UPDI_FLASH_PAGE_SIZE_MSB,
|
Avr8EdbgParameters::DEVICE_UPDI_FLASH_PAGE_SIZE_MSB,
|
||||||
static_cast<std::uint8_t>(flashPageSize >> 8)
|
static_cast<std::uint8_t>(parameters.flashPageSize >> 8)
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
if (this->targetParameters.eepromPageSize.has_value()) {
|
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(
|
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_EEPROM_PAGE_SIZE, parameters.eepromPageSize);
|
||||||
Avr8EdbgParameters::DEVICE_UPDI_EEPROM_PAGE_SIZE,
|
|
||||||
this->targetParameters.eepromPageSize.value()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->targetParameters.nvmModuleBaseAddress.has_value()) {
|
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(
|
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_NVMCTRL_ADDR, parameters.nvmModuleBaseAddress);
|
||||||
Avr8EdbgParameters::DEVICE_UPDI_NVMCTRL_ADDR,
|
|
||||||
this->targetParameters.nvmModuleBaseAddress.value()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->targetParameters.ocdModuleAddress.has_value()) {
|
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(
|
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_OCD_ADDR, parameters.ocdModuleAddress);
|
||||||
Avr8EdbgParameters::DEVICE_UPDI_OCD_ADDR,
|
|
||||||
this->targetParameters.ocdModuleAddress.value()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->targetParameters.flashSize.has_value()) {
|
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(
|
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_FLASH_SIZE, parameters.flashSize);
|
||||||
Avr8EdbgParameters::DEVICE_UPDI_FLASH_SIZE,
|
|
||||||
this->targetParameters.flashSize.value()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->targetParameters.eepromSize.has_value()) {
|
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(
|
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_EEPROM_SIZE, parameters.eepromSize);
|
||||||
Avr8EdbgParameters::DEVICE_UPDI_EEPROM_SIZE,
|
|
||||||
this->targetParameters.eepromSize.value()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->targetParameters.eepromStartAddress.has_value()) {
|
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(
|
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_EEPROM_BASE_ADDR, parameters.eepromStartAddress);
|
||||||
Avr8EdbgParameters::DEVICE_UPDI_EEPROM_BASE_ADDR,
|
|
||||||
this->targetParameters.eepromStartAddress.value()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->targetParameters.signatureSegmentStartAddress.has_value()) {
|
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(
|
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_SIG_BASE_ADDR, parameters.signatureSegmentStartAddress);
|
||||||
Avr8EdbgParameters::DEVICE_UPDI_SIG_BASE_ADDR,
|
|
||||||
this->targetParameters.signatureSegmentStartAddress.value()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->targetParameters.fuseSegmentStartAddress.has_value()) {
|
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(
|
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_FUSE_BASE_ADDR, parameters.fuseSegmentStartAddress);
|
||||||
Avr8EdbgParameters::DEVICE_UPDI_FUSE_BASE_ADDR,
|
|
||||||
this->targetParameters.fuseSegmentStartAddress.value()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->targetParameters.fuseSegmentSize.has_value()) {
|
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(
|
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_FUSE_SIZE, parameters.fuseSegmentSize);
|
||||||
Avr8EdbgParameters::DEVICE_UPDI_FUSE_SIZE,
|
|
||||||
this->targetParameters.fuseSegmentSize.value()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->targetParameters.lockbitsSegmentStartAddress.has_value()) {
|
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(
|
this->setParameter(Avr8EdbgParameters::DEVICE_UPDI_LOCK_BASE_ADDR, parameters.lockbitSegmentStartAddress);
|
||||||
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::activatePhysical(bool applyExternalReset) {
|
void EdbgAvr8Interface::activatePhysical(bool applyExternalReset) {
|
||||||
|
|||||||
@@ -0,0 +1,130 @@
|
|||||||
|
#include "DebugWireJtagParameters.hpp"
|
||||||
|
|
||||||
|
#include "src/Services/StringService.hpp"
|
||||||
|
|
||||||
|
#include "src/Exceptions/InternalFatalErrorException.hpp"
|
||||||
|
|
||||||
|
namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::Parameters::Avr8Generic
|
||||||
|
{
|
||||||
|
DebugWireJtagParameters::DebugWireJtagParameters(
|
||||||
|
const Targets::Microchip::Avr::Avr8Bit::TargetDescriptionFile& targetDescriptionFile
|
||||||
|
) {
|
||||||
|
using Services::StringService;
|
||||||
|
|
||||||
|
const auto& programMemorySegment = targetDescriptionFile.getProgramMemorySegment();
|
||||||
|
const auto& ramMemorySegment = targetDescriptionFile.getRamMemorySegment();
|
||||||
|
const auto& eepromMemorySegment = targetDescriptionFile.getEepromMemorySegment();
|
||||||
|
|
||||||
|
this->flashPageSize = static_cast<std::uint16_t>(programMemorySegment.pageSize.value());
|
||||||
|
this->flashSize = programMemorySegment.size;
|
||||||
|
this->flashStartWordAddress = static_cast<std::uint32_t>(programMemorySegment.startAddress / 2);
|
||||||
|
|
||||||
|
const auto firstBootSectionOptionGroup = targetDescriptionFile.tryGetPropertyGroup(
|
||||||
|
"boot_section_options.boot_section_1"
|
||||||
|
);
|
||||||
|
if (firstBootSectionOptionGroup.has_value()) {
|
||||||
|
this->bootSectionStartWordAddress = static_cast<std::uint32_t>(
|
||||||
|
StringService::toUint32(firstBootSectionOptionGroup->get().getProperty("start_address").value) / 2
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->ramStartAddress = static_cast<std::uint16_t>(ramMemorySegment.startAddress);
|
||||||
|
this->eepromSize = static_cast<std::uint16_t>(eepromMemorySegment.size);
|
||||||
|
this->eepromPageSize = static_cast<std::uint8_t>(eepromMemorySegment.pageSize.value());
|
||||||
|
|
||||||
|
const auto& ocdPropertyGroup = targetDescriptionFile.getPropertyGroup("ocd");
|
||||||
|
this->ocdRevision = StringService::toUint8(ocdPropertyGroup.getProperty("ocd_revision").value);
|
||||||
|
this->ocdDataRegister = StringService::toUint8(ocdPropertyGroup.getProperty("ocd_datareg").value);
|
||||||
|
|
||||||
|
const auto& eepromRegisterGroupDescriptor = targetDescriptionFile.getTargetPeripheralDescriptor("eeprom")
|
||||||
|
.getRegisterGroupDescriptor("eeprom");
|
||||||
|
|
||||||
|
const auto& eearDescriptor = eepromRegisterGroupDescriptor.tryGetRegisterDescriptor("eear");
|
||||||
|
if (eearDescriptor.has_value()) {
|
||||||
|
const auto startAddress = eearDescriptor->get().startAddress;
|
||||||
|
this->eepromAddressRegisterLow = static_cast<std::uint8_t>(startAddress);
|
||||||
|
this->eepromAddressRegisterHigh = static_cast<std::uint8_t>(
|
||||||
|
eearDescriptor->get().size > 1 ? startAddress >> 2 : startAddress
|
||||||
|
);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
const auto& eearlDescriptor = eepromRegisterGroupDescriptor.getRegisterDescriptor("eearl");
|
||||||
|
this->eepromAddressRegisterLow = static_cast<std::uint8_t>(eearlDescriptor.startAddress);
|
||||||
|
this->eepromAddressRegisterHigh = static_cast<std::uint8_t>(
|
||||||
|
eearlDescriptor.size > 1 ? eearlDescriptor.startAddress >> 2 : eearlDescriptor.startAddress
|
||||||
|
);
|
||||||
|
|
||||||
|
const auto eearhDescriptor = eepromRegisterGroupDescriptor.tryGetRegisterDescriptor("eearh");
|
||||||
|
if (eearhDescriptor.has_value()) {
|
||||||
|
this->eepromAddressRegisterHigh = static_cast<std::uint8_t>(eearhDescriptor->get().startAddress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this->eepromDataRegisterAddress = static_cast<std::uint8_t>(
|
||||||
|
eepromRegisterGroupDescriptor.getRegisterDescriptor("eedr").startAddress
|
||||||
|
);
|
||||||
|
|
||||||
|
this->eepromControlRegisterAddress = static_cast<std::uint8_t>(
|
||||||
|
eepromRegisterGroupDescriptor.getRegisterDescriptor("eecr").startAddress
|
||||||
|
);
|
||||||
|
|
||||||
|
const auto& cpuRegisterGroupDescriptor = targetDescriptionFile.getTargetPeripheralDescriptor("cpu")
|
||||||
|
.getRegisterGroupDescriptor("cpu");
|
||||||
|
|
||||||
|
const auto spmcsrDescriptor = cpuRegisterGroupDescriptor.tryGetRegisterDescriptor("spmcsr")
|
||||||
|
?: cpuRegisterGroupDescriptor.tryGetRegisterDescriptor("spmcr");
|
||||||
|
|
||||||
|
if (spmcsrDescriptor.has_value()) {
|
||||||
|
this->spmcRegisterStartAddress = static_cast<std::uint8_t>(spmcsrDescriptor->get().startAddress);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
const auto& bootLoaderRegisterGroupDescriptor = targetDescriptionFile.getTargetPeripheralDescriptor(
|
||||||
|
"boot_load"
|
||||||
|
).getRegisterGroupDescriptor("boot_load");
|
||||||
|
|
||||||
|
const auto spmcsrDescriptor = bootLoaderRegisterGroupDescriptor.tryGetRegisterDescriptor("spmcsr")
|
||||||
|
?: bootLoaderRegisterGroupDescriptor.tryGetRegisterDescriptor("spmcr");
|
||||||
|
|
||||||
|
if (!spmcsrDescriptor.has_value()) {
|
||||||
|
throw Exceptions::InternalFatalErrorException("Could not extract SPMCS register from TDF");
|
||||||
|
}
|
||||||
|
|
||||||
|
this->spmcRegisterStartAddress = static_cast<std::uint8_t>(spmcsrDescriptor->get().startAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto osccalDescriptor = cpuRegisterGroupDescriptor.tryGetRegisterDescriptor("osccal")
|
||||||
|
?: cpuRegisterGroupDescriptor.tryGetRegisterDescriptor("osccal0")
|
||||||
|
?: cpuRegisterGroupDescriptor.tryGetRegisterDescriptor("osccal1")
|
||||||
|
?: cpuRegisterGroupDescriptor.tryGetRegisterDescriptor("fosccal")
|
||||||
|
?: cpuRegisterGroupDescriptor.tryGetRegisterDescriptor("sosccala");
|
||||||
|
|
||||||
|
if (!osccalDescriptor.has_value()) {
|
||||||
|
throw Exceptions::InternalFatalErrorException("Could not extract OSCCAL register from TDF");
|
||||||
|
}
|
||||||
|
|
||||||
|
this->osccalAddress = static_cast<std::uint8_t>(osccalDescriptor->get().startAddress);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All addresses for registers that reside in the IO memory segment include the IO segment offset
|
||||||
|
* (start address). But the EDBG protocol requires *some* of these addresses to be stripped of this offset
|
||||||
|
* before sending them as target parameters.
|
||||||
|
*
|
||||||
|
* This applies to the following addresses:
|
||||||
|
*
|
||||||
|
* - OSCALL Address
|
||||||
|
* - EEARL Address
|
||||||
|
* - EEARH Address
|
||||||
|
* - EECR Address
|
||||||
|
* - EEDR Address
|
||||||
|
*
|
||||||
|
* It does *not* seem to apply to the SPMCR or OCDDR address.
|
||||||
|
*/
|
||||||
|
const auto& ioMemorySegment = targetDescriptionFile.getIoMemorySegment();
|
||||||
|
|
||||||
|
this->osccalAddress -= ioMemorySegment.startAddress;
|
||||||
|
this->eepromAddressRegisterLow -= ioMemorySegment.startAddress;
|
||||||
|
this->eepromAddressRegisterHigh -= ioMemorySegment.startAddress;
|
||||||
|
this->eepromControlRegisterAddress -= ioMemorySegment.startAddress;
|
||||||
|
this->eepromDataRegisterAddress -= ioMemorySegment.startAddress;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
#include "src/Targets/Microchip/AVR/AVR8/TargetDescriptionFile.hpp"
|
||||||
|
|
||||||
|
namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::Parameters::Avr8Generic
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* EDBG parameters for debugWire and JTAG AVR targets.
|
||||||
|
*
|
||||||
|
* See Microchip's "EDBG-based Tools Protocols" document for more on these parameters.
|
||||||
|
*/
|
||||||
|
struct DebugWireJtagParameters
|
||||||
|
{
|
||||||
|
std::uint16_t flashPageSize;
|
||||||
|
std::uint32_t flashSize;
|
||||||
|
std::uint32_t flashStartWordAddress;
|
||||||
|
std::optional<std::uint32_t> bootSectionStartWordAddress;
|
||||||
|
std::uint16_t ramStartAddress;
|
||||||
|
std::uint16_t eepromSize;
|
||||||
|
std::uint8_t eepromPageSize;
|
||||||
|
std::uint8_t ocdRevision;
|
||||||
|
std::uint8_t ocdDataRegister;
|
||||||
|
std::uint8_t eepromAddressRegisterHigh;
|
||||||
|
std::uint8_t eepromAddressRegisterLow;
|
||||||
|
std::uint8_t eepromDataRegisterAddress;
|
||||||
|
std::uint8_t eepromControlRegisterAddress;
|
||||||
|
std::uint8_t spmcRegisterStartAddress;
|
||||||
|
std::uint8_t osccalAddress;
|
||||||
|
|
||||||
|
DebugWireJtagParameters(const Targets::Microchip::Avr::Avr8Bit::TargetDescriptionFile& targetDescriptionFile);
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#include "PdiParameters.hpp"
|
||||||
|
|
||||||
|
#include "src/Services/StringService.hpp"
|
||||||
|
|
||||||
|
namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::Parameters::Avr8Generic
|
||||||
|
{
|
||||||
|
PdiParameters::PdiParameters(
|
||||||
|
const Targets::Microchip::Avr::Avr8Bit::TargetDescriptionFile& targetDescriptionFile
|
||||||
|
) {
|
||||||
|
using Services::StringService;
|
||||||
|
|
||||||
|
const auto& pdiGroup = targetDescriptionFile.getPropertyGroup("pdi_interface");
|
||||||
|
|
||||||
|
this->appSectionPdiOffset = StringService::toUint32(pdiGroup.getProperty("app_section_offset").value);
|
||||||
|
this->bootSectionPdiOffset = StringService::toUint32(pdiGroup.getProperty("boot_section_offset").value);
|
||||||
|
this->eepromPdiOffset = StringService::toUint32(pdiGroup.getProperty("eeprom_offset").value);
|
||||||
|
this->fuseRegistersPdiOffset = StringService::toUint32(pdiGroup.getProperty("fuse_registers_offset").value);
|
||||||
|
this->lockRegistersPdiOffset = StringService::toUint32(pdiGroup.getProperty("lock_registers_offset").value);
|
||||||
|
this->userSignaturesPdiOffset = StringService::toUint32(pdiGroup.getProperty("user_signatures_offset").value);
|
||||||
|
this->prodSignaturesPdiOffset = StringService::toUint32(pdiGroup.getProperty("prod_signatures_offset").value);
|
||||||
|
this->ramPdiOffset = StringService::toUint32(pdiGroup.getProperty("datamem_offset").value);
|
||||||
|
this->signaturesPdiOffset = StringService::toUint16(pdiGroup.getProperty("signature_offset").value);
|
||||||
|
|
||||||
|
const auto& programMemorySegment = targetDescriptionFile.getProgramMemorySegment();
|
||||||
|
const auto& eepromMemorySegment = targetDescriptionFile.getEepromMemorySegment();
|
||||||
|
|
||||||
|
this->appSectionSize = programMemorySegment.getSection("app_section").size;
|
||||||
|
this->bootSectionSize = static_cast<std::uint16_t>(programMemorySegment.getSection("boot_section").size);
|
||||||
|
this->flashPageSize = static_cast<std::uint16_t>(programMemorySegment.pageSize.value());
|
||||||
|
this->eepromSize = static_cast<std::uint16_t>(eepromMemorySegment.size);
|
||||||
|
this->eepromPageSize = static_cast<std::uint8_t>(eepromMemorySegment.pageSize.value());
|
||||||
|
|
||||||
|
this->nvmModuleBaseAddress = static_cast<std::uint16_t>(
|
||||||
|
targetDescriptionFile.getTargetPeripheralDescriptor("nvm").getRegisterGroupDescriptor("nvm").startAddress()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "src/Targets/Microchip/AVR/AVR8/TargetDescriptionFile.hpp"
|
||||||
|
|
||||||
|
namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::Parameters::Avr8Generic
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* EDBG parameters for PDI-enabled (XMega) AVR targets.
|
||||||
|
*
|
||||||
|
* See Microchip's "EDBG-based Tools Protocols" document for more on these parameters.
|
||||||
|
*/
|
||||||
|
struct PdiParameters
|
||||||
|
{
|
||||||
|
std::uint32_t appSectionPdiOffset;
|
||||||
|
std::uint32_t bootSectionPdiOffset;
|
||||||
|
std::uint32_t eepromPdiOffset;
|
||||||
|
std::uint32_t fuseRegistersPdiOffset;
|
||||||
|
std::uint32_t lockRegistersPdiOffset;
|
||||||
|
std::uint32_t userSignaturesPdiOffset;
|
||||||
|
std::uint32_t prodSignaturesPdiOffset;
|
||||||
|
std::uint32_t ramPdiOffset;
|
||||||
|
std::uint32_t appSectionSize;
|
||||||
|
std::uint16_t bootSectionSize;
|
||||||
|
std::uint16_t flashPageSize;
|
||||||
|
std::uint16_t eepromSize;
|
||||||
|
std::uint8_t eepromPageSize;
|
||||||
|
std::uint16_t nvmModuleBaseAddress;
|
||||||
|
std::uint16_t signaturesPdiOffset;
|
||||||
|
|
||||||
|
PdiParameters(const Targets::Microchip::Avr::Avr8Bit::TargetDescriptionFile& targetDescriptionFile);
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
#include "UpdiParameters.hpp"
|
||||||
|
|
||||||
|
#include "src/Services/StringService.hpp"
|
||||||
|
|
||||||
|
namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::Parameters::Avr8Generic
|
||||||
|
{
|
||||||
|
UpdiParameters::UpdiParameters(
|
||||||
|
const Targets::Microchip::Avr::Avr8Bit::TargetDescriptionFile& targetDescriptionFile
|
||||||
|
) {
|
||||||
|
using Services::StringService;
|
||||||
|
|
||||||
|
const auto& updiGroup = targetDescriptionFile.getPropertyGroup("updi_interface");
|
||||||
|
|
||||||
|
this->programMemoryStartAddress = StringService::toUint32(updiGroup.getProperty("progmem_offset").value);
|
||||||
|
this->ocdModuleAddress = StringService::toUint16(updiGroup.getProperty("ocd_base_addr").value);
|
||||||
|
|
||||||
|
const auto& programMemorySegment = targetDescriptionFile.getProgramMemorySegment();
|
||||||
|
const auto& eepromMemorySegment = targetDescriptionFile.getEepromMemorySegment();
|
||||||
|
const auto& signatureMemorySegment = targetDescriptionFile.getSignatureMemorySegment();
|
||||||
|
const auto& fuseMemorySegment = targetDescriptionFile.getFuseMemorySegment();
|
||||||
|
const auto& lockbitMemorySegment = targetDescriptionFile.getLockbitMemorySegment();
|
||||||
|
|
||||||
|
this->flashSize = programMemorySegment.size;
|
||||||
|
this->flashPageSize = static_cast<std::uint16_t>(programMemorySegment.pageSize.value());
|
||||||
|
this->eepromStartAddress = static_cast<std::uint16_t>(eepromMemorySegment.startAddress);
|
||||||
|
this->eepromSize = static_cast<std::uint16_t>(eepromMemorySegment.size);
|
||||||
|
this->eepromPageSize = static_cast<std::uint8_t>(eepromMemorySegment.pageSize.value());
|
||||||
|
this->signatureSegmentStartAddress = static_cast<std::uint16_t>(signatureMemorySegment.startAddress);
|
||||||
|
this->fuseSegmentSize = static_cast<std::uint16_t>(fuseMemorySegment.size);
|
||||||
|
this->fuseSegmentStartAddress = static_cast<std::uint16_t>(fuseMemorySegment.startAddress);
|
||||||
|
this->lockbitSegmentStartAddress = static_cast<std::uint16_t>(lockbitMemorySegment.startAddress);
|
||||||
|
|
||||||
|
this->nvmModuleBaseAddress = static_cast<std::uint16_t>(
|
||||||
|
targetDescriptionFile.getTargetPeripheralDescriptor("nvmctrl").getRegisterGroupDescriptor(
|
||||||
|
"nvmctrl"
|
||||||
|
).startAddress()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "src/Targets/Microchip/AVR/AVR8/TargetDescriptionFile.hpp"
|
||||||
|
|
||||||
|
namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::Parameters::Avr8Generic
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* EDBG parameters for UPDI-enabled AVR targets.
|
||||||
|
*
|
||||||
|
* See Microchip's "EDBG-based Tools Protocols" document for more on these parameters.
|
||||||
|
* BTW that document seems to be a little outdated. It doesn't list most of these parameters. I discovered the
|
||||||
|
* unlisted ones by looking at other open-source codebases and reverse engineering.
|
||||||
|
*/
|
||||||
|
struct UpdiParameters
|
||||||
|
{
|
||||||
|
std::uint32_t programMemoryStartAddress;
|
||||||
|
std::uint16_t flashPageSize;
|
||||||
|
std::uint8_t eepromPageSize;
|
||||||
|
std::uint16_t nvmModuleBaseAddress;
|
||||||
|
std::uint16_t ocdModuleAddress;
|
||||||
|
std::uint32_t flashSize;
|
||||||
|
std::uint16_t eepromSize;
|
||||||
|
std::uint16_t fuseSegmentSize;
|
||||||
|
std::uint16_t eepromStartAddress;
|
||||||
|
std::uint16_t signatureSegmentStartAddress;
|
||||||
|
std::uint16_t fuseSegmentStartAddress;
|
||||||
|
std::uint16_t lockbitSegmentStartAddress;
|
||||||
|
|
||||||
|
UpdiParameters(const Targets::Microchip::Avr::Avr8Bit::TargetDescriptionFile& targetDescriptionFile);
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user