From 5eabf145c2d5339bf6576dc54b92e78a621e1a92 Mon Sep 17 00:00:00 2001 From: Nav Date: Thu, 2 Jun 2022 22:24:37 +0100 Subject: [PATCH] Erasing XMEGA application section upon entering programming mode --- .../VendorSpecific/EDBG/AVR/Avr8Generic.hpp | 8 +++++ .../CommandFrames/AVR8Generic/EraseMemory.hpp | 31 +++++++++++++++++++ .../EDBG/AVR/EdbgAvr8Interface.cpp | 18 +++++++++++ .../EDBG/AVR/EdbgAvr8Interface.hpp | 7 +++++ 4 files changed, 64 insertions(+) create mode 100644 src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/CommandFrames/AVR8Generic/EraseMemory.hpp diff --git a/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/Avr8Generic.hpp b/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/Avr8Generic.hpp index f3b110b8..4401346e 100644 --- a/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/Avr8Generic.hpp +++ b/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/Avr8Generic.hpp @@ -179,4 +179,12 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr inline bool operator == (Avr8ResponseId id, unsigned char rawId) { return rawId == id; } + + enum class Avr8EraseMemoryMode: unsigned char + { + CHIP = 0x00, + APPLICATION_SECTION = 0x01, + BOOT_SECTION = 0x02, + EEPROM = 0x03, + }; } diff --git a/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/CommandFrames/AVR8Generic/EraseMemory.hpp b/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/CommandFrames/AVR8Generic/EraseMemory.hpp new file mode 100644 index 00000000..3da4676a --- /dev/null +++ b/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/CommandFrames/AVR8Generic/EraseMemory.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include + +#include "Avr8GenericCommandFrame.hpp" + +namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::CommandFrames::Avr8Generic +{ + class EraseMemory: public Avr8GenericCommandFrame> + { + public: + EraseMemory(Avr8EraseMemoryMode mode) { + /* + * The erase memory command consists of 7 bytes: + * 1. Command ID (0x20) + * 2. Version (0x00) + * 3. Erase mode (see Avr8EraseMemoryMode enum) + * 4. Start address (4 bytes) - this is just hardcoded to 0x00000000 for now. + */ + this->payload = { + 0x20, + 0x00, + static_cast(mode), + 0x00, + 0x00, + 0x00, + 0x00, + }; + } + }; +} diff --git a/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/EdbgAvr8Interface.cpp b/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/EdbgAvr8Interface.cpp index 9b746658..0b42b6c5 100644 --- a/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/EdbgAvr8Interface.cpp +++ b/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/EdbgAvr8Interface.cpp @@ -36,6 +36,7 @@ #include "src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/CommandFrames/AVR8Generic/ClearSoftwareBreakpoints.hpp" #include "src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/CommandFrames/AVR8Generic/EnterProgrammingMode.hpp" #include "src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/CommandFrames/AVR8Generic/LeaveProgrammingMode.hpp" +#include "src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/CommandFrames/AVR8Generic/EraseMemory.hpp" // AVR events #include "src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/Events/AVR8Generic/BreakEvent.hpp" @@ -691,6 +692,13 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr } this->programmingModeEnabled = true; + + if (this->configVariant == Avr8ConfigVariant::XMEGA) { + Logger::warning( + "The entire application section of program memory will be erased, in preparation for programming" + ); + this->eraseMemory(Avr8EraseMemoryMode::APPLICATION_SECTION); + } } void EdbgAvr8Interface::disableProgrammingMode() { @@ -1659,6 +1667,16 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr if (response.getResponseId() == Avr8ResponseId::FAILED) { throw Avr8CommandFailure("AVR8 Write memory command failed", response); } + + + void EdbgAvr8Interface::eraseMemory(Avr8EraseMemoryMode mode) { + auto response = this->edbgInterface.sendAvrCommandFrameAndWaitForResponseFrame( + CommandFrames::Avr8Generic::EraseMemory(mode) + ); + + if (response.getResponseId() == Avr8ResponseId::FAILED) { + throw Avr8CommandFailure("AVR8 erase memory command failed", response); + } } void EdbgAvr8Interface::refreshTargetState() { diff --git a/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/EdbgAvr8Interface.hpp b/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/EdbgAvr8Interface.hpp index 3cb5714b..c81e6a40 100644 --- a/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/EdbgAvr8Interface.hpp +++ b/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/EdbgAvr8Interface.hpp @@ -537,6 +537,13 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr */ void writeMemory(Avr8MemoryType type, std::uint32_t address, const Targets::TargetMemoryBuffer& buffer); + /** + * Erases a particular region of memory, depending on the value of mode. + * + * @param mode + */ + void eraseMemory(Avr8EraseMemoryMode mode); + /** * Fetches the current target state. *