From 91e3972e5f189117ab9989ca40e0aa756a0a1fad Mon Sep 17 00:00:00 2001 From: Michal Date: Thu, 28 May 2026 11:16:07 -0400 Subject: [PATCH] 64k write from dfu --- shared/dfu.cpp | 72 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 12 deletions(-) diff --git a/shared/dfu.cpp b/shared/dfu.cpp index 2f2e1d4..0b05d58 100644 --- a/shared/dfu.cpp +++ b/shared/dfu.cpp @@ -1,4 +1,6 @@ #include +#include +#include #include #include "dfu.h" @@ -13,10 +15,10 @@ using namespace daisy; -static constexpr const size_t kMaxDfuProgramSize = 8192; +static constexpr const size_t kQspiWriteBlockSize = 65536; static DfuLogger __attribute__((section(".dtcmram_bss"))) dfu_log; -static uint8_t __attribute__((section(".dtcmram_bss"))) gDfuWriteBuffer[kMaxDfuProgramSize]; +static uint8_t __attribute__((section(".dtcmram_bss"))) gDfuWriteBuffer[kQspiWriteBlockSize]; #define DSY_DTCMRAM_BSS __attribute__((section(".dtcmram_bss"))) @@ -49,6 +51,7 @@ class DFUHandle::Impl /** Handles the I/O */ Result ProcessIoRequests(); + bool HasPendingWrite() const { return pending_write_size_ > 0; } bool dfu_complete; bool dfu_initiated; @@ -82,6 +85,9 @@ class DFUHandle::Impl IoStatus io_state; uint8_t* io_buffer; size_t io_buffer_size; + uint32_t pending_write_address_; + size_t pending_write_size_; + QSPIHandle* qspi_; @@ -118,7 +124,9 @@ DFUHandle::Result DFUHandle::Impl::Init(QSPIHandle* qspi) dfu_log.Clear(); io_buffer = gDfuWriteBuffer; - io_buffer_size = kMaxDfuProgramSize; + io_buffer_size = kQspiWriteBlockSize; + pending_write_address_ = 0; + pending_write_size_ = 0; qspi_ = qspi; @@ -203,15 +211,43 @@ DFUHandle::Result DFUHandle::Impl::MemoryWrite(uint8_t *src, uint8_t *dest, uint return Result::ERR; } - if (System::GetMemoryRegion((uint32_t)dest) == System::System::MemoryRegion::QSPI) { - // Copy data to scratch buffer - std::copy(src, src+ Len, io_buffer); + if (System::GetMemoryRegion((uint32_t)dest) == System::MemoryRegion::QSPI) { + if (Len == 0) + return Result::OK; + + const uint32_t dest_addr = (uint32_t)dest; + if (pending_write_size_ == 0) + { + pending_write_address_ = dest_addr; + std::memset(io_buffer, 0xFF, io_buffer_size); + } + else if (dest_addr != (pending_write_address_ + pending_write_size_)) + { + // DFU writes are expected to be contiguous while buffering a block. + return Result::ERR; + } + + const size_t remaining = io_buffer_size - pending_write_size_; + if (Len > remaining) + { + // The DFU stack should provide packet sizes smaller than the block remainder. + return Result::ERR; + } + + std::copy(src, src + Len, io_buffer + pending_write_size_); + pending_write_size_ += Len; + + if (pending_write_size_ == io_buffer_size) + { + io_state.busy = true; + io_state.type = IoStatus::Type::Write; + io_state.start_time = System::GetNow(); + io_state.start_address = pending_write_address_; + io_state.length = io_buffer_size; + pending_write_size_ = 0; + pending_write_address_ = 0; + } - io_state.busy = true; - io_state.type = IoStatus::Type::Write; - io_state.start_time = System::GetNow(); - io_state.start_address = (uint32_t)dest; - io_state.length = Len; return Result::OK; } @@ -352,6 +388,18 @@ DFUHandle::Result DFUHandle::Impl::ProcessIoRequests() // io_state.start_address = Add; // io_state.length = sector_size_; + if (!io_state.busy && dfu_complete && pending_write_size_ > 0) + { + // Finalize a partial trailing block as a full 64KB write. + io_state.busy = true; + io_state.type = IoStatus::Type::Write; + io_state.start_time = System::GetNow(); + io_state.start_address = pending_write_address_; + io_state.length = io_buffer_size; + pending_write_size_ = 0; + pending_write_address_ = 0; + } + // Only one request can be handled at a time so we have one state // instead of list of requests, etc. if (io_state.busy) { @@ -512,7 +560,7 @@ DFUHandle::Result DFUHandle::DeInit() bool DFUHandle::GetDfuComplete() { - return pimpl_->dfu_complete; + return pimpl_->dfu_complete && !pimpl_->HasPendingWrite(); } bool DFUHandle::GetDfuInitiated()