Moved programming mode requirement for fuse programming into EDBG driver, as it is specific to that driver
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user