From a53a8c87f0051d5bfefc5ccb101cc885fde51ccd Mon Sep 17 00:00:00 2001 From: Nav Date: Sat, 22 Feb 2025 22:23:53 +0000 Subject: [PATCH] Fixed bug with DWEN fuse bit management, where the newly written value was being read back too quickly after the write, resulting in garbage data (0xFF) being returned. Removal of the default (35 millisecond) CMSIS command delay is what revealed this issue. --- src/Targets/Microchip/Avr8/Avr8.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/Targets/Microchip/Avr8/Avr8.cpp b/src/Targets/Microchip/Avr8/Avr8.cpp index 67aa4589..90f0a064 100644 --- a/src/Targets/Microchip/Avr8/Avr8.cpp +++ b/src/Targets/Microchip/Avr8/Avr8.cpp @@ -890,6 +890,8 @@ namespace Targets::Microchip::Avr8 } void Avr8::updateDwenFuseBit(bool enable) { + using Services::StringService; + if (this->avrIspInterface == nullptr) { throw Exception{ "Debug tool or driver does not provide access to an ISP interface - please confirm that the " @@ -1027,23 +1029,34 @@ namespace Targets::Microchip::Avr8 Logger::info("Cleared lock bits confirmed"); + Logger::debug("DWEN fuse byte value (before update): 0x" + StringService::toHex(dwenFuseByte)); + const auto newFuseValue = this->setFuseEnabled(dwenBitFieldDescriptor, dwenFuseByte, enable); + Logger::debug("New DWEN fuse byte value (to be written): 0x" + StringService::toHex(newFuseValue)); Logger::warning("Updating DWEN fuse bit"); this->avrIspInterface->programFuse(dwenRegisterDescriptor, newFuseValue); Logger::debug("Verifying DWEN fuse bit"); - if (this->avrIspInterface->readFuse(dwenRegisterDescriptor) != newFuseValue) { - throw Exception{"Failed to update DWEN fuse bit - post-update verification failed"}; + + // If we read back the newly-written value too quickly after writing, we get garbage data + std::this_thread::sleep_for(std::chrono::milliseconds{50}); + + const auto writtenValue = this->avrIspInterface->readFuse(dwenRegisterDescriptor); + if (writtenValue != newFuseValue) { + throw Exception{ + "Failed to update DWEN fuse bit - post-update verification failed (value read: 0x" + + StringService::toHex(writtenValue) + ")" + }; } Logger::info("DWEN fuse bit successfully updated"); this->avrIspInterface->deactivate(); - } catch (const Exception& exception) { + } catch (const Exception&) { this->avrIspInterface->deactivate(); - throw exception; + throw; } }