Files
desklock/firmware/components/esp_hosted/examples/host_gpio_expander
jpmschweitzerandClaude Fable 5 cb5826e02b
Test, Build and Push / test-gateway (push) Successful in 12s
Test, Build and Push / release (push) Skipped
Test, Build and Push / build-gateway (push) Skipped
Fork fix: the SDIO wedge is FIXED (esp-hosted-mcu #167)
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>
2026-07-15 09:50:27 +02:00
..

ESP-Hosted GPIO Control Example

This example demonstrates how to use the ESP-Hosted solution to control the GPIOs of the slave (co-processor) from the host MCU.

How to Use

Feature Switch

Feature can be controlled at Host and Slave using CONFIG_ESP_HOSTED_ENABLE_GPIO_EXPANDER option. It is by default disabled at slave.

Slave Configuration: * The firmware flashed on the slave board must have the GPIO RPC feature enabled. In the slave's idf.py menuconfig, set the following: (Top) → Example Configuration ---> [*] Enable GPIO Expander support (host can control slave GPIOs) This corresponds to the CONFIG_ESP_HOSTED_ENABLE_GPIO_EXPANDER=y option.

Build and Flash

  1. Slave

    • Slave build & flashed with above config
  2. Host:

    • Set your target board (e.g., idf.py set-target esp32p4).
    • Build and flash the project: idf.py -p <host_port> build flash monitor.

The host application will:

  1. Initialize the ESP-Hosted transport.
  2. Configure a specific GPIO pin on the slave as an output.
  3. Toggle the GPIO level (HIGH and LOW) every second.
  4. After a few toggles, it will reconfigure the same GPIO as an input.
  5. Read and print the GPIO level.

You can connect an LED to the specified GPIO on the slave board to visually verify the output functionality.