Skip to content

transport: Support External SPI Flash Read/Write over USB DFU (Alt 5)#361

Open
anthonychen1251 wants to merge 6 commits into
OpenPRoT:earlgrey-hwefrom
anthonychen1251:suport-dfu-external-spi-flash-rw
Open

transport: Support External SPI Flash Read/Write over USB DFU (Alt 5)#361
anthonychen1251 wants to merge 6 commits into
OpenPRoT:earlgrey-hwefrom
anthonychen1251:suport-dfu-external-spi-flash-rw

Conversation

@anthonychen1251

Copy link
Copy Markdown

This PR introduces support for reading and writing external SPI Flash (SPI EEPROM 0) over USB DFU via Alt Setting 5 on OpenPRoT Earlgrey, including flash_server IPC multi-service dispatch, DFU protocol handler extensions, ZLP fixes, and host-side E2E integration tests.

Note: this depends on #347. Only review the last 4 commits.

lchiawei and others added 6 commits July 23, 2026 07:58
Key modifications and fixes made during the port:
- Makes the driver explicitly enter "Global 4-byte" mode when flash size
  >= 16 MB, which includes:
  * Update the command config in `from_sfdp()` &
    `from_sfdp_conservative()`.
  * Explicitly enters the global 4-byte mode at the end of
    initialization.
- Skips the support of DUAL / QUAD in `SpiTxnWidth`. Also, inits the
  driver with non-conservative version for now.
- Moves `transfer_req_resp` from legacy SPI Host driver to SPI Flash
  driver, as a helper method.
- Moves `check_valid_size` from legacy Flash trait to SPI Flash
  driver, as a helper method.
- Adds `is_busy` helper method as what we did for `BlockingFlash` trait,
  although we didn't implement this trait directly now.
- Wraps legacy `page_size` and `size` into a `geometry` method required
  by `Flash` trait. Currently we hard-coded the erasable bitmap as 4KB
  and 64KB, and we may parse them in the future.
- For `erase()` method, the `Flash` trait only accepts the size declared
  in the erasable bitmap, but here we uses the legacy implementation
  which will loop over the size to erase. However, we still only accepts
  power of 2 as the erase size due to `Flash` trait's contract. Also
  removes the original `erase_page()` method.
- Drops `FlashStreamingRead` support (as we mentioned in SPI Host
  driver commit).

Mock SPI Device & Unit Test Refactoring:
- Ports the legacy `FakeSpiHost` to OpenPRoT, renaming it to `FakeSpiDevice`
  under `drivers/mock/spi_device_fake.rs` and implementing standard
  `embedded_hal::spi::SpiDevice` and `ErrorType` traits.
- Rewrites mock transmission logic to be stateless by removing `TxnState`,
  supporting multi-buffer transaction execution and automatic TX/RX clock
  log alignment and padding.
- Introduces `assert_all_expectations_met()` to strictly assert that all
  preprogrammed SPI responses are executed, preventing silent test leaks.
- Adapts unit tests to new `PowerOf2Usize` API constraints:
  * Erase lengths in mixed granularity and multiple page tests are changed
    to powers of 2 (e.g., 144KB -> 128KB, 12KB -> 16KB).
  * Obsolete `test_erase_zero_length` is removed as zero-length input is
    prevented at compile time.
- Aligns mock expectations with Global 4-byte address mode: expected
  opcodes are updated from 4-byte-specific ones (e.g. `OP_READ4B`) to
  standard opcodes (e.g. `OP_READ`) with 4-byte address streams.
- Removes obsolete unit tests for prefetch, FIFO draining, and
  Streaming Read.

Signed-off-by: Chia-Wei Liu <lchiawei@google.com>
- Update system.json5 to split the original flash_service into
  eflash_service and a new spi_flash_service.
- Map the spi_host0 memory region (0x40300000) into the flash_server
  process.
- Implement a wait_group in flash_server.rs to handle incoming requests
  for both eflash_service and spi_flash_service.
- Initialize the SPI Host and SPI Flash driver in flash_server.rs,
  logging errors using zfmt diagnostics.
- Update usbmgr to connect to the renamed eflash_service and initialize
  the new spi_flash_usb initiator.
- Add spi_flash and spi_host dependencies to the flash_server target in
  BUILD.bazel.

Signed-off-by: Anthony Chen <antchen@google.com>
- Increase DFU alt settings to 6 and register Alt 5 interface in usbmgr.
- Pass the external spi_flash client from usbmgr to EarlgreyDfuHandler.
- Update dnload() in EarlgreyDfuHandler to query SPI flash geometry,
  align erase requests using driver page size, and program blocks to
  external SPI flash.
- Update upload() to read chunks from external SPI flash.
- Update manifest() to bypass manifestation reboot for Alt 5 download.

Signed-off-by: Anthony Chen <antchen@google.com>
Only send ZLP in DfuClass::poll if the total transfer size is less than
the DFU wTransferSize (2048 bytes), avoiding a redundant ZLP when
returning a full block.

Signed-off-by: Anthony Chen <antchen@google.com>
- Implement host_usb_dfu_spi_flash.rs to download a payload to Alt 5
  (SPI EEPROM 0) and upload it back for verification.
- Add host_usb_dfu_spi_flash to target dependencies and define
  dfu_spi_flash_hyper{310,340}_test target in BUILD.bazel.

Signed-off-by: Anthony Chen <antchen@google.com>
@linux-foundation-easycla

linux-foundation-easycla Bot commented Jul 24, 2026

Copy link
Copy Markdown

CLA Signed
The committers listed above are authorized under a signed CLA.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants