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:
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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:
|
||||
/*
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
*/
|
||||
|
||||
@@ -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"};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"};
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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++;
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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 + "\")"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"},
|
||||
});
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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]};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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>(
|
||||
|
||||
@@ -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};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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()};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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"};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user