Files
ZIFI32--ESP32-/firmware/README.md
T
alexandClaude Sonnet 5 6d835bc44c Initial import: ESP32 ZiFi32 firmware with SMB2/3 VFS bridge
Based on https://github.com/tslabs/zx-evo/tree/master/pentevo/esp32,
extended with an SMB2/3 server that exposes the ZX Evolution's real SD
card as a network share (browse/download/upload/delete), plus assorted
stability and protocol-correctness fixes in vfs_bridge.cpp and the
vendored libsmb2 - see firmware/README.md for the detailed changelog
and current status.

Also adds:
- firmware/: ready-to-flash compiled binaries + flashing instructions
- hardware/: adapter board connection diagram, PCB photo, and Gerber
  files
- src/third_party/libsmb2: vendored from sahlberg/libsmb2 (LGPL-2.1,
  see its own COPYING/LICENCE files), de-submoduled to a plain
  snapshot with local patches applied directly

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-14 16:00:05 +03:00

5.2 KiB

ESP32 firmware (ZX Evolution / TS-Conf ZiFi32 module)

Compiled firmware for the ESP32-S3-based WiFi/SPI module used by the ZX Evolution / TS-Conf ("Pentevo") platform.

Base source: this firmware is based on tslabs/zx-evo — full source for this fork lives in pentevo/esp32/src alongside this folder; this firmware/ directory only holds ready-to-flash binaries.

Requirements

The ZX Evolution/TS-Conf board's own core firmware must be built with VDAC2 and ESP32 (ZiFi32) peripheral support enabled - without both, the core won't recognize the ESP32 module on the SPI bus at all (no matter how correct this ESP32-side firmware is), and won't drive the FT8xx video chip either. Check this before assuming a connection problem is on the ESP32 side.

The RESET jumper on the IDE connector must be installed as well - see ../hardware/connection_diagram.webp.

What's changed vs. the upstream source

Most of the work in this fork is a VFS bridge that exposes the ZX Evolution's real SD card as a network share over SMB2/3, so any Windows/ macOS/Linux SMB client can browse, download, upload to, and delete files on the real Wild Commander filesystem without pulling the card. This is still actively being worked on — see "Status" below.

Changes so far, roughly in the order they were made:

  • Real filesystem wired up. vfs_bridge.cpp's SMB2 handlers (CREATE/READ/WRITE/CLOSE/QUERY_DIRECTORY/QUERY_INFO/etc.) now talk to the real filesystem via a small request/response bridge (vfs_request.cpp) over the existing SPI link to the Z80 side, instead of the original hardcoded demo filesystem.
  • Upload (WRITE) and delete support for files and empty directories, including proper FILE_DELETE_ON_CLOSE handling and a SMB2_STATUS_DIRECTORY_NOT_EMPTY reply when a non-empty directory delete is rejected.
  • Directory listing fixes: SMB2_RETURN_SINGLE_ENTRY pagination support (needed by cmd.exe's own SMB2 client, not just Explorer), the missing non-"ID" directory info classes, synthesized ./.. entries, and a NextEntryOffset encoding bug in the vendored libsmb2 that silently corrupted any listing past the second entry.
  • srvsvc share-enumeration fix: the RPC pipe used to always report the Phase-1 placeholder share name "test" regardless of what a client had actually connected to — fixed to report the real share name.
  • Added SMB2_FILE_FS_VOLUME_INFORMATION support (a bare dir/net use needs it; Explorer doesn't ask for it, which is why this was missed at first).
  • Stability fixes: a NULL-pointer crash in the named-pipe RPC transceive path, and a 0-length SPI DMA transaction that could wedge the whole SPI channel to the Z80 side.
  • libsmb2 (vendored, src/third_party/libsmb2) patches:
    • SMB2_FSCTL_DFS_GET_REFERRALS now answers STATUS_OBJECT_PATH_NOT_FOUND instead of STATUS_NOT_IMPLEMENTED — the wrong status code was sending Windows Explorer into a retry storm before it would even attempt to connect to the share.
    • SET_INFO parsing is now permissive for info classes this server doesn't specifically implement (passes the raw buffer through instead of failing to parse) — a hard parse failure here used to tear down the entire TCP connection instead of just failing that one request, which showed up as Explorer aborting mid file-copy with a generic error.
    • A close_cmd return value of -2 now maps to SMB2_STATUS_DIRECTORY_NOT_EMPTY in the CLOSE reply instead of a generic STATUS_NOT_IMPLEMENTED.
  • Auth simplified to plain guest/anonymous sessions (authorize_handler always succeeds) — an earlier attempt at forcing NTLMv2 + SMB2 signing turned out to be unrelated to a since-fixed listing bug, so it was backed out rather than kept as unnecessary complexity.
  • Removed high-frequency per-request debug logging that was originally added to chase the above bugs, replaced with a single per-connection summary line.

Status

The SMB2/3 server (read, browse, upload, delete) works against real Windows/ Samba clients. This is still in-progress work — directory/file creation (MKDIR) isn't implemented yet, overwriting an existing file with shorter content doesn't truncate the old tail, and there's no live-update (change_notify) support, so Explorer can show a stale listing for a moment after a change until it's refreshed. See the source tree's own code comments for the current state of any specific handler.

Flashing

Target chip: ESP32-S3. Using esptool.py directly:

esptool.py --chip esp32s3 -p COM5 -b 460800 write_flash \
  --flash-mode dio --flash-freq 80m --flash-size detect \
  0x0     bootloader.bin \
  0x8000  partition-table.bin \
  0x10000 esp-spi.bin

(replace COM5 with the actual port; flasher_args.json in this folder has the same offsets in idf.py's own JSON format, for reference or scripting.)

If you're building from source instead: ESP-IDF v6.1 (not v6.1-rc1) — idf.py build flash.

Hardware

See ../hardware/ for:

  • connection_diagram.webp — how this module wires up to a ZX Evolution board.
  • pcb_photo.jpg — a photo of the adapter board.
  • gerber/ — Gerber files for the adapter PCB.