Moved programming mode requirement for fuse programming into EDBG driver, as it is specific to that driver

This commit is contained in:
Nav
2023-05-28 21:27:01 +01:00
parent a3fa436e52
commit 216a1357b7
2 changed files with 125 additions and 146 deletions

View File

@@ -1670,6 +1670,11 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
}
}
const auto managingProgrammingMode = type == Avr8MemoryType::FUSES && !this->programmingModeEnabled;
if (managingProgrammingMode) {
this->enableProgrammingMode();
}
if (!excludedAddresses.empty() && (this->avoidMaskedMemoryRead || type != Avr8MemoryType::SRAM)) {
/*
* Driver-side masked memory read.
@@ -1770,6 +1775,10 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
)
);
if (managingProgrammingMode) {
this->disableProgrammingMode();
}
if (responseFrame.id == Avr8ResponseId::FAILED) {
throw Avr8CommandFailure("AVR8 Read memory command failed", responseFrame);
}
@@ -1794,6 +1803,11 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
}
}
const auto managingProgrammingMode = type == Avr8MemoryType::FUSES && !this->programmingModeEnabled;
if (managingProgrammingMode) {
this->enableProgrammingMode();
}
const auto bytes = static_cast<TargetMemorySize>(buffer.size());
if (this->alignmentRequired(type)) {
@@ -1852,6 +1866,16 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
)
);
// We must disable and re-enable programming mode, in order for the changes to the fuse bit to take effect.
if (type == Avr8MemoryType::FUSES) {
this->disableProgrammingMode();
if (!managingProgrammingMode) {
this->enableProgrammingMode();
}
}
if (responseFrame.id == Avr8ResponseId::FAILED) {
throw Avr8CommandFailure("AVR8 Write memory command failed", responseFrame);
}

View File

@@ -335,7 +335,7 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit
void Avr8::writeMemory(TargetMemoryType memoryType, std::uint32_t startAddress, const TargetMemoryBuffer& buffer) {
if (memoryType == TargetMemoryType::FLASH && !this->programmingModeEnabled()) {
throw Exception("Attempted FLASH memory write with no active programming session.");
throw Exception("Attempted Flash memory write with no active programming session.");
}
this->avr8DebugInterface->writeMemory(memoryType, startAddress, buffer);
@@ -348,17 +348,26 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit
return;
}
if (!this->programmingModeEnabled()) {
throw Exception("Attempted Flash memory erase with no active programming session.");
}
/*
* For JTAG and UPDI targets, we must perform a chip erase. This means we could end up erasing EEPROM,
* unless the EESAVE fuse bit has been programmed.
*
* If configured to do so, we will ensure that the EESAVE fuse bit has been programmed when we start a
* programming session. See Avr8::enableProgrammingMode() for more.
* If configured to do so, we will ensure that the EESAVE fuse bit has been programmed before we perform
* the chip erase. The fuse will be restored to its original value at the end of the programming session.
*/
if (
this->targetConfig.physicalInterface == PhysicalInterface::JTAG
|| this->targetConfig.physicalInterface == PhysicalInterface::UPDI
) {
if (this->targetConfig.preserveEeprom) {
Logger::debug("Inspecting EESAVE fuse bit");
this->activeProgrammingSession->managingEesaveFuseBit = this->updateEesaveFuseBit(true);
}
return this->avr8DebugInterface->eraseChip();
}
@@ -572,26 +581,6 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit
this->avr8DebugInterface->enableProgrammingMode();
this->activeProgrammingSession = ProgrammingSession();
if (
this->targetConfig.preserveEeprom
&& (
this->targetConfig.physicalInterface == PhysicalInterface::JTAG
|| this->targetConfig.physicalInterface == PhysicalInterface::UPDI
)
) {
Logger::debug("Inspecting EESAVE fuse bit");
this->activeProgrammingSession->managingEesaveFuseBit = this->updateEesaveFuseBit(true);
if (this->activeProgrammingSession->managingEesaveFuseBit) {
/*
* We must disable and re-enable programming mode, in order for the changes to the EESAVE fuse bit to
* take effect.
*/
this->avr8DebugInterface->disableProgrammingMode();
this->avr8DebugInterface->enableProgrammingMode();
}
}
}
void Avr8::disableProgrammingMode() {
@@ -923,9 +912,6 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit
throw Exception("Could not find JTAGEN bit field in TDF.");
}
try {
this->enableProgrammingMode();
const auto ocdenFuseByteValue = this->avr8DebugInterface->readMemory(
TargetMemoryType::FUSES,
ocdenFuseBitsDescriptor->byteAddress,
@@ -958,8 +944,6 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit
if (this->isFuseEnabled(*ocdenFuseBitsDescriptor, ocdenFuseByteValue) == enable) {
Logger::debug("OCDEN fuse bit already set to desired value - aborting update operation");
this->disableProgrammingMode();
return;
}
@@ -988,11 +972,6 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit
Logger::info("OCDEN fuse bit updated");
this->disableProgrammingMode();
} catch (const Exception& exception) {
this->disableProgrammingMode();
throw exception;
}
}
bool Avr8::updateEesaveFuseBit(bool enable) {
@@ -1004,13 +983,6 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit
throw Exception("Could not find EESAVE bit field in TDF.");
}
const auto managingProgrammingMode = !this->programmingModeEnabled();
try {
if (managingProgrammingMode) {
this->enableProgrammingMode();
}
const auto eesaveFuseByteValue = this->avr8DebugInterface->readMemory(
TargetMemoryType::FUSES,
eesaveFuseBitsDescriptor->byteAddress,
@@ -1021,11 +993,6 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit
if (this->isFuseEnabled(*eesaveFuseBitsDescriptor, eesaveFuseByteValue) == enable) {
Logger::debug("EESAVE fuse bit already set to desired value - aborting update operation");
if (managingProgrammingMode) {
this->disableProgrammingMode();
}
return false;
}
@@ -1053,19 +1020,7 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit
Logger::info("EESAVE fuse bit updated");
if (managingProgrammingMode) {
this->disableProgrammingMode();
}
return true;
} catch (const Exception& exception) {
if (managingProgrammingMode) {
this->disableProgrammingMode();
}
throw exception;
}
}
ProgramMemorySection Avr8::getProgramMemorySectionFromAddress(std::uint32_t address) {