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>
This commit is contained in:
2026-09-14 16:00:05 +03:00
co-authored by Claude Sonnet 5
commit 6d835bc44c
377 changed files with 189430 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(spi_gpio_probe)
+1
View File
@@ -0,0 +1 @@
idf_component_register(SRCS "main.c" INCLUDE_DIRS ".")
+103
View File
@@ -0,0 +1,103 @@
// Standalone diagnostic firmware - NOT part of the real esp-spi project.
// Purpose: bypass the SPI slave peripheral entirely and watch the raw GPIO
// pins (plain digital input, interrupt on every edge) that our real
// firmware's spi_slave.cpp configures for SPI slave use on ESP32-S3:
// CS=GPIO10, SCLK=GPIO12, MOSI=GPIO13, MISO=GPIO11
// Logs every CS/SCLK edge with a microsecond timestamp and the
// MOSI/MISO/CS level sampled at that instant, so a real transaction
// attempt from the CH341A bridge can be visually reconstructed from the
// console log - answers directly whether the ESP32 sees anything at all
// on these pins, and if so, whether it looks like a sane SPI waveform
// (CS low, some number of SCLK edges, CS high) or not.
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/gpio.h"
#include "esp_timer.h"
#define PIN_CS 10
#define PIN_SCLK 12
#define PIN_MOSI 13
#define PIN_MISO 11
typedef struct
{
int64_t us;
uint8_t pin; // which pin's edge triggered this event (PIN_CS or PIN_SCLK)
uint8_t level; // level that pin transitioned TO
uint8_t cs;
uint8_t sclk;
uint8_t mosi;
uint8_t miso;
} event_t;
#define EVQ_LEN 4096
static QueueHandle_t evq;
static void IRAM_ATTR gpio_isr(void *arg)
{
uint32_t pin = (uint32_t)(uintptr_t)arg;
event_t ev;
ev.us = esp_timer_get_time();
ev.pin = (uint8_t)pin;
ev.level = (uint8_t)gpio_get_level((gpio_num_t)pin);
ev.cs = (uint8_t)gpio_get_level(PIN_CS);
ev.sclk = (uint8_t)gpio_get_level(PIN_SCLK);
ev.mosi = (uint8_t)gpio_get_level(PIN_MOSI);
ev.miso = (uint8_t)gpio_get_level(PIN_MISO);
BaseType_t hpw = pdFALSE;
xQueueSendFromISR(evq, &ev, &hpw);
if (hpw) portYIELD_FROM_ISR();
}
void app_main(void)
{
printf("\n\n=== spi_gpio_probe starting ===\n");
printf("Pins: CS=GPIO%d SCLK=GPIO%d MOSI=GPIO%d MISO=GPIO%d\n", PIN_CS, PIN_SCLK, PIN_MOSI, PIN_MISO);
printf("Watching CS + SCLK edges only (plain digital input, no SPI peripheral involved).\n\n");
evq = xQueueCreate(EVQ_LEN, sizeof(event_t));
gpio_config_t io = { 0 };
io.pin_bit_mask = (1ULL << PIN_CS) | (1ULL << PIN_SCLK) | (1ULL << PIN_MOSI) | (1ULL << PIN_MISO);
io.mode = GPIO_MODE_INPUT;
io.pull_up_en = GPIO_PULLUP_DISABLE;
io.pull_down_en = GPIO_PULLDOWN_DISABLE;
io.intr_type = GPIO_INTR_ANYEDGE;
gpio_config(&io);
gpio_install_isr_service(0);
gpio_isr_handler_add((gpio_num_t)PIN_CS, gpio_isr, (void*)(uintptr_t)PIN_CS);
gpio_isr_handler_add((gpio_num_t)PIN_SCLK, gpio_isr, (void*)(uintptr_t)PIN_SCLK);
printf("Idle levels right now: CS=%d SCLK=%d MOSI=%d MISO=%d\n\n",
gpio_get_level(PIN_CS), gpio_get_level(PIN_SCLK),
gpio_get_level(PIN_MOSI), gpio_get_level(PIN_MISO));
int64_t last_us = 0;
unsigned long total_events = 0;
unsigned long cs_high_count = 0;
for (;;)
{
event_t ev;
if (xQueueReceive(evq, &ev, pdMS_TO_TICKS(3000)))
{
const char *pin_name = (ev.pin == PIN_CS) ? "CS " : "SCLK";
long long delta = last_us ? (long long)(ev.us - last_us) : 0;
printf("[t=%10lld us d=%6lld us] %s -> %d | CS=%d SCLK=%d MOSI=%d MISO=%d\n",
(long long)ev.us, delta, pin_name, ev.level,
ev.cs, ev.sclk, ev.mosi, ev.miso);
last_us = ev.us;
total_events++;
if (ev.pin == PIN_CS && ev.level == 1) cs_high_count++;
}
else
{
printf("--- idle (no CS/SCLK edges in last 3s) --- total_events=%lu cs_high_transitions=%lu\n",
total_events, cs_high_count);
}
}
}
File diff suppressed because it is too large Load Diff