Added support for writing to EEPROM via EDBG AVR8 Generic driver

This commit is contained in:
Nav
2022-12-08 21:08:35 +00:00
parent 6ec383b0a3
commit 96a688df08
5 changed files with 155 additions and 110 deletions

View File

@@ -367,51 +367,8 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit
}
void Avr8::writeMemory(TargetMemoryType memoryType, std::uint32_t startAddress, const TargetMemoryBuffer& buffer) {
if (
memoryType == TargetMemoryType::FLASH && this->programmingSession.has_value()
&& this->targetConfig->physicalInterface != PhysicalInterface::DEBUG_WIRE
) {
if (this->targetConfig->physicalInterface == PhysicalInterface::PDI) {
const auto startSection = this->getProgramMemorySectionFromAddress(startAddress);
const auto endSection = this->getProgramMemorySectionFromAddress(
static_cast<std::uint32_t>(startAddress + buffer.size() - 1)
);
if (startSection != endSection) {
throw Exception(
"Requested program memory write spans more than one section (APPLICATION and BOOT) - aborting"
);
}
if (
!this->programmingSession->applicationSectionErased
&& (
startSection == ProgramMemorySection::APPLICATION
|| endSection == ProgramMemorySection::APPLICATION
)
) {
Logger::warning("Erasing program memory APPLICATION section, in preparation for programming");
this->avr8DebugInterface->eraseProgramMemory(ProgramMemorySection::APPLICATION);
this->programmingSession->applicationSectionErased = true;
}
if (
!this->programmingSession->bootSectionErased
&& (
startSection == ProgramMemorySection::BOOT
|| endSection == ProgramMemorySection::BOOT
)
) {
Logger::warning("Erasing program memory BOOT section, in preparation for programming");
this->avr8DebugInterface->eraseProgramMemory(ProgramMemorySection::BOOT);
this->programmingSession->bootSectionErased = true;
}
} else if (!this->programmingSession->chipErased) {
Logger::warning("Erasing entire chip, in preparation for programming");
this->avr8DebugInterface->eraseProgramMemory();
this->programmingSession->chipErased = true;
}
if (memoryType == TargetMemoryType::FLASH) {
return this->writeFlashMemory(startAddress, buffer);
}
this->avr8DebugInterface->writeMemory(memoryType, startAddress, buffer);
@@ -774,6 +731,73 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit
return this->id.value();
}
void Avr8::writeFlashMemory(TargetMemoryAddress startAddress, const TargetMemoryBuffer& buffer) {
if (!this->programmingSession.has_value()) {
throw Exception("Attempted FLASH memory write with no active programming session.");
}
if (this->targetConfig->physicalInterface == PhysicalInterface::PDI) {
/*
* For PDI targets, we can erase specific sections (APPLICATION and BOOTLOADER sections) of program memory.
*
* We'll only erase the section if we intend to write to it.
*/
const auto startSection = this->getProgramMemorySectionFromAddress(startAddress);
const auto endSection = this->getProgramMemorySectionFromAddress(
static_cast<std::uint32_t>(startAddress + buffer.size() - 1)
);
if (startSection != endSection) {
/*
* TODO:
* Get rid of this. Was placed here because I didn't have enough time to implement and test the
* writing to multiple sections in a single instance.
*/
throw Exception(
"Requested program memory write spans more than one section (APPLICATION and BOOT) - aborting"
);
}
if (
!this->programmingSession->applicationSectionErased
&& (
startSection == ProgramMemorySection::APPLICATION
|| endSection == ProgramMemorySection::APPLICATION
)
) {
Logger::warning("Erasing program memory APPLICATION section, in preparation for programming");
this->avr8DebugInterface->eraseProgramMemory(ProgramMemorySection::APPLICATION);
this->programmingSession->applicationSectionErased = true;
}
if (
!this->programmingSession->bootSectionErased
&& (
startSection == ProgramMemorySection::BOOT
|| endSection == ProgramMemorySection::BOOT
)
) {
Logger::warning("Erasing program memory BOOT section, in preparation for programming");
this->avr8DebugInterface->eraseProgramMemory(ProgramMemorySection::BOOT);
this->programmingSession->bootSectionErased = true;
}
this->programmingSession->chipErased = true;
}
// debugWire targets do not need to be erased - this is done automatically when writing to FLASH.
if (
this->targetConfig->physicalInterface != PhysicalInterface::DEBUG_WIRE
&& !this->programmingSession->chipErased
) {
Logger::warning("Erasing entire chip, in preparation for programming");
this->avr8DebugInterface->eraseProgramMemory();
this->programmingSession->chipErased = true;
}
return this->avr8DebugInterface->writeMemory(TargetMemoryType::FLASH, startAddress, buffer);
}
void Avr8::updateDwenFuseBit(bool enable) {
if (this->avrIspInterface == nullptr) {
throw Exception(

View File

@@ -175,6 +175,14 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit
*/
TargetSignature getId() override;
/**
* Writes to FLASH memory (with any necessary erasing).
*
* @param startAddress
* @param buffer
*/
void writeFlashMemory(TargetMemoryAddress startAddress, const TargetMemoryBuffer& buffer);
/**
* Updates the debugWire enable (DWEN) fuse bit on the AVR target.
*