Files
desklock/firmware/components/esp_hosted/slave/main/slave_wifi_std.h
T
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

152 lines
7.5 KiB
C

/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __SLAVE_WIFI_STD_H__
#define __SLAVE_WIFI_STD_H__
#include "esp_err.h"
#include "esp_hosted_rpc.pb-c.h"
#include "esp_wifi.h"
#include "slave_wifi_config.h"
// TODO temporary include
#if H_DPP_SUPPORT
#include "esp_dpp.h"
#endif
typedef enum {
PAYLOAD_TYPE_RPC_RESP_WIFI_GET_CONFIG,
PAYLOAD_TYPE_RPC_EVENT_SUPP_DPP_GET_CONFIG,
#if H_WIFI_DPP_SUPPORT
PAYLOAD_TYPE_RPC_EVENT_WIFI_DPP_GET_CONFIG,
#endif
} rpc_payload_type_t;
uint8_t get_wifi_std_capabilities(void);
esp_err_t __wrap_esp_wifi_init(const wifi_init_config_t *config);
void send_wifi_event_data_to_host(int event, void *event_data, int event_size);
esp_err_t esp_hosted_register_wifi_event_handlers(void);
esp_err_t req_wifi_init(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_deinit(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_get_mac(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_get_mode(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_set_mode(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_set_mac(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_set_ps(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_get_ps(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_set_max_tx_power(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_get_max_tx_power(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_start(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_stop(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_connect(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_disconnect(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t esp_hosted_set_sta_config(wifi_interface_t iface, wifi_config_t *cfg);
esp_err_t req_wifi_set_config(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_get_config(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_scan_start(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_set_protocol(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_get_protocol(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_scan_stop(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_scan_get_ap_num(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_scan_get_ap_record(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_scan_get_ap_records(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_clear_ap_list(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_restore(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_clear_fast_connect(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_sta_get_ap_info(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_deauth_sta(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_set_storage(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_set_bandwidth(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_get_bandwidth(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_set_channel(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_get_channel(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_set_country_code(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_get_country_code(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_set_country(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_get_country(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_ap_get_sta_list(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_ap_get_sta_aid(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_sta_get_rssi(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_sta_get_aid(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_sta_get_negotiated_phymode(Rpc *req, Rpc *resp, void *priv_data);
#if H_PRESENT_IN_ESP_IDF_5_4_0
esp_err_t req_wifi_set_protocols(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_get_protocols(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_set_bandwidths(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_get_bandwidths(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_set_band(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_get_band(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_set_band_mode(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_get_band_mode(Rpc *req, Rpc *resp, void *priv_data);
#endif
esp_err_t req_wifi_set_inactive_time(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_get_inactive_time(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_disable_pmf_config(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_scan_params(Rpc *req, Rpc *resp, void *priv_data);
#if CONFIG_SOC_WIFI_HE_SUPPORT
#if H_WIFI_HE_GREATER_THAN_ESP_IDF_5_3
esp_err_t req_wifi_sta_twt_config(Rpc *req, Rpc *resp, void *priv_data);
#endif
esp_err_t req_wifi_sta_itwt_setup(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_sta_itwt_teardown(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_sta_itwt_suspend(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_sta_itwt_get_flow_id_status(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_sta_itwt_send_probe_req(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_wifi_sta_itwt_set_target_wake_time_offset(Rpc *req, Rpc *resp, void *priv_data);
#endif // CONFIG_SOC_WIFI_HE_SUPPORT
#if H_DPP_SUPPORT
esp_err_t req_supp_dpp_init(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_supp_dpp_deinit(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_supp_dpp_bootstrap_gen(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_supp_dpp_start_listen(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_supp_dpp_stop_listen(Rpc *req, Rpc *resp, void *priv_data);
#endif // H_DPP_SUPPORT
/*
* if network split is not enabled, uses stub functions defined in slave_wifi_std.c
* if network split is enabled, uses functions defined in slave_network_split.c
*/
esp_err_t req_get_dhcp_dns_status(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t req_set_dhcp_dns_status(Rpc *req, Rpc *resp, void *priv_data);
esp_err_t rpc_evt_sta_scan_done(Rpc *ntfy, const uint8_t *data, ssize_t len, int event_id);
esp_err_t rpc_evt_sta_connected(Rpc *ntfy, const uint8_t *data, ssize_t len, int event_id);
esp_err_t rpc_evt_sta_disconnected(Rpc *ntfy, const uint8_t *data, ssize_t len, int event_id);
esp_err_t rpc_evt_ap_staconn_conn_disconn(Rpc *ntfy, const uint8_t *data, ssize_t len, int event_id);
#if CONFIG_SOC_WIFI_HE_SUPPORT
esp_err_t rpc_evt_itwt_setup(Rpc *ntfy, const uint8_t *data, ssize_t len, int event_id);
esp_err_t rpc_evt_itwt_teardown(Rpc *ntfy, const uint8_t *data, ssize_t len, int event_id);
esp_err_t rpc_evt_itwt_suspend(Rpc *ntfy, const uint8_t *data, ssize_t len, int event_id);
esp_err_t rpc_evt_itwt_probe(Rpc *ntfy, const uint8_t *data, ssize_t len, int event_id);
#endif // CONFIG_SOC_WIFI_HE_SUPPORT
#if H_DPP_SUPPORT
#if H_SUPP_DPP_SUPPORT
esp_err_t rpc_evt_supp_dpp_uri_ready(Rpc *ntfy, const uint8_t *data, ssize_t len);
esp_err_t rpc_evt_supp_dpp_cfg_recvd(Rpc *ntfy, const uint8_t *data, ssize_t len);
esp_err_t rpc_evt_supp_dpp_fail(Rpc *ntfy, const uint8_t *data, ssize_t len);
#endif // H_SUPP_DPP_SUPPORT
#if H_WIFI_DPP_SUPPORT
esp_err_t rpc_evt_wifi_dpp_uri_ready(Rpc *ntfy, const uint8_t *data, ssize_t len);
esp_err_t rpc_evt_wifi_dpp_cfg_recvd(Rpc *ntfy, const uint8_t *data, ssize_t len);
esp_err_t rpc_evt_wifi_dpp_fail(Rpc *ntfy, const uint8_t *data, ssize_t len);
#endif // H_WIFI_DPP_SUPPORT
#endif // H_DPP_SUPPORT
esp_err_t rpc_evt_Event_DhcpDnsStatus(Rpc *ntfy, const uint8_t *data, ssize_t len);
#endif