diff --git a/shared/dfu.cpp b/shared/dfu.cpp index 2da4691..8f606bb 100644 --- a/shared/dfu.cpp +++ b/shared/dfu.cpp @@ -235,12 +235,19 @@ DFUHandle::Result DFUHandle::Impl::MemoryWrite(uint8_t *src, uint8_t *dest, uint DFUHandle::Result DFUHandle::Impl::MemoryRead(uint8_t *src, uint8_t *dest, uint32_t Len) { uint32_t tstart = System::GetNow(); - if (System::GetMemoryRegion((uint32_t)src) == System::MemoryRegion::QSPI) + const uintptr_t address = reinterpret_cast(src); + constexpr uintptr_t qspi_end = QSPI_BASE + 0x800000U; + // Reads run in the USB interrupt: never touch QSPI while main-loop I/O + // has temporarily disabled memory mapping. Check the entire range. + if (!io_state.busy && dest != nullptr && address >= QSPI_BASE + && address < qspi_end && Len <= qspi_end - address) { - // TODO -- this will need to change for multi-programs + // A read-only verification session must also suppress the boot timeout. + dfu_initiated = true; + // src already points at the requested memory-mapped QSPI address. + const volatile uint8_t* source = src; for (size_t i = 0; i < Len; i++) - dest[i] = *((__IO uint8_t *)QSPI_BASE + *src + i); - // dest[i] = qspi_buffer[*src + i]; + dest[i] = source[i]; // Log uint32_t tend = System::GetNow(); auto dur = tend - tstart; @@ -473,8 +480,11 @@ extern "C" */ uint8_t *MEM_If_Read_FS(uint8_t *src, uint8_t *dest, uint32_t Len) { - /* Return a valid address to avoid HardFault */ - return (uint8_t *)dfu_impl.MemoryRead(src, dest, Len); + // The USB stack needs the data buffer, not an OK/ERR enum cast to + // an address. Returning OK (zero) previously uploaded address zero. + return dfu_impl.MemoryRead(src, dest, Len) == DFUHandle::Result::OK + ? dest + : nullptr; } /**