Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 60 additions & 12 deletions shared/dfu.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#include <cstdint>
#include <algorithm>
#include <cstring>
#include <stm32h750xx.h>

#include "dfu.h"
Expand All @@ -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")))

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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_;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -512,7 +560,7 @@ DFUHandle::Result DFUHandle::DeInit()

bool DFUHandle::GetDfuComplete()
{
return pimpl_->dfu_complete;
return pimpl_->dfu_complete && !pimpl_->HasPendingWrite();
}

bool DFUHandle::GetDfuInitiated()
Expand Down