Skip to content

Commit 2a185ed

Browse files
committed
drivers: wifi: Add WiFi drivers for ESP hosted firmware.
This is a host driver for ESP32 chips running the esp-hosted firmware, which turns ESP32s into a WLAN/BT co-processor. Signed-off-by: Ibrahim Abdalkader <[email protected]>
1 parent ca0f5f6 commit 2a185ed

13 files changed

+1643
-0
lines changed

drivers/wifi/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ endif() # CONFIG_BUILD_ONLY_NO_BLOBS
2020

2121
add_subdirectory_ifdef(CONFIG_WIFI_ESP_AT esp_at)
2222
add_subdirectory_ifdef(CONFIG_WIFI_ESP32 esp32)
23+
add_subdirectory_ifdef(CONFIG_WIFI_ESP_HOSTED esp_hosted)
2324
add_subdirectory_ifdef(CONFIG_WIFI_ESWIFI eswifi)
2425
add_subdirectory_ifdef(CONFIG_WIFI_SIMPLELINK simplelink)
2526
add_subdirectory_ifdef(CONFIG_WIFI_WINC1500 winc1500)

drivers/wifi/Kconfig

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ source "drivers/wifi/simplelink/Kconfig.simplelink"
4040
source "drivers/wifi/eswifi/Kconfig.eswifi"
4141
source "drivers/wifi/esp_at/Kconfig.esp_at"
4242
source "drivers/wifi/esp32/Kconfig.esp32"
43+
source "drivers/wifi/esp_hosted/Kconfig.esp_hosted"
4344
source "drivers/wifi/nxp/Kconfig.nxp"
4445
source "drivers/wifi/infineon/Kconfig.airoc"
4546
source "drivers/wifi/nrf_wifi/Kconfig.nrfwifi"
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Copyright (c) 2025 Arduino SA
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
if (CONFIG_WIFI_ESP_HOSTED)
5+
6+
zephyr_library_named(esp_hosted)
7+
8+
list(APPEND CMAKE_MODULE_PATH ${ZEPHYR_BASE}/modules/nanopb)
9+
include(nanopb)
10+
11+
zephyr_library_sources(
12+
esp_hosted_hal.c
13+
esp_hosted_wifi.c
14+
)
15+
16+
zephyr_nanopb_sources(esp_hosted
17+
esp_hosted_proto.pb
18+
)
19+
20+
zephyr_include_directories(
21+
./
22+
)
23+
24+
zephyr_compile_definitions(
25+
PB_ENABLE_MALLOC=1
26+
)
27+
endif()
+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# ESP Hosted WiFi driver options
2+
3+
# Copyright (c) 2025 Arduino SA
4+
# SPDX-License-Identifier: Apache-2.0
5+
6+
menuconfig WIFI_ESP_HOSTED
7+
bool "ESP_HOSTED driver support"
8+
depends on DT_HAS_ESPRESSIF_ESP_HOSTED_ENABLED
9+
default y
10+
select GPIO
11+
select SPI
12+
select WIFI_OFFLOAD
13+
select WIFI_NM
14+
select NANOPB
15+
select NET_L2_ETHERNET
16+
select NET_L2_WIFI_MGMT
17+
select WIFI_USE_NATIVE_NETWORKING
18+
19+
if WIFI_ESP_HOSTED
20+
21+
config WIFI_ESP_HOSTED_DEBUG
22+
bool "Extra debugging messages"
23+
24+
config WIFI_ESP_HOSTED_EVENT_TASK_PRIORITY
25+
int "Event task priority"
26+
default 4
27+
28+
config WIFI_ESP_HOSTED_EVENT_TASK_STACK_SIZE
29+
int "Event task stack size"
30+
default 16384
31+
32+
config WIFI_ESP_HOSTED_EVENT_TASK_POLL_MS
33+
int "Event task poll rate in ms"
34+
default 20
35+
36+
config WIFI_ESP_HOSTED_AP_CLIENTS_MAX
37+
int "Max number of AP clients"
38+
default 5
39+
40+
config WIFI_ESP_HOSTED_AP_CHANNEL_DEF
41+
int "Default AP channel"
42+
default 9
43+
44+
endif

drivers/wifi/esp_hosted/decode.py

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#!/usr/bin/env python
2+
from google.protobuf.internal.decoder import _DecodeVarint
3+
from io import BytesIO
4+
5+
def decode_protobuf(data):
6+
"""
7+
Decodes a Protobuf message supporting varint and length-delimited fields.
8+
9+
Parameters:
10+
- data (bytes): The Protobuf-encoded message.
11+
12+
Returns:
13+
- dict: A dictionary containing the decoded fields.
14+
"""
15+
stream = BytesIO(data)
16+
decoded_message = {}
17+
18+
current_pos = 0
19+
data_length = len(data)
20+
21+
while current_pos < data_length:
22+
# Position the stream at the current position
23+
stream.seek(current_pos)
24+
25+
# Decode the tag (field number and wire type)
26+
tag, tag_length = _DecodeVarint(data[current_pos:], 0)
27+
current_pos += tag_length
28+
29+
field_number = tag >> 3
30+
wire_type = tag & 0x07
31+
32+
if wire_type == 0: # Varint
33+
# Decode the varint value
34+
value, value_length = _DecodeVarint(data[current_pos:], 0)
35+
current_pos += value_length
36+
decoded_message[f"field{field_number}"] = value
37+
38+
elif wire_type == 2: # Length-delimited
39+
# Decode the length
40+
length, length_varint_size = _DecodeVarint(data[current_pos:], 0)
41+
current_pos += length_varint_size
42+
43+
# Read the bytes
44+
value = data[current_pos:current_pos + length]
45+
current_pos += length
46+
47+
# Try to decode the value as a nested message
48+
try:
49+
nested_message = decode_protobuf(value)
50+
if nested_message: # If successful, store as nested message
51+
decoded_message[f"field{field_number}"] = nested_message
52+
else: # Otherwise store as bytes
53+
decoded_message[f"field{field_number}"] = value
54+
except Exception:
55+
# If decoding as a nested message fails, store as bytes
56+
decoded_message[f"field{field_number}"] = value
57+
58+
else:
59+
raise ValueError(f"Unsupported wire type: {wire_type}")
60+
61+
return decoded_message
62+
63+
# Example usage with your provided data
64+
print(decode_protobuf(bytes([0x10, 0x68, 0xc2, 0x06, 0x02, 0x08, 0x03])))
65+
print(decode_protobuf(bytes([0x08, 0x01, 0x10, 0x68, 0xc2, 0x06, 0x02, 0x08, 0x03])))
66+
67+
+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright (c) 2025 Arduino SA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <stdint.h>
8+
#include <string.h>
9+
10+
#include <zephyr/kernel.h>
11+
#include "esp_hosted_wifi.h"
12+
13+
#include <zephyr/logging/log.h>
14+
LOG_MODULE_REGISTER(esp_hosted_hal, CONFIG_WIFI_LOG_LEVEL);
15+
16+
int esp_hosted_hal_init(const struct device *dev)
17+
{
18+
const esp_hosted_config_t *config = dev->config;
19+
20+
if (!spi_is_ready_dt(&config->spi_bus)) {
21+
LOG_ERR("SPI device is not ready");
22+
return -ENODEV;
23+
}
24+
25+
/* Configure pins. */
26+
gpio_pin_configure_dt(&config->dataready_gpio, GPIO_OUTPUT);
27+
gpio_pin_configure_dt(&config->reset_gpio, GPIO_OUTPUT);
28+
29+
/* Perform a hard-reset */
30+
gpio_pin_set_dt(&config->dataready_gpio, 1);
31+
gpio_pin_set_dt(&config->reset_gpio, 0);
32+
k_msleep(100);
33+
gpio_pin_set_dt(&config->reset_gpio, 1);
34+
k_msleep(500);
35+
36+
/* Configure handshake/dataready pins. */
37+
gpio_pin_configure_dt(&config->dataready_gpio, GPIO_INPUT);
38+
gpio_pin_configure_dt(&config->handshake_gpio, GPIO_INPUT);
39+
40+
return 0;
41+
}
42+
43+
bool esp_hosted_hal_data_ready(const struct device *dev)
44+
{
45+
const esp_hosted_config_t *config = dev->config;
46+
47+
return gpio_pin_get_dt(&config->dataready_gpio);
48+
}
49+
50+
int esp_hosted_hal_spi_transfer(const struct device *dev, void *tx, void *rx, uint32_t size)
51+
{
52+
int ret = 0;
53+
esp_hosted_data_t *data = dev->data;
54+
const esp_hosted_config_t *config = dev->config;
55+
56+
const struct spi_buf tx_buf = {.buf = tx ? tx : rx, .len = size};
57+
const struct spi_buf_set tx_set = {.buffers = &tx_buf, .count = 1};
58+
59+
const struct spi_buf rx_buf = {.buf = rx ? rx : tx, .len = size};
60+
const struct spi_buf_set rx_set = {.buffers = &rx_buf, .count = 1};
61+
62+
/* Wait for handshake pin to go high. */
63+
for (uint64_t start = k_uptime_get();; k_msleep(1)) {
64+
if (gpio_pin_get_dt(&config->handshake_gpio) &&
65+
(rx == NULL || gpio_pin_get_dt(&config->dataready_gpio))) {
66+
break;
67+
}
68+
if ((k_uptime_get() - start) >= 100) {
69+
return -ETIMEDOUT;
70+
}
71+
}
72+
73+
if (k_sem_take(&data->bus_sem, K_FOREVER) != 0) {
74+
return -1;
75+
}
76+
77+
/* Transfer SPI buffers. */
78+
if (spi_transceive_dt(&config->spi_bus, &tx_set, &rx_set)) {
79+
LOG_ERR("spi_transceive failed");
80+
ret = -EIO;
81+
}
82+
83+
k_sem_give(&data->bus_sem);
84+
return ret;
85+
}
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/*
2+
* Copyright (c) 2025 Arduino SA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef ZEPHYR_INCLUDED_DRIVERS_ESP_HOSTED_HAL_H
8+
#define ZEPHYR_INCLUDED_DRIVERS_ESP_HOSTED_HAL_H
9+
int esp_hosted_hal_init(const struct device *dev);
10+
bool esp_hosted_hal_data_ready(const struct device *dev);
11+
int esp_hosted_hal_spi_transfer(const struct device *dev, void *tx, void *rx, uint32_t size);
12+
#endif /* ZEPHYR_INCLUDED_DRIVERS_ESP_HOSTED_HAL_H */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
*.ssid max_size:32 max_length:31
2+
*.bssid max_size:17
3+
*.mac max_size:17
4+
*.pwd max_size:64 max_length:63
5+
*.entries type:FT_POINTER
6+
*.stations type:FT_POINTER
7+
*.init_data max_size:0
8+
esp_hosted_proto.pb max_size:256 max_count:64 anonymous_oneof:true type:FT_STATIC

0 commit comments

Comments
 (0)