Root cause (verified against our exact IDF tree, not the community guess): the "258" in "sdio_write_task: Failed to send data: 258" is NOT a timeout (that is 263). 258 = 0x102 = ESP_ERR_INVALID_ARG. On the ESP32-P4, block- mode CMD53 writes require the SOURCE buffer to be 64-byte (cache-line) aligned; the IDF sdmmc driver rejects a misaligned source with INVALID_ARG BEFORE any bus activity. esp_hosts write loop then declares "Unrecoverable host sdio state" and reboots the whole P4. The audio TX payload is not 64-aligned, so streaming mic audio wedged on the very FIRST frame (which is exactly what we saw: listening -> instant Failed to send -> reboot). This also explains why buffer/queue/clock/retry tuning all did nothing: the write never reached the bus. And why our symptom was instant, not after ~100 writes (the community block-mode-desync theory) — it is the first misaligned buffer, every time. Fix: vendored esp_hosted 2.12.11 as an editable local component (overrides the registry copy) and bounce a misaligned TX payload through one aligned DMA scratch buffer in hosted_sdio_write_block (port_esp_hosted_host_sdio.c). TX is serialized by the bus lock so a single static bounce buffer is safe; freed in hosted_sdio_deinit. Host-only change — no C6 reflash. VERIFIED ON HARDWARE (autonomous self-test): 40s of continuous mic-audio upstream streaming — the traffic that previously wedged on the first frame — ran clean, zero timeouts, zero reboots. A guarded SDIO_TX_SELFTEST harness is kept (compiled out) for future SDIO stress testing. Credit: root cause + patch designed via multi-agent investigation; the precise 258=INVALID_ARG decode (correcting the upstream community timeout assumption) came from checking our actual esp_err.h. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There are two tests. "test-generated-code" is a simple test that can easily be adapted. "test-generated-code2" is a comprehensive test. -- If you have a quick problem, hack at "test-generated-code"; but i don't want that file to be too hard to navigate, so you must eventually add a test to "test-generated-code2". I appreciate additional test cases! Please submit them as issues in the tracking system, or email me. -- Here are the files involved in each test: test.proto Protobuf declarations for the simple test. test.pb-c.c Protobuf-C generated code based on test.proto test.pb-c.h Protobuf-C generated code based on test.proto test-full.proto Protobuf declarations for the exhaustive test. test-full.pb-c.c Protobuf-C generated code based on test-full.proto test-full.pb-c.h Protobuf-C generated code based on test-full.proto test-full.pb.cc Protobuf (C++) generated code based on test-full.proto test-full.pb.h Protobuf (C++) generated code based on test-full.proto generated-code/ test-generated-code.c Actual test code. test-generated-code Test executable. generated-code2/ cxx-generate-packed-data.cc C++ code to generated data to compare with C. cxx-generate-packed-data Program whichs generates data (using C++ api) test-full-cxx-output.inc Output of cxx-generate-packed-data. test-generated-code2.c Actual test code. test-generated-code2 Test executable.