Massive refactor to accommodate RISC-V targets

- Refactored entire codebase (excluding the Insight component) to accommodate multiple target architectures (no longer specific to AVR)
- Deleted 'generate SVD' GDB monitor command - I will eventually move this functionality to the Bloom website
- Added unit size property to address spaces
- Many other changes which I couldn't be bothered to describe here
This commit is contained in:
Nav
2024-07-23 21:14:22 +01:00
parent 2986934485
commit 6cdbfbe950
331 changed files with 8815 additions and 8565 deletions

View File

@@ -38,14 +38,14 @@ namespace DebugToolDrivers::Microchip
this->setConfiguration(this->configurationIndex.value());
}
auto cmsisHidInterface = Usb::HidInterface(
auto cmsisHidInterface = Usb::HidInterface{
this->cmsisHidInterfaceNumber,
this->getEndpointMaxPacketSize(
this->getFirstEndpointAddress(this->cmsisHidInterfaceNumber, LIBUSB_ENDPOINT_IN)
),
this->vendorId,
this->productId
);
};
cmsisHidInterface.init();
@@ -57,7 +57,7 @@ namespace DebugToolDrivers::Microchip
* Because of this, we have to enforce a minimum time gap between commands. See comment
* in CmsisDapInterface class declaration for more info.
*/
this->edbgInterface->setMinimumCommandTimeGap(std::chrono::milliseconds(35));
this->edbgInterface->setMinimumCommandTimeGap(std::chrono::milliseconds{35});
// We don't need to claim the CMSISDAP interface here as the HIDAPI will have already done so.
if (!this->sessionStarted) {
@@ -70,9 +70,7 @@ namespace DebugToolDrivers::Microchip
);
}
this->edbgAvrIspInterface = std::make_unique<EdbgAvrIspInterface>(this->edbgInterface.get());
this->setInitialised(true);
this->initialised = true;
}
void EdbgDevice::close() {
@@ -82,21 +80,50 @@ namespace DebugToolDrivers::Microchip
this->edbgInterface->getUsbHidInterface().close();
UsbDevice::close();
this->initialised = false;
}
TargetInterfaces::Microchip::Avr::Avr8::Avr8DebugInterface* EdbgDevice::getAvr8DebugInterface(
const Targets::Microchip::Avr::Avr8Bit::Avr8TargetConfig& targetConfig,
Targets::Microchip::Avr::Avr8Bit::Family targetFamily,
const Targets::Microchip::Avr::Avr8Bit::TargetParameters& targetParameters,
const Targets::TargetRegisterDescriptorMapping& targetRegisterDescriptorsById
bool EdbgDevice::isInitialised() const {
return this->initialised;
}
std::string EdbgDevice::getSerialNumber() {
using namespace CommandFrames::Discovery;
using ResponseFrames::Discovery::ResponseId;
const auto responseFrame = this->edbgInterface->sendAvrCommandFrameAndWaitForResponseFrame(
Query{QueryContext::SERIAL_NUMBER}
);
if (responseFrame.id != ResponseId::OK) {
throw DeviceInitializationFailure{
"Failed to fetch serial number from device - invalid Discovery Protocol response ID."
};
}
const auto data = responseFrame.getPayloadData();
return std::string{data.begin(), data.end()};
}
std::string EdbgDevice::getFirmwareVersionString() {
// TODO: Implement this
return "UNKNOWN";
}
DebugToolDrivers::TargetInterfaces::TargetPowerManagementInterface* EdbgDevice::getTargetPowerManagementInterface()
{
return this->targetPowerManagementInterface.get();
}
TargetInterfaces::Microchip::Avr8::Avr8DebugInterface* EdbgDevice::getAvr8DebugInterface(
const Targets::Microchip::Avr8::TargetDescriptionFile& targetDescriptionFile,
const Targets::Microchip::Avr8::Avr8TargetConfig& targetConfig
) {
if (this->edbgAvr8Interface == nullptr) {
this->edbgAvr8Interface = std::make_unique<EdbgAvr8Interface>(
this->edbgInterface.get(),
targetConfig,
targetFamily,
targetParameters,
targetRegisterDescriptorsById
targetDescriptionFile,
targetConfig
);
this->configureAvr8Interface();
@@ -105,40 +132,30 @@ namespace DebugToolDrivers::Microchip
return this->edbgAvr8Interface.get();
}
std::string EdbgDevice::getSerialNumber() {
using namespace CommandFrames::Discovery;
using ResponseFrames::Discovery::ResponseId;
const auto responseFrame = this->edbgInterface->sendAvrCommandFrameAndWaitForResponseFrame(
Query(QueryContext::SERIAL_NUMBER)
);
if (responseFrame.id != ResponseId::OK) {
throw DeviceInitializationFailure(
"Failed to fetch serial number from device - invalid Discovery Protocol response ID."
TargetInterfaces::Microchip::Avr8::AvrIspInterface* EdbgDevice::getAvrIspInterface(
const Targets::Microchip::Avr8::TargetDescriptionFile& targetDescriptionFile,
const Targets::Microchip::Avr8::Avr8TargetConfig& targetConfig
) {
if (this->edbgAvrIspInterface == nullptr) {
this->edbgAvrIspInterface = std::make_unique<EdbgAvrIspInterface>(
this->edbgInterface.get(),
targetDescriptionFile
);
this->configureAvr8Interface();
}
const auto data = responseFrame.getPayloadData();
return std::string(data.begin(), data.end());
}
std::string EdbgDevice::getFirmwareVersionString() {
// TODO: Implement this
return "UNKNOWN";
return this->edbgAvrIspInterface.get();
}
void EdbgDevice::startSession() {
using namespace CommandFrames::HouseKeeping;
using ResponseFrames::HouseKeeping::ResponseId;
const auto responseFrame = this->edbgInterface->sendAvrCommandFrameAndWaitForResponseFrame(
StartSession()
);
const auto responseFrame = this->edbgInterface->sendAvrCommandFrameAndWaitForResponseFrame(StartSession{});
if (responseFrame.id == ResponseId::FAILED) {
// Failed response returned!
throw DeviceInitializationFailure("Failed to start session with EDBG device!");
throw DeviceInitializationFailure{"Failed to start session with EDBG device!"};
}
this->sessionStarted = true;
@@ -148,13 +165,10 @@ namespace DebugToolDrivers::Microchip
using namespace CommandFrames::HouseKeeping;
using ResponseFrames::HouseKeeping::ResponseId;
const auto responseFrame = this->edbgInterface->sendAvrCommandFrameAndWaitForResponseFrame(
EndSession()
);
const auto responseFrame = this->edbgInterface->sendAvrCommandFrameAndWaitForResponseFrame(EndSession{});
if (responseFrame.id == ResponseId::FAILED) {
// Failed response returned!
throw DeviceFailure("Failed to end session with EDBG device!");
throw DeviceFailure{"Failed to end session with EDBG device!"};
}
this->sessionStarted = false;

View File

@@ -50,22 +50,7 @@ namespace DebugToolDrivers::Microchip
*/
void close() override;
TargetInterfaces::Microchip::Avr::Avr8::Avr8DebugInterface* getAvr8DebugInterface(
const Targets::Microchip::Avr::Avr8Bit::Avr8TargetConfig& targetConfig,
Targets::Microchip::Avr::Avr8Bit::Family targetFamily,
const Targets::Microchip::Avr::Avr8Bit::TargetParameters& targetParameters,
const Targets::TargetRegisterDescriptorMapping& targetRegisterDescriptorsById
) override;
TargetInterfaces::Microchip::Avr::AvrIspInterface* getAvrIspInterface(
const Targets::Microchip::Avr::Avr8Bit::Avr8TargetConfig& targetConfig
) override {
return this->edbgAvrIspInterface.get();
}
DebugToolDrivers::TargetInterfaces::TargetPowerManagementInterface* getTargetPowerManagementInterface() override {
return this->targetPowerManagementInterface.get();
}
[[nodiscard]] bool isInitialised() const override;
/**
* Retrieves the device serial number via the "Discovery" EDBG sub-protocol.
@@ -81,6 +66,18 @@ namespace DebugToolDrivers::Microchip
*/
std::string getFirmwareVersionString() override;
DebugToolDrivers::TargetInterfaces::TargetPowerManagementInterface* getTargetPowerManagementInterface() override;
TargetInterfaces::Microchip::Avr8::Avr8DebugInterface* getAvr8DebugInterface(
const Targets::Microchip::Avr8::TargetDescriptionFile& targetDescriptionFile,
const Targets::Microchip::Avr8::Avr8TargetConfig& targetConfig
) override;
TargetInterfaces::Microchip::Avr8::AvrIspInterface* getAvrIspInterface(
const Targets::Microchip::Avr8::TargetDescriptionFile& targetDescriptionFile,
const Targets::Microchip::Avr8::Avr8TargetConfig& targetConfig
) override;
/**
* Starts a session with the EDBG device using the "Housekeeping" EDBG sub-protocol.
*/
@@ -92,6 +89,8 @@ namespace DebugToolDrivers::Microchip
void endSession();
protected:
bool initialised = false;
/**
* The USB interface number of the CMSIS-DAP HID interface.
*/
@@ -136,9 +135,9 @@ namespace DebugToolDrivers::Microchip
* ISP cannot be used for debugging operations. The EdbgAvrIspInterface class does *not* implement
* the Avr8DebugInterface.
*
* Currently, Bloom will only use the ISP interface as a fallback when attempting to connect to debugWire
* targets. We use the interface to inspect and update the "debugWire enable" (DWEN) fuse-bit, before making a
* second connection attempt via the debugWire interface.
* Currently, Bloom will only use the ISP interface as a fallback when attempting to connect to debugWIRE
* targets. We use the interface to inspect and update the "debugWIRE enable" (DWEN) fuse-bit, before making a
* second connection attempt via the debugWIRE interface.
*/
std::unique_ptr<Microchip::Protocols::Edbg::Avr::EdbgAvrIspInterface> edbgAvrIspInterface = nullptr;

View File

@@ -30,10 +30,10 @@ namespace DebugToolDrivers::Microchip
);
if (!nonEdbgDevices.empty()) {
throw DeviceNotFound(
throw DeviceNotFound{
"The connected MPLAB PICkit 4 device is not in \"AVR mode\". Please follow the instructions at "
+ Services::PathService::homeDomainName() + "/docs/avr-mode"
);
};
}
throw exception;

View File

@@ -38,10 +38,10 @@ namespace DebugToolDrivers::Microchip
}
if (!nonEdbgDevices.empty()) {
throw DeviceNotFound(
throw DeviceNotFound{
"The connected MPLAB Snap device is not in \"AVR mode\". Please follow the instructions at "
+ Services::PathService::homeDomainName() + "/docs/avr-mode"
);
};
}
throw exception;

View File

@@ -8,10 +8,9 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
{
struct Avr8EdbgParameter
{
unsigned char context = 0x00;
unsigned char id = 0x00;
unsigned char context;
unsigned char id;
constexpr Avr8EdbgParameter() = default;
constexpr Avr8EdbgParameter(unsigned char context, unsigned char id)
: context(context)
, id(id)
@@ -20,70 +19,70 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
struct Avr8EdbgParameters
{
static constexpr Avr8EdbgParameter CONFIG_VARIANT {0x00, 0x00};
static constexpr Avr8EdbgParameter CONFIG_FUNCTION {0x00, 0x01};
static constexpr Avr8EdbgParameter PHYSICAL_INTERFACE {0x01, 0x00};
static constexpr Avr8EdbgParameter DW_CLOCK_DIVISION_FACTOR {0x01, 0x10};
static constexpr Avr8EdbgParameter PDI_CLOCK_SPEED {0x01, 0x31};
static constexpr Avr8EdbgParameter MEGA_DEBUG_CLOCK {0x01, 0x21};
static constexpr Avr8EdbgParameter JTAG_DAISY_CHAIN_SETTINGS {0x01, 0x01};
static constexpr Avr8EdbgParameter CONFIG_VARIANT = {0x00, 0x00};
static constexpr Avr8EdbgParameter CONFIG_FUNCTION = {0x00, 0x01};
static constexpr Avr8EdbgParameter PHYSICAL_INTERFACE = {0x01, 0x00};
static constexpr Avr8EdbgParameter DW_CLOCK_DIVISION_FACTOR = {0x01, 0x10};
static constexpr Avr8EdbgParameter PDI_CLOCK_SPEED = {0x01, 0x31};
static constexpr Avr8EdbgParameter MEGA_DEBUG_CLOCK = {0x01, 0x21};
static constexpr Avr8EdbgParameter JTAG_DAISY_CHAIN_SETTINGS = {0x01, 0x01};
// debugWire and JTAG parameters
static constexpr Avr8EdbgParameter DEVICE_BOOT_START_ADDR {0x02, 0x0A};
static constexpr Avr8EdbgParameter DEVICE_FLASH_BASE {0x02, 0x06};
static constexpr Avr8EdbgParameter DEVICE_SRAM_START {0x02, 0x0E};
static constexpr Avr8EdbgParameter DEVICE_EEPROM_SIZE {0x02, 0x10};
static constexpr Avr8EdbgParameter DEVICE_EEPROM_PAGE_SIZE {0x02, 0x12};
static constexpr Avr8EdbgParameter DEVICE_FLASH_PAGE_SIZE {0x02, 0x00};
static constexpr Avr8EdbgParameter DEVICE_FLASH_SIZE {0x02, 0x02};
static constexpr Avr8EdbgParameter DEVICE_OCD_REVISION {0x02, 0x13};
static constexpr Avr8EdbgParameter DEVICE_OCD_DATA_REGISTER {0x02, 0x18};
static constexpr Avr8EdbgParameter DEVICE_SPMCR_REGISTER {0x02, 0x1D};
static constexpr Avr8EdbgParameter DEVICE_OSCCAL_ADDR {0x02, 0x1E};
static constexpr Avr8EdbgParameter DEVICE_EEARH_ADDR {0x02, 0x19};
static constexpr Avr8EdbgParameter DEVICE_EEARL_ADDR {0x02, 0x1A};
static constexpr Avr8EdbgParameter DEVICE_EECR_ADDR {0x02, 0x1B};
static constexpr Avr8EdbgParameter DEVICE_EEDR_ADDR {0x02, 0x1C};
// debugWIRE and JTAG parameters
static constexpr Avr8EdbgParameter DEVICE_BOOT_START_ADDR = {0x02, 0x0A};
static constexpr Avr8EdbgParameter DEVICE_FLASH_BASE = {0x02, 0x06};
static constexpr Avr8EdbgParameter DEVICE_SRAM_START = {0x02, 0x0E};
static constexpr Avr8EdbgParameter DEVICE_EEPROM_SIZE = {0x02, 0x10};
static constexpr Avr8EdbgParameter DEVICE_EEPROM_PAGE_SIZE = {0x02, 0x12};
static constexpr Avr8EdbgParameter DEVICE_FLASH_PAGE_SIZE = {0x02, 0x00};
static constexpr Avr8EdbgParameter DEVICE_FLASH_SIZE = {0x02, 0x02};
static constexpr Avr8EdbgParameter DEVICE_OCD_REVISION = {0x02, 0x13};
static constexpr Avr8EdbgParameter DEVICE_OCD_DATA_REGISTER = {0x02, 0x18};
static constexpr Avr8EdbgParameter DEVICE_SPMCR_REGISTER = {0x02, 0x1D};
static constexpr Avr8EdbgParameter DEVICE_OSCCAL_ADDR = {0x02, 0x1E};
static constexpr Avr8EdbgParameter DEVICE_EEARH_ADDR = {0x02, 0x19};
static constexpr Avr8EdbgParameter DEVICE_EEARL_ADDR = {0x02, 0x1A};
static constexpr Avr8EdbgParameter DEVICE_EECR_ADDR = {0x02, 0x1B};
static constexpr Avr8EdbgParameter DEVICE_EEDR_ADDR = {0x02, 0x1C};
// PDI/XMega device parameters
static constexpr Avr8EdbgParameter DEVICE_XMEGA_APPL_BASE_ADDR {0x02, 0x00};
static constexpr Avr8EdbgParameter DEVICE_XMEGA_BOOT_BASE_ADDR {0x02, 0x04};
static constexpr Avr8EdbgParameter DEVICE_XMEGA_EEPROM_BASE_ADDR {0x02, 0x08};
static constexpr Avr8EdbgParameter DEVICE_XMEGA_FUSE_BASE_ADDR {0x02, 0x0C};
static constexpr Avr8EdbgParameter DEVICE_XMEGA_LOCKBIT_BASE_ADDR {0x02, 0x10};
static constexpr Avr8EdbgParameter DEVICE_XMEGA_USER_SIGN_BASE_ADDR {0x02, 0x14};
static constexpr Avr8EdbgParameter DEVICE_XMEGA_PROD_SIGN_BASE_ADDR {0x02, 0x18};
static constexpr Avr8EdbgParameter DEVICE_XMEGA_DATA_BASE_ADDR {0x02, 0x1C};
static constexpr Avr8EdbgParameter DEVICE_XMEGA_APPLICATION_BYTES {0x02, 0x20};
static constexpr Avr8EdbgParameter DEVICE_XMEGA_BOOT_BYTES {0x02, 0x24};
static constexpr Avr8EdbgParameter DEVICE_XMEGA_NVM_BASE {0x02, 0x2B};
static constexpr Avr8EdbgParameter DEVICE_XMEGA_SIGNATURE_OFFSET {0x02, 0x2D};
static constexpr Avr8EdbgParameter DEVICE_XMEGA_FLASH_PAGE_BYTES {0x02, 0x26};
static constexpr Avr8EdbgParameter DEVICE_XMEGA_EEPROM_SIZE {0x02, 0x28};
static constexpr Avr8EdbgParameter DEVICE_XMEGA_EEPROM_PAGE_SIZE {0x02, 0x2A};
static constexpr Avr8EdbgParameter DEVICE_XMEGA_APPL_BASE_ADDR = {0x02, 0x00};
static constexpr Avr8EdbgParameter DEVICE_XMEGA_BOOT_BASE_ADDR = {0x02, 0x04};
static constexpr Avr8EdbgParameter DEVICE_XMEGA_EEPROM_BASE_ADDR = {0x02, 0x08};
static constexpr Avr8EdbgParameter DEVICE_XMEGA_FUSE_BASE_ADDR = {0x02, 0x0C};
static constexpr Avr8EdbgParameter DEVICE_XMEGA_LOCKBIT_BASE_ADDR = {0x02, 0x10};
static constexpr Avr8EdbgParameter DEVICE_XMEGA_USER_SIGN_BASE_ADDR = {0x02, 0x14};
static constexpr Avr8EdbgParameter DEVICE_XMEGA_PROD_SIGN_BASE_ADDR = {0x02, 0x18};
static constexpr Avr8EdbgParameter DEVICE_XMEGA_DATA_BASE_ADDR = {0x02, 0x1C};
static constexpr Avr8EdbgParameter DEVICE_XMEGA_APPLICATION_BYTES = {0x02, 0x20};
static constexpr Avr8EdbgParameter DEVICE_XMEGA_BOOT_BYTES = {0x02, 0x24};
static constexpr Avr8EdbgParameter DEVICE_XMEGA_NVM_BASE = {0x02, 0x2B};
static constexpr Avr8EdbgParameter DEVICE_XMEGA_SIGNATURE_OFFSET = {0x02, 0x2D};
static constexpr Avr8EdbgParameter DEVICE_XMEGA_FLASH_PAGE_BYTES = {0x02, 0x26};
static constexpr Avr8EdbgParameter DEVICE_XMEGA_EEPROM_SIZE = {0x02, 0x28};
static constexpr Avr8EdbgParameter DEVICE_XMEGA_EEPROM_PAGE_SIZE = {0x02, 0x2A};
// UPDI device parameters
static constexpr Avr8EdbgParameter DEVICE_UPDI_PROGMEM_BASE_ADDR {0x02, 0x00};
static constexpr Avr8EdbgParameter DEVICE_UPDI_FLASH_PAGE_SIZE {0x02, 0x02};
static constexpr Avr8EdbgParameter DEVICE_UPDI_EEPROM_PAGE_SIZE {0x02, 0x03};
static constexpr Avr8EdbgParameter DEVICE_UPDI_NVMCTRL_ADDR {0x02, 0x04};
static constexpr Avr8EdbgParameter DEVICE_UPDI_OCD_ADDR {0x02, 0x06};
static constexpr Avr8EdbgParameter DEVICE_UPDI_FLASH_SIZE {0x02, 0x12};
static constexpr Avr8EdbgParameter DEVICE_UPDI_EEPROM_SIZE {0x02, 0x16};
static constexpr Avr8EdbgParameter DEVICE_UPDI_USER_SIG_SIZE {0x02, 0x18};
static constexpr Avr8EdbgParameter DEVICE_UPDI_FUSE_SIZE {0x02, 0x1A};
static constexpr Avr8EdbgParameter DEVICE_UPDI_EEPROM_BASE_ADDR {0x02, 0x20};
static constexpr Avr8EdbgParameter DEVICE_UPDI_USER_SIG_BASE_ADDR {0x02, 0x22};
static constexpr Avr8EdbgParameter DEVICE_UPDI_SIG_BASE_ADDR {0x02, 0x24};
static constexpr Avr8EdbgParameter DEVICE_UPDI_FUSE_BASE_ADDR {0x02, 0x26};
static constexpr Avr8EdbgParameter DEVICE_UPDI_LOCK_BASE_ADDR {0x02, 0x28};
static constexpr Avr8EdbgParameter DEVICE_UPDI_DEVICE_ID {0x02, 0x2A};
static constexpr Avr8EdbgParameter DEVICE_UPDI_PROGMEM_BASE_ADDR_MSB {0x02, 0x2C};
static constexpr Avr8EdbgParameter DEVICE_UPDI_FLASH_PAGE_SIZE_MSB {0x02, 0x2D};
static constexpr Avr8EdbgParameter DEVICE_UPDI_24_BIT_ADDRESSING_ENABLE {0x02, 0x2E};
static constexpr Avr8EdbgParameter DEVICE_UPDI_PROGMEM_BASE_ADDR = {0x02, 0x00};
static constexpr Avr8EdbgParameter DEVICE_UPDI_FLASH_PAGE_SIZE = {0x02, 0x02};
static constexpr Avr8EdbgParameter DEVICE_UPDI_EEPROM_PAGE_SIZE = {0x02, 0x03};
static constexpr Avr8EdbgParameter DEVICE_UPDI_NVMCTRL_ADDR = {0x02, 0x04};
static constexpr Avr8EdbgParameter DEVICE_UPDI_OCD_ADDR = {0x02, 0x06};
static constexpr Avr8EdbgParameter DEVICE_UPDI_FLASH_SIZE = {0x02, 0x12};
static constexpr Avr8EdbgParameter DEVICE_UPDI_EEPROM_SIZE = {0x02, 0x16};
static constexpr Avr8EdbgParameter DEVICE_UPDI_USER_SIG_SIZE = {0x02, 0x18};
static constexpr Avr8EdbgParameter DEVICE_UPDI_FUSE_SIZE = {0x02, 0x1A};
static constexpr Avr8EdbgParameter DEVICE_UPDI_EEPROM_BASE_ADDR = {0x02, 0x20};
static constexpr Avr8EdbgParameter DEVICE_UPDI_USER_SIG_BASE_ADDR = {0x02, 0x22};
static constexpr Avr8EdbgParameter DEVICE_UPDI_SIG_BASE_ADDR = {0x02, 0x24};
static constexpr Avr8EdbgParameter DEVICE_UPDI_FUSE_BASE_ADDR = {0x02, 0x26};
static constexpr Avr8EdbgParameter DEVICE_UPDI_LOCK_BASE_ADDR = {0x02, 0x28};
static constexpr Avr8EdbgParameter DEVICE_UPDI_DEVICE_ID = {0x02, 0x2A};
static constexpr Avr8EdbgParameter DEVICE_UPDI_PROGMEM_BASE_ADDR_MSB = {0x02, 0x2C};
static constexpr Avr8EdbgParameter DEVICE_UPDI_FLASH_PAGE_SIZE_MSB = {0x02, 0x2D};
static constexpr Avr8EdbgParameter DEVICE_UPDI_24_BIT_ADDRESSING_ENABLE = {0x02, 0x2E};
static constexpr Avr8EdbgParameter RUN_TIMERS_WHILST_STOPPED {0x03, 0x00};
static constexpr Avr8EdbgParameter ENABLE_HIGH_VOLTAGE_UPDI {0x03, 0x06};
static constexpr Avr8EdbgParameter RUN_TIMERS_WHILST_STOPPED = {0x03, 0x00};
static constexpr Avr8EdbgParameter ENABLE_HIGH_VOLTAGE_UPDI = {0x03, 0x06};
};
enum class Avr8ConfigVariant: unsigned char
@@ -103,16 +102,14 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
DEBUGGING = 0x02,
};
static inline auto getPhysicalInterfaceToAvr8IdMapping() {
using Targets::TargetPhysicalInterface;
return std::map<TargetPhysicalInterface, unsigned char>({
{TargetPhysicalInterface::DEBUG_WIRE, 0x05},
{TargetPhysicalInterface::PDI, 0x06},
{TargetPhysicalInterface::JTAG, 0x04},
{TargetPhysicalInterface::UPDI, 0x08},
});
}
enum class Avr8PhysicalInterface: unsigned char
{
NONE = 0x00,
JTAG = 0x04,
DEBUG_WIRE = 0x05,
PDI = 0x06,
PDI_1W = 0x08,
};
enum class Avr8MemoryType: unsigned char
{
@@ -148,10 +145,10 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
/**
* The FLASH_PAGE memory type can be used to read and write full flash pages on the target.
*
* Only available with the JTAG and debugWire config variants.
* Only available with the JTAG and debugWIRE config variants.
*
* This memory type is not available with the JTAG config variant in debugging mode. Programming mode will need
* to be enabled before it can be used with JTAG targets. With the debugWire variant, this memory type *can* be
* to be enabled before it can be used with JTAG targets. With the debugWIRE variant, this memory type *can* be
* used whilst in debugging mode.
*/
FLASH_PAGE = 0xB0,
@@ -171,7 +168,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
/**
* The SPM memory type can be used to read memory from the target whilst in debugging mode.
*
* Only available with JTAG and debugWire config variants.
* Only available with JTAG and debugWIRE config variants.
*/
SPM = 0xA0,
@@ -186,7 +183,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
/**
* The FUSES memory type can be used to read and write AVR fuses in programming mode.
*
* Not available for the debugWire config variant.
* Not available for the debugWIRE config variant.
*/
FUSES = 0xB2,
};

View File

@@ -12,7 +12,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
/**
* AVR CMSIS-DAP vendor command.
*/
class AvrCommand: public ::DebugToolDrivers::Protocols::CmsisDap::Command
class AvrCommand: public ::DebugToolDrivers::Protocols::CmsisDap::Command
{
public:
/*

View File

@@ -12,11 +12,11 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
: Response(rawResponse)
{
if (this->id != 0x82) {
throw Exception("Failed to construct AvrEvent object - invalid response ID.");
throw Exception{"Failed to construct AvrEvent object - invalid response ID."};
}
if (this->data.size() < 7) {
throw Exception("Failed to construct AvrEvent object - unexpected size of AVR_EVT response.");
throw Exception{"Failed to construct AvrEvent object - unexpected size of AVR_EVT response."};
}
// Response size is two bytes, MSB
@@ -28,17 +28,17 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
}
if (this->data.size() < responsePacketSize + 7) {
throw Exception("Failed to construct AvrEvent object - invalid size of AVR_EVT response packet.");
throw Exception{"Failed to construct AvrEvent object - invalid size of AVR_EVT response packet."};
}
/*
* Ignore the SOF, protocol version, handler ID, sequence ID and size bytes (which all make up 7 bytes
* in total).
*/
this->eventData = std::vector<unsigned char>(
this->eventData = std::vector<unsigned char>{
this->data.begin() + 7,
this->data.begin() + 7 + static_cast<std::int64_t>(responsePacketSize)
);
};
this->eventId = static_cast<AvrEventId>(this->eventData[0]);
}

View File

@@ -10,12 +10,12 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
: Response(rawResponse)
{
if (this->id != 0x81) {
throw Exception("Failed to construct AvrResponse object - invalid response ID.");
throw Exception{"Failed to construct AvrResponse object - invalid response ID."};
}
if (this->data.empty()) {
// All AVR responses should contain at least one byte (the fragment info byte)
throw Exception("Failed to construct AvrResponse object - malformed AVR_RSP data");
throw Exception{"Failed to construct AvrResponse object - malformed AVR_RSP data"};
}
if (this->data[0] == 0x00) {

View File

@@ -11,7 +11,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::CommandFrames::Avr8
: Avr8GenericCommandFrame()
{
/*
* The disable debugWire command consists of 2 bytes:
* The disable debugWIRE command consists of 2 bytes:
* 1. Command ID (0x17)
* 2. Version (0x00)
*/

View File

@@ -4,17 +4,18 @@
#include "AvrIspCommandFrame.hpp"
#include "src/Targets/Microchip/AVR/Fuse.hpp"
#include "src/Targets/Microchip/AVR8/Fuse.hpp"
#include "src/Exceptions/InternalFatalErrorException.hpp"
namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::CommandFrames::AvrIsp
{
class ProgramFuse: public AvrIspCommandFrame<std::array<unsigned char, 5>>
{
public:
ProgramFuse(Targets::Microchip::Avr::FuseType fuseType, unsigned char value)
ProgramFuse(Targets::Microchip::Avr8::FuseType fuseType, Targets::Microchip::Avr8::FuseValue value)
: AvrIspCommandFrame()
{
using Targets::Microchip::Avr::FuseType;
using Targets::Microchip::Avr8::FuseType;
/*
* The program fuse command consists of 5 bytes:
@@ -54,7 +55,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::CommandFrames::AvrI
break;
}
default: {
throw Exceptions::Exception("Unsupported fuse type");
throw Exceptions::InternalFatalErrorException{"Unsupported fuse type"};
}
}
}

View File

@@ -4,20 +4,18 @@
#include "AvrIspCommandFrame.hpp"
#include "src/Targets/Microchip/AVR/Fuse.hpp"
#include "src/Targets/Microchip/AVR8/Fuse.hpp"
#include "src/Exceptions/InternalFatalErrorException.hpp"
namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::CommandFrames::AvrIsp
{
class ReadFuse: public AvrIspCommandFrame<std::array<unsigned char, 6>>
{
public:
ReadFuse(
Targets::Microchip::Avr::FuseType fuseType,
std::uint8_t returnAddress
)
ReadFuse(Targets::Microchip::Avr8::FuseType fuseType, std::uint8_t returnAddress)
: AvrIspCommandFrame()
{
using Targets::Microchip::Avr::FuseType;
using Targets::Microchip::Avr8::FuseType;
/*
* The read fuse command consists of 6 bytes:
@@ -60,6 +58,9 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::CommandFrames::AvrI
this->payload[5] = 0x00;
break;
}
default: {
throw Exceptions::InternalFatalErrorException{"Unsupported fuse type"};
}
}
}
};

View File

@@ -1,11 +1,11 @@
#pragma once
#include <cstdint>
#include <src/Targets/Microchip/AVR/Fuse.hpp>
#include <src/Targets/Microchip/AVR8/Fuse.hpp>
#include "AvrIspCommandFrame.hpp"
#include "src/Targets/Microchip/AVR/Fuse.hpp"
#include "src/Targets/Microchip/AVR8/Fuse.hpp"
namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::CommandFrames::AvrIsp
{
@@ -18,7 +18,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::CommandFrames::AvrI
)
: AvrIspCommandFrame()
{
using Targets::Microchip::Avr::FuseType;
using Targets::Microchip::Avr8::FuseType;
/*
* The read signature command consists of 6 bytes:

View File

@@ -65,7 +65,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
* CommandFrames::Avr8Generic::GetDeviceId getDeviceIdCommandFrame;
*
* auto responseFrame = edbgInterface->sendAvrCommandFrameAndWaitForResponseFrame(getDeviceIdCommandFrame);
* Targets::Microchip::Avr::TargetSignature avrSignature = responseFrame->extractSignature();
* Targets::Microchip::Avr8::TargetSignature avrSignature = responseFrame->extractSignature();
*
* In the code above, the responseFrame object will be an instance of the ResponseFrames::Avr8Generic::GetDeviceId
* class, which provides the extractSignature() function (to extract the AVR signature from the response frame).
@@ -145,27 +145,30 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
* A vector of sequenced AvrCommands, each containing a segment of the AvrCommandFrame.
*/
[[nodiscard]] std::vector<AvrCommand> generateAvrCommands(std::size_t maximumCommandPacketSize) const {
auto rawCommandFrame = this->getRawCommandFrame();
const auto rawCommandFrame = this->getRawCommandFrame();
std::size_t commandFrameSize = rawCommandFrame.size();
auto commandsRequired = static_cast<std::size_t>(
const auto commandFrameSize = rawCommandFrame.size();
const auto commandsRequired = static_cast<std::size_t>(
std::ceil(static_cast<float>(commandFrameSize) / static_cast<float>(maximumCommandPacketSize))
);
std::vector<AvrCommand> avrCommands;
std::size_t copiedPacketSize = 0;
for (std::size_t i = 0; i < commandsRequired; i++) {
auto avrCommands = std::vector<AvrCommand>{};
auto copiedPacketSize = std::size_t{0};
for (auto i = std::size_t{0}; i < commandsRequired; ++i) {
// If we're on the last packet, the packet size will be what ever is left of the AvrCommandFrame
std::size_t commandPacketSize = ((i + 1) != commandsRequired) ? maximumCommandPacketSize
: (commandFrameSize - (maximumCommandPacketSize * i));
const auto commandPacketSize = static_cast<std::size_t>(
((i + 1) != commandsRequired)
? maximumCommandPacketSize
: (commandFrameSize - (maximumCommandPacketSize * i))
);
avrCommands.emplace_back(AvrCommand(
commandsRequired,
i + 1,
std::vector<unsigned char>(
std::vector<unsigned char>{
rawCommandFrame.begin() + static_cast<std::int64_t>(copiedPacketSize),
rawCommandFrame.begin() + static_cast<std::int64_t>(copiedPacketSize + commandPacketSize)
)
}
));
copiedPacketSize += commandPacketSize;
}

View File

@@ -6,7 +6,7 @@
#include <optional>
#include <cassert>
#include "src/DebugToolDrivers/TargetInterfaces/Microchip/AVR/AVR8/Avr8DebugInterface.hpp"
#include "src/DebugToolDrivers/TargetInterfaces/Microchip/AVR8/Avr8DebugInterface.hpp"
#include "src/DebugToolDrivers/Microchip/Protocols/EDBG/EdbgInterface.hpp"
#include "Avr8Generic.hpp"
@@ -15,10 +15,8 @@
#include "src/Targets/TargetPhysicalInterface.hpp"
#include "src/Targets/TargetMemory.hpp"
#include "src/Targets/TargetRegisterDescriptor.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/TargetParameters.hpp"
#include "src/Targets/Microchip/AVR8/TargetDescriptionFile.hpp"
#include "src/Targets/Microchip/AVR8/Family.hpp"
namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
{
@@ -31,13 +29,13 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
* This implementation should work with any Microchip EDBG-based CMSIS-DAP debug tool (such as the Atmel-ICE,
* Power Debugger, the MPLAB SNAP debugger (in "AVR mode"), etc).
*/
class EdbgAvr8Interface: public ::DebugToolDrivers::TargetInterfaces::Microchip::Avr::Avr8::Avr8DebugInterface
class EdbgAvr8Interface: public ::DebugToolDrivers::TargetInterfaces::Microchip::Avr8::Avr8DebugInterface
{
public:
explicit EdbgAvr8Interface(
EdbgInterface* edbgInterface,
const Targets::Microchip::Avr::Avr8Bit::TargetDescriptionFile& targetDescriptionFile,
const Targets::Microchip::Avr::Avr8Bit::Avr8TargetConfig& targetConfig
const Targets::Microchip::Avr8::TargetDescriptionFile& targetDescriptionFile,
const Targets::Microchip::Avr8::Avr8TargetConfig& targetConfig
);
/**
@@ -140,6 +138,11 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
*/
void deactivate() override;
Targets::TargetRegisterAccess getRegisterAccess(
const Targets::TargetRegisterDescriptor& registerDescriptor,
const Targets::TargetAddressSpaceDescriptor& addressSpaceDescriptor
) override;
/**
* Issues the "PC Read" command to the debug tool, to extract the current program counter.
*
@@ -160,7 +163,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
*
* @return
*/
Targets::Microchip::Avr::TargetSignature getDeviceId() override;
Targets::Microchip::Avr8::TargetSignature getDeviceId() override;
/**
* Issues the "Software Breakpoint Set" command to the debug tool, setting a software breakpoint at the given
@@ -212,27 +215,31 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
* @param descriptorIds
* @return
*/
Targets::TargetRegisters readRegisters(const Targets::TargetRegisterDescriptorIds& descriptorIds) override;
Targets::TargetRegisterDescriptorAndValuePairs readRegisters(
const Targets::TargetRegisterDescriptors& descriptors
) override;
/**
* Writes registers to target.
*
* @param registers
*/
void writeRegisters(const Targets::TargetRegisters& registers) override;
void writeRegisters(const Targets::TargetRegisterDescriptorAndValuePairs& registers) override;
/**
* This is an overloaded method.
*
* Resolves the correct Avr8MemoryType from the given TargetMemoryType and calls readMemory().
*
* @param memoryType
* @param addressSpaceDescriptor
* @param memorySegmentDescriptor
* @param startAddress
* @param bytes
* @return
*/
Targets::TargetMemoryBuffer readMemory(
Targets::TargetMemoryType memoryType,
const Targets::TargetAddressSpaceDescriptor& addressSpaceDescriptor,
const Targets::TargetMemorySegmentDescriptor& memorySegmentDescriptor,
Targets::TargetMemoryAddress startAddress,
Targets::TargetMemorySize bytes,
const std::set<Targets::TargetMemoryAddressRange>& excludedAddressRanges = {}
@@ -243,12 +250,14 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
*
* Resolves the correct Avr8MemoryType from the given TargetMemoryType and calls writeMemory().
*
* @param memoryType
* @param addressSpaceDescriptor
* @param memorySegmentDescriptor
* @param startAddress
* @param buffer
*/
void writeMemory(
Targets::TargetMemoryType memoryType,
const Targets::TargetAddressSpaceDescriptor& addressSpaceDescriptor,
const Targets::TargetMemorySegmentDescriptor& memorySegmentDescriptor,
Targets::TargetMemoryAddress startAddress,
const Targets::TargetMemoryBuffer& buffer
) override;
@@ -259,7 +268,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
* @param section
*/
void eraseProgramMemory(
std::optional<Targets::Microchip::Avr::Avr8Bit::ProgramMemorySection> section = std::nullopt
std::optional<Targets::Microchip::Avr8::ProgramMemorySection> section = std::nullopt
) override;
/**
@@ -272,7 +281,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
*
* @return
*/
Targets::TargetState getTargetState() override;
Targets::TargetExecutionState getExecutionState() override;
/**
* Enters programming mode on the EDBG debug tool.
@@ -311,13 +320,14 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
bool reactivateJtagTargetPostProgrammingMode = false;
/**
* We keep record of the current target state for caching purposes. We'll only refresh the target state if the
* target is running. If it has already stopped, then we assume it cannot transition to a running state without
* an instruction from us.
* We keep record of the current target execution state for caching purposes.
*
* We'll only refresh the target state if the target is running. If it has already stopped, then we assume it
* cannot transition to a running state without an instruction from us.
*
* @TODO: Review this. Is the above assumption correct? Always? Explore the option of polling the target state.
*/
Targets::TargetState targetState = Targets::TargetState::UNKNOWN;
Targets::TargetExecutionState cachedExecutionState = Targets::TargetExecutionState::UNKNOWN;
/**
* Upon configuration, the physical interface must be activated on the debug tool. We keep record of this to
@@ -411,7 +421,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
* 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.
*
* - 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.
* - The setPdiParameters() function sends the required target parameters for PDI sessions.
* - The setUpdiParameters() function sends the required target parameters for UPDI sessions.
@@ -459,6 +469,8 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
*/
void clearEvents();
Avr8MemoryType getRegisterMemoryType(const Targets::TargetRegisterDescriptor& descriptor);
/**
* Checks if alignment is required for memory access via a given Avr8MemoryType.
*
@@ -486,14 +498,13 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
Targets::TargetMemorySize alignMemoryBytes(Avr8MemoryType memoryType, Targets::TargetMemorySize bytes);
/**
* Checks if a maximum memory access size is imposed for a given Avr8MemoryType.
* Determines the maximum memory access size imposed on the given Avr8MemoryType.
*
* @param memoryType
* The imposed maximum size, or std::nullopt if a maximum isn't required.
*
* @return
*/
std::optional<Targets::TargetMemorySize> maximumMemoryAccessSize(Avr8MemoryType memoryType);
Targets::TargetMemorySize maximumMemoryAccessSize(Avr8MemoryType memoryType);
/**
* Reads memory on the target.
@@ -546,7 +557,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
void refreshTargetState();
/**
* Temporarily disables the debugWire module on the target. This does not affect the DWEN fuse. The module
* Temporarily disables the debugWIRE module on the target. This does not affect the DWEN fuse. The module
* will be reactivated upon the cycling of the target power.
*/
void disableDebugWire();
@@ -580,7 +591,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
}
}
std::this_thread::sleep_for(std::chrono::milliseconds(50));
std::this_thread::sleep_for(std::chrono::milliseconds{50});
attemptCount++;
}

View File

@@ -7,13 +7,14 @@
namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
{
EdbgAvr8Session::EdbgAvr8Session(
const Targets::Microchip::Avr::Avr8Bit::TargetDescriptionFile& targetDescriptionFile,
const Targets::Microchip::Avr::Avr8Bit::Avr8TargetConfig& targetConfig
const Targets::Microchip::Avr8::TargetDescriptionFile& targetDescriptionFile,
const Targets::Microchip::Avr8::Avr8TargetConfig& targetConfig
)
: targetDescriptionFile(targetDescriptionFile)
, targetConfig(targetConfig)
, programAddressSpace(this->targetDescriptionFile.getProgramAddressSpace())
, ramAddressSpace(this->targetDescriptionFile.getRamAddressSpace())
, registerFileAddressSpace(this->targetDescriptionFile.getRegisterFileAddressSpace())
, dataAddressSpace(this->targetDescriptionFile.getDataAddressSpace())
, eepromAddressSpace(this->targetDescriptionFile.getEepromAddressSpace())
, ioAddressSpace(this->targetDescriptionFile.getIoAddressSpace())
, signatureAddressSpace(this->targetDescriptionFile.getSignatureAddressSpace())
@@ -38,20 +39,20 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
);
if (!resolvedConfigVariant.has_value()) {
throw Exceptions::Exception(
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::Microchip::Avr8::Family avrFamily,
Targets::TargetPhysicalInterface physicalInterface
) {
using Targets::Microchip::Avr::Avr8Bit::Family;
using Targets::Microchip::Avr8::Family;
using Targets::TargetPhysicalInterface;
if (avrFamily == Family::MEGA || avrFamily == Family::TINY) {

View File

@@ -4,8 +4,8 @@
#include <optional>
#include <functional>
#include "src/Targets/Microchip/AVR/AVR8/TargetDescriptionFile.hpp"
#include "src/Targets/Microchip/AVR/AVR8/Avr8TargetConfig.hpp"
#include "src/Targets/Microchip/AVR8/TargetDescriptionFile.hpp"
#include "src/Targets/Microchip/AVR8/Avr8TargetConfig.hpp"
#include "src/Targets/TargetMemorySegmentDescriptor.hpp"
#include "src/Targets/TargetRegisterDescriptor.hpp"
@@ -21,12 +21,12 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
/**
* AVR8 TDF, from which we extract all target info to configure the EDBG debug tool.
*/
const Targets::Microchip::Avr::Avr8Bit::TargetDescriptionFile& targetDescriptionFile;
const Targets::Microchip::Avr8::TargetDescriptionFile& targetDescriptionFile;
/**
* Project's AVR8 target configuration.
*/
const Targets::Microchip::Avr::Avr8Bit::Avr8TargetConfig& targetConfig;
const Targets::Microchip::Avr8::Avr8TargetConfig& targetConfig;
/**
* The EDBG config variant parameter.
@@ -37,7 +37,8 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
Avr8ConfigVariant configVariant = Avr8ConfigVariant::NONE;
const Targets::TargetDescription::AddressSpace& programAddressSpace;
const Targets::TargetDescription::AddressSpace& ramAddressSpace;
const Targets::TargetDescription::AddressSpace& registerFileAddressSpace;
const Targets::TargetDescription::AddressSpace& dataAddressSpace;
const Targets::TargetDescription::AddressSpace& eepromAddressSpace;
const Targets::TargetDescription::AddressSpace& ioAddressSpace;
const Targets::TargetDescription::AddressSpace& signatureAddressSpace;
@@ -59,8 +60,8 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
std::optional<std::uint8_t> ocdDataRegister;
EdbgAvr8Session(
const Targets::Microchip::Avr::Avr8Bit::TargetDescriptionFile& targetDescriptionFile,
const Targets::Microchip::Avr::Avr8Bit::Avr8TargetConfig& targetConfig
const Targets::Microchip::Avr8::TargetDescriptionFile& targetDescriptionFile,
const Targets::Microchip::Avr8::Avr8TargetConfig& targetConfig
);
private:
@@ -75,7 +76,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
* any particular EDBG config variant.
*/
static std::optional<Avr8ConfigVariant> tryResolveConfigVariant(
Targets::Microchip::Avr::Avr8Bit::Family avrFamily,
Targets::Microchip::Avr8::Family avrFamily,
Targets::TargetPhysicalInterface physicalInterface
);
};

View File

@@ -1,6 +1,7 @@
#include "EdbgAvrIspInterface.hpp"
#include "src/TargetController/Exceptions/TargetOperationFailure.hpp"
#include "src/Exceptions/InternalFatalErrorException.hpp"
#include "src/Logger/Logger.hpp"
// Command frames
@@ -13,7 +14,7 @@
namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
{
using namespace Targets::Microchip::Avr;
using namespace Targets::Microchip::Avr8;
using CommandFrames::AvrIsp::EnterProgrammingMode;
using CommandFrames::AvrIsp::LeaveProgrammingMode;
@@ -26,17 +27,17 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
using Exceptions::TargetOperationFailure;
EdbgAvrIspInterface::EdbgAvrIspInterface(EdbgInterface* edbgInterface)
EdbgAvrIspInterface::EdbgAvrIspInterface(
EdbgInterface* edbgInterface,
const TargetDescriptionFile& targetDescriptionFile
)
: edbgInterface(edbgInterface)
, ispParameters(IspParameters{targetDescriptionFile})
{}
void EdbgAvrIspInterface::setIspParameters(const Targets::Microchip::Avr::IspParameters& ispParameters) {
this->ispParameters = ispParameters;
}
void EdbgAvrIspInterface::activate() {
const auto responseFrame = this->edbgInterface->sendAvrCommandFrameAndWaitForResponseFrame(
EnterProgrammingMode(
EnterProgrammingMode{
this->ispParameters.programModeTimeout,
this->ispParameters.programModeStabilizationDelay,
this->ispParameters.programModeCommandExecutionDelay,
@@ -44,42 +45,35 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
this->ispParameters.programModeByteDelay,
this->ispParameters.programModePollValue,
this->ispParameters.programModePollIndex
)
}
);
if (responseFrame.statusCode != StatusCode::OK) {
throw TargetOperationFailure(
throw TargetOperationFailure{
"Failed to enable programming mode via the ISP interface - check target's SPI connection "
"and/or its SPIEN fuse bit."
);
};
}
}
void EdbgAvrIspInterface::deactivate() {
const auto responseFrame = this->edbgInterface->sendAvrCommandFrameAndWaitForResponseFrame(
LeaveProgrammingMode(
this->ispParameters.programModePreDelay,
this->ispParameters.programModePostDelay
)
LeaveProgrammingMode{this->ispParameters.programModePreDelay, this->ispParameters.programModePostDelay}
);
if (responseFrame.statusCode != StatusCode::OK) {
throw TargetOperationFailure("Failed to disable programming mode via the ISP interface.");
throw TargetOperationFailure{"Failed to disable programming mode via the ISP interface."};
}
}
TargetSignature EdbgAvrIspInterface::getDeviceId() {
// The read signature command only allows us to read one signature byte at a time.
return TargetSignature(
this->readSignatureByte(0),
this->readSignatureByte(1),
this->readSignatureByte(2)
);
return {this->readSignatureByte(0), this->readSignatureByte(1), this->readSignatureByte(2)};
}
Fuse EdbgAvrIspInterface::readFuse(FuseType fuseType) {
FuseValue EdbgAvrIspInterface::readFuse(const Targets::TargetRegisterDescriptor& fuseRegisterDescriptor) {
const auto responseFrame = this->edbgInterface->sendAvrCommandFrameAndWaitForResponseFrame(
ReadFuse(fuseType, this->ispParameters.readFusePollIndex)
ReadFuse{this->resolveFuseType(fuseRegisterDescriptor), this->ispParameters.readFusePollIndex}
);
if (
@@ -87,17 +81,17 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|| responseFrame.payload.size() < 4
|| static_cast<StatusCode>(responseFrame.payload[3]) != StatusCode::OK
) {
throw TargetOperationFailure(
throw TargetOperationFailure{
"Failed to read fuse via ISP - response frame status code/size indicates a failure."
);
};
}
return Fuse(fuseType, responseFrame.payload[2]);
return static_cast<FuseValue>(responseFrame.payload[2]);
}
unsigned char EdbgAvrIspInterface::readLockBitByte() {
const auto responseFrame = this->edbgInterface->sendAvrCommandFrameAndWaitForResponseFrame(
ReadLock(this->ispParameters.readLockPollIndex)
ReadLock{this->ispParameters.readLockPollIndex}
);
if (
@@ -105,29 +99,32 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|| responseFrame.payload.size() < 4
|| static_cast<StatusCode>(responseFrame.payload[3]) != StatusCode::OK
) {
throw TargetOperationFailure(
throw TargetOperationFailure{
"Failed to read lock bit byte via ISP - response frame status code/size indicates a failure."
);
};
}
return responseFrame.payload[2];
}
void EdbgAvrIspInterface::programFuse(Targets::Microchip::Avr::Fuse fuse) {
void EdbgAvrIspInterface::programFuse(
const Targets::TargetRegisterDescriptor& fuseRegisterDescriptor,
FuseValue value
) {
const auto responseFrame = this->edbgInterface->sendAvrCommandFrameAndWaitForResponseFrame(
ProgramFuse(fuse.type, fuse.value)
ProgramFuse{this->resolveFuseType(fuseRegisterDescriptor), value}
);
if (responseFrame.statusCode != StatusCode::OK || responseFrame.payload.size() < 2) {
throw TargetOperationFailure(
throw TargetOperationFailure{
"Failed to program fuse via ISP - response frame status code/size indicates a failure."
);
};
}
}
unsigned char EdbgAvrIspInterface::readSignatureByte(std::uint8_t signatureByteAddress) {
const auto responseFrame = this->edbgInterface->sendAvrCommandFrameAndWaitForResponseFrame(
ReadSignature(signatureByteAddress, this->ispParameters.readSignaturePollIndex)
ReadSignature{signatureByteAddress, this->ispParameters.readSignaturePollIndex}
);
if (
@@ -135,12 +132,30 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
|| responseFrame.payload.size() < 4
|| static_cast<StatusCode>(responseFrame.payload[3]) != StatusCode::OK
) {
throw TargetOperationFailure(
throw TargetOperationFailure{
"Failed to read signature byte (address: " + std::to_string(signatureByteAddress)
+ ") via ISP - response frame status code/size indicates a failure."
);
};
}
return responseFrame.payload[2];
}
FuseType EdbgAvrIspInterface::resolveFuseType(const Targets::TargetRegisterDescriptor& fuseRegisterDescriptor) {
if (fuseRegisterDescriptor.key == "low") {
return FuseType::LOW;
}
if (fuseRegisterDescriptor.key == "high") {
return FuseType::HIGH;
}
if (fuseRegisterDescriptor.key == "extended") {
return FuseType::EXTENDED;
}
throw Exceptions::InternalFatalErrorException{
"Could not resolve fuse type from register descriptor (key: \"" + fuseRegisterDescriptor.key + "\")"
};
}
}

View File

@@ -5,8 +5,9 @@
#include <thread>
#include <cassert>
#include "src/DebugToolDrivers/TargetInterfaces/Microchip/AVR/AvrIspInterface.hpp"
#include "src/DebugToolDrivers/TargetInterfaces/Microchip/AVR8/AvrIspInterface.hpp"
#include "src/DebugToolDrivers/Microchip/Protocols/EDBG/EdbgInterface.hpp"
#include "src/Targets/Microchip/AVR8/TargetDescriptionFile.hpp"
namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
{
@@ -19,25 +20,13 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
* This implementation should work with any Microchip EDBG-based CMSIS-DAP debug tool with ISP support (such as
* the Atmel-ICE, Power Debugger, the MPLAB SNAP debugger (in "AVR mode"), etc).
*/
class EdbgAvrIspInterface: public TargetInterfaces::Microchip::Avr::AvrIspInterface
class EdbgAvrIspInterface: public TargetInterfaces::Microchip::Avr8::AvrIspInterface
{
public:
explicit EdbgAvrIspInterface(EdbgInterface* edbgInterface);
/**
* The EdbgAvrIspInterface doesn't actually require any config from the user, at this point in time. So this
* function does nothing, for now.
*
* @param targetConfig
*/
void configure(const TargetConfig& targetConfig) override {};
/**
* Accepts the target's ISP parameters. These should be extracted from the target's TDF.
*
* @param ispParameters
*/
void setIspParameters(const Targets::Microchip::Avr::IspParameters& ispParameters) override;
explicit EdbgAvrIspInterface(
EdbgInterface* edbgInterface,
const Targets::Microchip::Avr8::TargetDescriptionFile& targetDescriptionFile
);
/**
* Initialises the ISP interface by enabling "programming mode" on the debug tool. This will activate the
@@ -56,15 +45,17 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
*
* @return
*/
Targets::Microchip::Avr::TargetSignature getDeviceId() override;
Targets::Microchip::Avr8::TargetSignature getDeviceId() override;
/**
* Reads a particular fuse byte from the AVR target.
*
* @param fuseType
* @param fuseRegisterDescriptor
* @return
*/
Targets::Microchip::Avr::Fuse readFuse(Targets::Microchip::Avr::FuseType fuseType) override;
Targets::Microchip::Avr8::FuseValue readFuse(
const Targets::TargetRegisterDescriptor& fuseRegisterDescriptor
) override;
/**
* Reads the lock bit byte from the AVR target.
@@ -76,9 +67,13 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
/**
* Programs a particular fuse on the AVR target.
*
* @param fuse
* @param fuseRegisterDescriptor
* @param value
*/
void programFuse(Targets::Microchip::Avr::Fuse fuse) override;
void programFuse(
const Targets::TargetRegisterDescriptor& fuseRegisterDescriptor,
Targets::Microchip::Avr8::FuseValue value
) override;
private:
/**
@@ -89,7 +84,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
*/
EdbgInterface* edbgInterface;
Targets::Microchip::Avr::IspParameters ispParameters;
Targets::Microchip::Avr8::IspParameters ispParameters;
/**
* The EDBG AVRISP protocol only allows us to read a single signature byte at a time.
@@ -100,5 +95,9 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
* @return
*/
[[nodiscard]] unsigned char readSignatureByte(std::uint8_t signatureByteAddress);
Targets::Microchip::Avr8::FuseType resolveFuseType(
const Targets::TargetRegisterDescriptor& fuseRegisterDescriptor
);
};
}

View File

@@ -19,7 +19,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
* 1 byte for break cause
* 2 bytes for extended info
*/
throw Exception("Failed to process BreakEvent from AvrEvent - unexpected packet size.");
throw Exception{"Failed to process BreakEvent from AvrEvent - unexpected packet size."};
}
// Program counter consists of 4 bytes

View File

@@ -68,7 +68,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
}
explicit Avr8CommandFailure(const char* message): TargetOperationFailure(message) {
this->message = std::string(message);
this->message = std::string{message};
}
explicit Avr8CommandFailure(
@@ -95,7 +95,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
}
private:
static const inline auto failureCodeToDescription = std::map<Avr8CommandFailureCode, std::string>({
static const inline auto failureCodeToDescription = std::map<Avr8CommandFailureCode, std::string>{
{Avr8CommandFailureCode::DEBUGWIRE_PHYSICAL_ERROR, "debugWIRE physical error"},
{Avr8CommandFailureCode::JTAGM_FAILED_TO_INITIALISE, "JTAGM failed to initialise"},
{Avr8CommandFailureCode::UNKNOWN_JTAG_ERROR, "JTAGM did something strange"},
@@ -143,6 +143,6 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
{Avr8CommandFailureCode::FEATURE_NOT_AVAILABLE, "Feature not available"},
{Avr8CommandFailureCode::UNKNOWN_COMMAND, "Command has not been implemented"},
{Avr8CommandFailureCode::UNKNOWN_ERROR, "Unknown error reported by EDBG device"},
});
};
};
}

View File

@@ -1,13 +1,12 @@
#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
const Targets::Microchip::Avr8::TargetDescriptionFile& targetDescriptionFile
) {
using Services::StringService;
@@ -55,7 +54,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::Parameters::Avr8Gen
this->eearAddressLow = static_cast<std::uint8_t>(eearlDescriptor.startAddress);
/*
* Some debugWire targets only have a single-byte `EEARL` register.
* Some debugWIRE targets only have a single-byte `EEARL` register.
*
* In the absence of an `EEARH` register, and if there is no high byte in the `EEARL` register, the
* `eearAddressHigh` parameter should be equal to the `eearAddressLow` parameter, as stated in the
@@ -80,8 +79,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::Parameters::Avr8Gen
const auto cpuPeripheralDescriptor = targetDescriptionFile.getTargetPeripheralDescriptor("cpu");
const auto& cpuRegisterGroupDescriptor = cpuPeripheralDescriptor.getRegisterGroupDescriptor("cpu");
const auto spmcsrDescriptor = cpuRegisterGroupDescriptor.tryGetRegisterDescriptor("spmcsr")
?: cpuRegisterGroupDescriptor.tryGetRegisterDescriptor("spmcr");
const auto spmcsrDescriptor = cpuRegisterGroupDescriptor.tryGetFirstRegisterDescriptor({"spmcsr", "spmcr"});
if (spmcsrDescriptor.has_value()) {
this->spmcrAddress = static_cast<std::uint8_t>(spmcsrDescriptor->get().startAddress);
@@ -90,24 +88,27 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::Parameters::Avr8Gen
const auto bootLoadPeripheral = targetDescriptionFile.getTargetPeripheralDescriptor("boot_load");
const auto& bootLoaderRegisterGroupDescriptor = bootLoadPeripheral.getRegisterGroupDescriptor("boot_load");
const auto spmcsrDescriptor = bootLoaderRegisterGroupDescriptor.tryGetRegisterDescriptor("spmcsr")
?: bootLoaderRegisterGroupDescriptor.tryGetRegisterDescriptor("spmcr");
const auto spmcsrDescriptor = bootLoaderRegisterGroupDescriptor.tryGetFirstRegisterDescriptor(
{"spmcsr", "spmcr"}
);
if (!spmcsrDescriptor.has_value()) {
throw Exceptions::InternalFatalErrorException("Could not extract SPMCS register from TDF");
throw Exceptions::InternalFatalErrorException{"Could not extract SPMCS register from TDF"};
}
this->spmcrAddress = 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");
const auto osccalDescriptor = cpuRegisterGroupDescriptor.tryGetFirstRegisterDescriptor({
"osccal",
"osccal0",
"osccal1",
"fosccal",
"sosccala",
});
if (!osccalDescriptor.has_value()) {
throw Exceptions::InternalFatalErrorException("Could not extract OSCCAL register from TDF");
throw Exceptions::InternalFatalErrorException{"Could not extract OSCCAL register from TDF"};
}
this->osccalAddress = static_cast<std::uint8_t>(osccalDescriptor->get().startAddress);

View File

@@ -3,12 +3,12 @@
#include <cstdint>
#include <optional>
#include "src/Targets/Microchip/AVR/AVR8/TargetDescriptionFile.hpp"
#include "src/Targets/Microchip/AVR8/TargetDescriptionFile.hpp"
namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::Parameters::Avr8Generic
{
/**
* EDBG parameters for debugWire and JTAG AVR targets.
* EDBG parameters for debugWIRE and JTAG AVR targets.
*
* See Microchip's "EDBG-based Tools Protocols" document for more on these parameters.
*/
@@ -30,6 +30,6 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::Parameters::Avr8Gen
std::uint8_t spmcrAddress;
std::uint8_t osccalAddress;
DebugWireJtagParameters(const Targets::Microchip::Avr::Avr8Bit::TargetDescriptionFile& targetDescriptionFile);
DebugWireJtagParameters(const Targets::Microchip::Avr8::TargetDescriptionFile& targetDescriptionFile);
};
}

View File

@@ -4,9 +4,7 @@
namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::Parameters::Avr8Generic
{
PdiParameters::PdiParameters(
const Targets::Microchip::Avr::Avr8Bit::TargetDescriptionFile& targetDescriptionFile
) {
PdiParameters::PdiParameters(const Targets::Microchip::Avr8::TargetDescriptionFile& targetDescriptionFile) {
using Services::StringService;
const auto& pdiGroup = targetDescriptionFile.getPropertyGroup("pdi_interface");

View File

@@ -2,7 +2,7 @@
#include <cstdint>
#include "src/Targets/Microchip/AVR/AVR8/TargetDescriptionFile.hpp"
#include "src/Targets/Microchip/AVR8/TargetDescriptionFile.hpp"
namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::Parameters::Avr8Generic
{
@@ -29,6 +29,6 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::Parameters::Avr8Gen
std::uint16_t nvmModuleBaseAddress;
std::uint16_t signaturesPdiOffset;
PdiParameters(const Targets::Microchip::Avr::Avr8Bit::TargetDescriptionFile& targetDescriptionFile);
PdiParameters(const Targets::Microchip::Avr8::TargetDescriptionFile& targetDescriptionFile);
};
}

View File

@@ -4,9 +4,7 @@
namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::Parameters::Avr8Generic
{
UpdiParameters::UpdiParameters(
const Targets::Microchip::Avr::Avr8Bit::TargetDescriptionFile& targetDescriptionFile
) {
UpdiParameters::UpdiParameters(const Targets::Microchip::Avr8::TargetDescriptionFile& targetDescriptionFile) {
using Services::StringService;
const auto& updiGroup = targetDescriptionFile.getPropertyGroup("updi_interface");

View File

@@ -2,7 +2,7 @@
#include <cstdint>
#include "src/Targets/Microchip/AVR/AVR8/TargetDescriptionFile.hpp"
#include "src/Targets/Microchip/AVR8/TargetDescriptionFile.hpp"
namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::Parameters::Avr8Generic
{
@@ -28,6 +28,6 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::Parameters::Avr8Gen
std::uint16_t fuseSegmentStartAddress;
std::uint16_t lockbitSegmentStartAddress;
UpdiParameters(const Targets::Microchip::Avr::Avr8Bit::TargetDescriptionFile& targetDescriptionFile);
UpdiParameters(const Targets::Microchip::Avr8::TargetDescriptionFile& targetDescriptionFile);
};
}

View File

@@ -10,7 +10,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::ResponseFrames::Avr
: AvrResponseFrame(avrResponses)
{
if (this->payload.empty()) {
throw Exception("Response ID missing from AVR8 Generic response frame payload.");
throw Exception{"Response ID missing from AVR8 Generic response frame payload."};
}
this->id = static_cast<Avr8ResponseId>(this->payload[0]);
@@ -21,11 +21,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::ResponseFrames::Avr
* AVR8 data payloads are in little endian form and include two bytes before the data (response ID and
* version byte) as well as an additional byte after the data, known as the 'status code'.
*/
auto data = std::vector<unsigned char>(
this->payload.begin() + 2,
this->payload.end() - 1
);
auto data = std::vector<unsigned char>{this->payload.begin() + 2, this->payload.end() - 1};
std::reverse(data.begin(), data.end());
return data;
}

View File

@@ -6,10 +6,12 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::ResponseFrames::Avr
: Avr8GenericResponseFrame(AvrResponses)
{}
Targets::Microchip::Avr::TargetSignature GetDeviceId::extractSignature(
Targets::Microchip::Avr8::TargetSignature GetDeviceId::extractSignature(
Targets::TargetPhysicalInterface physicalInterface
) const {
using Targets::TargetPhysicalInterface;
using Targets::Microchip::Avr8::TargetSignature;
const auto payloadData = this->getPayloadData();
switch (physicalInterface) {
@@ -18,14 +20,14 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::ResponseFrames::Avr
* When using the DebugWire physical interface, the get device ID command will return
* four bytes, where the first can be ignored.
*/
return Targets::Microchip::Avr::TargetSignature(payloadData[1], payloadData[2], payloadData[3]);
return TargetSignature{payloadData[1], payloadData[2], payloadData[3]};
}
case TargetPhysicalInterface::PDI:
case TargetPhysicalInterface::UPDI: {
/*
* When using the PDI physical interface, the signature is returned in LSB format.
*/
return Targets::Microchip::Avr::TargetSignature(payloadData[3], payloadData[2], payloadData[1]);
return TargetSignature{payloadData[3], payloadData[2], payloadData[1]};
}
case TargetPhysicalInterface::JTAG: {
/*
@@ -50,18 +52,14 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::ResponseFrames::Avr
(payloadData[0] << 24) | (payloadData[1] << 16) | (payloadData[2] << 8) | (payloadData[3])
);
return Targets::Microchip::Avr::TargetSignature(
return TargetSignature{
0x1E,
static_cast<unsigned char>((jtagId << 4) >> 24),
static_cast<unsigned char>((jtagId << 12) >> 24)
);
};
}
default: {
return Targets::Microchip::Avr::TargetSignature(
payloadData[0],
payloadData[1],
payloadData[2]
);
return TargetSignature{payloadData[0], payloadData[1], payloadData[2]};
}
}
}

View File

@@ -2,7 +2,7 @@
#include "Avr8GenericResponseFrame.hpp"
#include "src/Targets/Microchip/AVR/TargetSignature.hpp"
#include "src/Targets/Microchip/AVR8/TargetSignature.hpp"
#include "src/Targets/TargetPhysicalInterface.hpp"
namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::ResponseFrames::Avr8Generic
@@ -12,7 +12,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::ResponseFrames::Avr
public:
explicit GetDeviceId(const std::vector<AvrResponse>& AvrResponses);
Targets::Microchip::Avr::TargetSignature extractSignature(
Targets::Microchip::Avr8::TargetSignature extractSignature(
Targets::TargetPhysicalInterface physicalInterface
) const;
};

View File

@@ -23,8 +23,10 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::ResponseFrames::Avr
* command ID and version, the other four being the PC. The four PC bytes are little-endian.
*/
if (this->payload.size() != 6) {
throw Exceptions::Exception("Failed to extract PC from payload of PC read command response "
"frame - unexpected payload size.");
throw Exceptions::Exception{
"Failed to extract PC from payload of PC read command response "
"frame - unexpected payload size."
};
}
return static_cast<Targets::TargetMemoryAddress>(

View File

@@ -17,10 +17,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::ResponseFrames::Avr
* AVR8 data payloads are typically in little endian form, but this does not apply to the data returned
* from the READ MEMORY commands.
*/
return std::vector<unsigned char>(
this->payload.begin() + 2,
this->payload.end() - 1
);
return {this->payload.begin() + 2, this->payload.end() - 1};
}
};
}

View File

@@ -10,7 +10,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::ResponseFrames::Avr
: AvrResponseFrame(avrResponses)
{
if (this->payload.size() < 2) {
throw Exception("Status code missing from AVRISP response frame payload.");
throw Exception{"Status code missing from AVRISP response frame payload."};
}
this->statusCode = static_cast<StatusCode>(this->payload[1]);

View File

@@ -8,7 +8,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
void AvrResponseFrame::initFromAvrResponses(const std::vector<AvrResponse>& avrResponses) {
// Build a raw frame buffer from the AvrResponse objects and just call initFromRawFrame()
auto rawFrame = std::vector<unsigned char>();
auto rawFrame = std::vector<unsigned char>{};
for (const auto& avrResponse : avrResponses) {
rawFrame.insert(rawFrame.end(), avrResponse.responsePacket.begin(), avrResponse.responsePacket.end());
@@ -23,12 +23,12 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr
* All AVR response frames must consist of at least four bytes (SOF, sequence ID (two bytes) and
* a protocol handler ID).
*/
throw Exception("Failed to construct AvrResponseFrame - unexpected end to raw frame");
throw Exception{"Failed to construct AvrResponseFrame - unexpected end to raw frame"};
}
if (rawFrame[0] != 0x0E) {
// Invalid SOF byte value
throw Exception("Failed to construct AvrResponseFrame - unexpected SOF byte value in raw frame");
throw Exception{"Failed to construct AvrResponseFrame - unexpected SOF byte value in raw frame"};
}
this->sequenceId = static_cast<std::uint16_t>((rawFrame[2] << 8) + rawFrame[1]);

View File

@@ -10,7 +10,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::ResponseFrames::Dis
: AvrResponseFrame(avrResponses)
{
if (this->payload.empty()) {
throw Exception("Response ID missing from DISCOVERY response frame payload.");
throw Exception{"Response ID missing from DISCOVERY response frame payload."};
}
this->id = static_cast<ResponseId>(payload[0]);
@@ -22,9 +22,6 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::ResponseFrames::Dis
}
// DISCOVERY payloads include two bytes before the data (response ID and version byte).
return std::vector<unsigned char>(
this->payload.begin() + 2,
this->payload.end()
);
return {this->payload.begin() + 2, this->payload.end()};
}
}

View File

@@ -10,7 +10,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::ResponseFrames::Edb
: AvrResponseFrame(avrResponses)
{
if (this->payload.empty()) {
throw Exception("Response ID missing from EDBG Control response frame payload.");
throw Exception{"Response ID missing from EDBG Control response frame payload."};
}
this->id = static_cast<EdbgControlResponseId>(this->payload[0]);
@@ -25,9 +25,6 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::ResponseFrames::Edb
* EDBG Control data payloads include two bytes before the data (response ID and version byte) as well as an
* additional byte after the data, known as the 'status code'.
*/
return std::vector<unsigned char>(
this->payload.begin() + 2,
this->payload.end() - 1
);
return {this->payload.begin() + 2, this->payload.end() - 1};
}
}

View File

@@ -10,7 +10,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg::Avr::ResponseFrames::Hou
: AvrResponseFrame(avrResponses)
{
if (this->payload.empty()) {
throw Exception("Response ID missing from HOUSEKEEPING response frame payload.");
throw Exception{"Response ID missing from HOUSEKEEPING response frame payload."};
}
this->id = static_cast<ResponseId>(this->payload[0]);

View File

@@ -25,26 +25,25 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg
}
// This should never happen
throw DeviceCommunicationFailure(
throw DeviceCommunicationFailure{
"Cannot send AVR command frame - failed to generate CMSIS-DAP Vendor (AVR) commands"
);
};
}
std::optional<Microchip::Protocols::Edbg::Avr::AvrEvent> EdbgInterface::requestAvrEvent() {
auto avrEventResponse = this->sendCommandAndWaitForResponse(Avr::AvrEventCommand());
auto avrEventResponse = this->sendCommandAndWaitForResponse(Avr::AvrEventCommand{});
if (avrEventResponse.id != 0x82) {
throw DeviceCommunicationFailure("Unexpected response to AvrEventCommand from device");
}
return !avrEventResponse.eventData.empty() ? std::optional(avrEventResponse) : std::nullopt;
return !avrEventResponse.eventData.empty() ? std::optional{avrEventResponse} : std::nullopt;
}
std::vector<Microchip::Protocols::Edbg::Avr::AvrResponse> EdbgInterface::requestAvrResponses() {
using Microchip::Protocols::Edbg::Avr::AvrResponseCommand;
std::vector<Microchip::Protocols::Edbg::Avr::AvrResponse> responses;
AvrResponseCommand responseCommand;
auto responses = std::vector<Microchip::Protocols::Edbg::Avr::AvrResponse>{};
const auto responseCommand = AvrResponseCommand{};
auto avrResponse = this->sendCommandAndWaitForResponse(responseCommand);
responses.push_back(avrResponse);
@@ -55,15 +54,13 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg
auto avrResponse = this->sendCommandAndWaitForResponse(responseCommand);
if (avrResponse.fragmentCount != fragmentCount) {
throw DeviceCommunicationFailure(
throw DeviceCommunicationFailure{
"Failed to fetch AvrResponse objects - invalid fragment count returned."
);
};
}
if (avrResponse.fragmentCount == 0 && avrResponse.fragmentNumber == 0) {
throw DeviceCommunicationFailure(
"Failed to fetch AvrResponse objects - unexpected empty response"
);
throw DeviceCommunicationFailure{"Failed to fetch AvrResponse objects - unexpected empty response"};
}
if (avrResponse.fragmentNumber == 0) {

View File

@@ -23,7 +23,7 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg
* The EdbgInterface class implements the EDBG sub-protocol, which takes the form of numerous CMSIS-DAP vendor
* commands.
*/
class EdbgInterface: public ::DebugToolDrivers::Protocols::CmsisDap::CmsisDapInterface
class EdbgInterface: public ::DebugToolDrivers::Protocols::CmsisDap::CmsisDapInterface
{
public:
explicit EdbgInterface(Usb::HidInterface&& cmsisHidInterface);
@@ -71,9 +71,9 @@ class EdbgInterface: public ::DebugToolDrivers::Protocols::CmsisDap::CmsisDapInt
if (response.data[0] != 0x01) {
// The last response packet should always acknowledge receipt of the AvrCommandFrame
throw Exceptions::DeviceCommunicationFailure(
throw Exceptions::DeviceCommunicationFailure{
"Failed to send AvrCommandFrame to device - device did not acknowledge receipt."
);
};
}
return typename CommandFrameType::ExpectedResponseFrameType(this->requestAvrResponses());

View File

@@ -18,21 +18,21 @@ namespace DebugToolDrivers::Microchip::Protocols::Edbg
void EdbgTargetPowerManagementInterface::enableTargetPower() {
const auto responseFrame = this->edbgInterface->sendAvrCommandFrameAndWaitForResponseFrame(
SetParameter(EdbgParameters::CONTROL_TARGET_POWER, 0x01)
SetParameter{EdbgParameters::CONTROL_TARGET_POWER, 0x01}
);
if (responseFrame.id == EdbgControlResponseId::FAILED) {
throw Exception("Failed to enable target power via EDBG Control protocol");
throw Exception{"Failed to enable target power via EDBG Control protocol"};
}
}
void EdbgTargetPowerManagementInterface::disableTargetPower() {
const auto responseFrame = this->edbgInterface->sendAvrCommandFrameAndWaitForResponseFrame(
SetParameter(EdbgParameters::CONTROL_TARGET_POWER, 0x00)
SetParameter{EdbgParameters::CONTROL_TARGET_POWER, 0x00}
);
if (responseFrame.id == EdbgControlResponseId::FAILED) {
throw Exception("Failed to disable target power via EDBG Control protocol");
throw Exception{"Failed to disable target power via EDBG Control protocol"};
}
}
}