esp32: add esp32 wifi driver
add support for esp32 wifi Signed-off-by: Shubham Kulkarni <shubham.kulkarni@espressif.com>
This commit is contained in:
parent
54fb930feb
commit
e16e606923
7 changed files with 431 additions and 0 deletions
|
@ -4,3 +4,4 @@ add_subdirectory_ifdef(CONFIG_WIFI_WINC1500 winc1500)
|
|||
add_subdirectory_ifdef(CONFIG_WIFI_SIMPLELINK simplelink)
|
||||
add_subdirectory_ifdef(CONFIG_WIFI_ESWIFI eswifi)
|
||||
add_subdirectory_ifdef(CONFIG_WIFI_ESP esp)
|
||||
add_subdirectory_ifdef(CONFIG_WIFI_ESP32 esp32)
|
||||
|
|
|
@ -33,5 +33,6 @@ source "drivers/wifi/winc1500/Kconfig.winc1500"
|
|||
source "drivers/wifi/simplelink/Kconfig.simplelink"
|
||||
source "drivers/wifi/eswifi/Kconfig.eswifi"
|
||||
source "drivers/wifi/esp/Kconfig.esp"
|
||||
source "drivers/wifi/esp32/Kconfig.esp32"
|
||||
|
||||
endif # WIFI
|
||||
|
|
5
drivers/wifi/esp32/CMakeLists.txt
Normal file
5
drivers/wifi/esp32/CMakeLists.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
zephyr_sources_ifdef(CONFIG_WIFI_ESP32
|
||||
src/esp_wifi_drv.c
|
||||
)
|
232
drivers/wifi/esp32/Kconfig.esp32
Normal file
232
drivers/wifi/esp32/Kconfig.esp32
Normal file
|
@ -0,0 +1,232 @@
|
|||
# Copyright 2020 Espressif Systems (Shanghai) PTE LTD
|
||||
|
||||
menuconfig WIFI_ESP32
|
||||
bool "ESP32 SoC WiFi support"
|
||||
select POSIX_API
|
||||
select THREAD_CUSTOM_DATA
|
||||
select DYNAMIC_INTERRUPTS
|
||||
help
|
||||
Enable ESP32 SoC WiFi support.
|
||||
|
||||
Note: POSIX_API is required by Wifi library. It shall be removed
|
||||
once NEWLIB gets supported.
|
||||
|
||||
if WIFI_ESP32
|
||||
|
||||
config ESP32_WIFI_SSID
|
||||
string "SSID of WiFi network"
|
||||
help
|
||||
SSID (network name) for the application to connect to.
|
||||
|
||||
config ESP32_WIFI_PASSWORD
|
||||
string "Password (WPA or WPA2) of WiFi network"
|
||||
help
|
||||
WiFi password (WPA or WPA2) for the example to use.
|
||||
|
||||
config ESP32_WIFI_STA_AUTO
|
||||
bool "Automatically connect to configured WiFi SSID"
|
||||
help
|
||||
WiFi driver will automatically connect to SSID.
|
||||
|
||||
config ESP32_WIFI_STA_RECONNECT
|
||||
bool "WiFi connection retry"
|
||||
default y
|
||||
help
|
||||
Set auto WiFI reconnection when disconnected.
|
||||
|
||||
config ESP32_WIFI_EVENT_TASK_STACK_SIZE
|
||||
int "Event Task Stack Size"
|
||||
default 4096
|
||||
|
||||
config ESP32_WIFI_EVENT_TASK_PRIO
|
||||
int "Event Task Priority"
|
||||
default 4
|
||||
|
||||
config ESP32_WIFI_STATIC_RX_BUFFER_NUM
|
||||
int "Max number of WiFi static RX buffers"
|
||||
range 2 25
|
||||
default 10
|
||||
help
|
||||
Set the number of WiFi static RX buffers. Each buffer takes approximately
|
||||
1.6KB of RAM. The static rx buffers are allocated when esp_wifi_init is
|
||||
called, they are not freed until esp_wifi_deinit is called.
|
||||
|
||||
WiFi hardware use these buffers to receive all 802.11 frames. A higher
|
||||
number may allow higher throughput but increases memory use.
|
||||
If ESP32_WIFI_AMPDU_RX_ENABLED is enabled, this value is recommended to
|
||||
set equal or bigger than ESP32_WIFI_RX_BA_WIN in order to achieve better
|
||||
throughput and compatibility with both stations and APs.
|
||||
|
||||
config ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM
|
||||
int "Max number of WiFi dynamic RX buffers"
|
||||
range 0 128
|
||||
default 32
|
||||
help
|
||||
Set the number of WiFi dynamic RX buffers, 0 means unlimited RX buffers
|
||||
will be allocated (provided sufficient free RAM). The size of each dynamic
|
||||
RX buffer depends on the size of the received data frame.
|
||||
|
||||
For each received data frame, the WiFi driver makes a copy to an RX buffer
|
||||
and then delivers it to the high layer TCP/IP stack. The dynamic RX buffer
|
||||
is freed after the higher layer has successfully received the data frame.
|
||||
|
||||
For some applications, WiFi data frames may be received faster than the
|
||||
application can process them. In these cases we may run out of memory if
|
||||
RX buffer number is unlimited (0). If a dynamic RX buffer limit is set,
|
||||
it should be at least the number of static RX buffers.
|
||||
|
||||
choice ESP32_WIFI_TX_BUFFER
|
||||
prompt "Type of WiFi TX buffers"
|
||||
default ESP32_WIFI_DYNAMIC_TX_BUFFER
|
||||
help
|
||||
Select type of WiFi TX buffers:
|
||||
|
||||
If "Static" is selected, WiFi TX buffers are allocated when WiFi is
|
||||
initialized and released when WiFi is de-initialized. The size of each
|
||||
static TX buffer is fixed to about 1.6KB.
|
||||
|
||||
If "Dynamic" is selected, each WiFi TX buffer is allocated as needed
|
||||
when a data frame is delivered to the Wifi driver from the TCP/IP stack.
|
||||
The buffer is freed after the data frame has been sent by the WiFi driver.
|
||||
The size of each dynamic TX buffer depends on the length of each data
|
||||
frame sent by the TCP/IP layer.
|
||||
|
||||
If PSRAM is enabled, "Static" should be selected to guarantee enough
|
||||
WiFi TX buffers. If PSRAM is disabled, "Dynamic" should be selected
|
||||
to improve the utilization of RAM.
|
||||
|
||||
config ESP32_WIFI_STATIC_TX_BUFFER
|
||||
bool "Static"
|
||||
config ESP32_WIFI_DYNAMIC_TX_BUFFER
|
||||
bool "Dynamic"
|
||||
endchoice
|
||||
|
||||
config ESP32_WIFI_TX_BUFFER_TYPE
|
||||
int
|
||||
default 0 if ESP32_WIFI_STATIC_TX_BUFFER
|
||||
default 1 if ESP32_WIFI_DYNAMIC_TX_BUFFER
|
||||
|
||||
config ESP32_WIFI_STATIC_TX_BUFFER_NUM
|
||||
int "Max number of WiFi static TX buffers"
|
||||
depends on ESP32_WIFI_STATIC_TX_BUFFER
|
||||
range 1 64
|
||||
default 16
|
||||
help
|
||||
Set the number of WiFi static TX buffers. Each buffer takes approximately
|
||||
1.6KB of RAM. The static RX buffers are allocated when esp_wifi_init() is
|
||||
called, they are not released until esp_wifi_deinit() is called.
|
||||
|
||||
For each transmitted data frame from the higher layer TCP/IP stack,
|
||||
the WiFi driver makes a copy of it in a TX buffer. For some applications
|
||||
especially UDP applications, the upper layer can deliver frames faster
|
||||
than WiFi layer can transmit.
|
||||
In these cases, we may run out of TX buffers.
|
||||
|
||||
config ESP32_WIFI_CACHE_TX_BUFFER_NUM
|
||||
int "Max number of WiFi cache TX buffers"
|
||||
range 16 128
|
||||
default 32
|
||||
help
|
||||
Set the number of WiFi cache TX buffer number.
|
||||
|
||||
For each TX packet from uplayer, such as LWIP etc, WiFi driver needs to
|
||||
allocate a static TX buffer and makes a copy of uplayer packet. If WiFi
|
||||
driver fails to allocate the static TX buffer, it caches the uplayer
|
||||
packets to a dedicated buffer queue, this option is used to configure the
|
||||
size of the cached TX queue.
|
||||
|
||||
config ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM
|
||||
int "Max number of WiFi dynamic TX buffers"
|
||||
depends on ESP32_WIFI_DYNAMIC_TX_BUFFER
|
||||
range 1 128
|
||||
default 32
|
||||
help
|
||||
Set the number of WiFi dynamic TX buffers. The size of each
|
||||
dynamic TXbuffer is not fixed, it depends on the size of each
|
||||
transmitted data frame.
|
||||
|
||||
For each transmitted frame from the higher layer TCP/IP stack,
|
||||
the WiFi driver makes a copy of it in a TX buffer. For some applications,
|
||||
especially UDP applications, the upper layer can deliver frames faster
|
||||
than WiFi layer can transmit. In these cases, we may run out of TX
|
||||
buffers.
|
||||
|
||||
config ESP32_WIFI_CSI_ENABLED
|
||||
bool "WiFi CSI(Channel State Information)"
|
||||
help
|
||||
Select this option to enable CSI(Channel State Information) feature.
|
||||
CSI takes about CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM KB of RAM.
|
||||
If CSI is not used, it is better to disable this feature in order
|
||||
to save memory.
|
||||
|
||||
config ESP32_WIFI_AMPDU_TX_ENABLED
|
||||
bool "WiFi AMPDU TX"
|
||||
default y
|
||||
help
|
||||
Select this option to enable AMPDU TX feature. It improves transmission
|
||||
error checking and overall network performance with the cost of processing
|
||||
speed. Helpful when the device is operating in crowded wireless area.
|
||||
|
||||
config ESP32_WIFI_TX_BA_WIN
|
||||
int "WiFi AMPDU TX BA window size"
|
||||
depends on ESP32_WIFI_AMPDU_TX_ENABLED
|
||||
range 2 32
|
||||
default 6
|
||||
help
|
||||
Set the size of WiFi Block Ack TX window. Generally a bigger value means
|
||||
higher throughput but more memory. Most of time we should NOT change the
|
||||
default value unless special reason, e.g. test the maximum
|
||||
UDP TX throughput with iperf etc. For iperf test in shieldbox,
|
||||
the recommended value is 9~12.
|
||||
|
||||
config ESP32_WIFI_AMPDU_RX_ENABLED
|
||||
bool "WiFi AMPDU RX"
|
||||
default y
|
||||
help
|
||||
Select this option to enable AMPDU RX feature. It improves transmission
|
||||
error checking and overall network performance with the cost of processing
|
||||
speed. Helpful when the device is operating in crowded wireless area.
|
||||
|
||||
config ESP32_WIFI_RX_BA_WIN
|
||||
int "WiFi AMPDU RX BA window size"
|
||||
depends on ESP32_WIFI_AMPDU_RX_ENABLED
|
||||
range 2 32
|
||||
default 6
|
||||
help
|
||||
Set the size of WiFi Block Ack RX window. Generally a bigger value means
|
||||
higher throughput and better compatibility but more memory. Most of time
|
||||
we should NOT change the default value unless special reason,
|
||||
e.g. test the maximum UDP RX throughput with iperf etc. For iperf test in
|
||||
shieldbox, the recommended value is 9~12. If PSRAM is used and WiFi memory
|
||||
is preferred to allocat in PSRAM first, the default and minimum value
|
||||
should be 16 to achieve better throughput and compatibility with both
|
||||
stations and APs.
|
||||
|
||||
choice ESP32_WIFI_TASK_CORE_ID
|
||||
prompt "WiFi Task Core ID"
|
||||
default ESP32_WIFI_TASK_PINNED_TO_CORE_0
|
||||
help
|
||||
Pinned WiFi task to core 0 (core 1 not supported yet)
|
||||
|
||||
config ESP32_WIFI_TASK_PINNED_TO_CORE_0
|
||||
bool "Core 0"
|
||||
endchoice
|
||||
|
||||
config ESP32_PHY_MAX_WIFI_TX_POWER
|
||||
int "Max WiFi TX power (dBm)"
|
||||
range 10 20
|
||||
default 20
|
||||
help
|
||||
Set maximum transmit power for WiFi radio. Actual transmit power for high
|
||||
data rates may be lower than this setting.
|
||||
|
||||
config ESP32_PHY_MAX_TX_POWER
|
||||
int
|
||||
default ESP32_PHY_MAX_WIFI_TX_POWER
|
||||
|
||||
config ESP32_WIFI_SW_COEXIST_ENABLE
|
||||
bool
|
||||
help
|
||||
Software controls WiFi/Bluetooth coexistence. Not supported yet.
|
||||
|
||||
endif # WIFI_ESP32
|
184
drivers/wifi/esp32/src/esp_wifi_drv.c
Normal file
184
drivers/wifi/esp32/src/esp_wifi_drv.c
Normal file
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Espressif Systems (Shanghai) Co., Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT espressif_esp32_wifi
|
||||
|
||||
#include <logging/log.h>
|
||||
LOG_MODULE_REGISTER(esp32_wifi, CONFIG_WIFI_LOG_LEVEL);
|
||||
|
||||
#include <net/ethernet.h>
|
||||
#include <net/net_pkt.h>
|
||||
#include <net/net_if.h>
|
||||
#include <device.h>
|
||||
#include <soc.h>
|
||||
#include <ethernet/eth_stats.h>
|
||||
#include "esp_networking_priv.h"
|
||||
#include "esp_private/wifi.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_wifi_system.h"
|
||||
#include "esp_wpa.h"
|
||||
|
||||
#define DEV_DATA(dev) \
|
||||
((struct esp32_wifi_runtime *)(dev)->data)
|
||||
|
||||
/* use global iface pointer to support any ethernet driver */
|
||||
/* necessary for wifi callback functions */
|
||||
static struct net_if *esp32_wifi_iface;
|
||||
|
||||
struct esp32_wifi_runtime {
|
||||
struct net_if *iface;
|
||||
uint8_t mac_addr[6];
|
||||
bool tx_err;
|
||||
uint32_t tx_word;
|
||||
int tx_pos;
|
||||
uint8_t frame_buf[NET_ETH_MAX_FRAME_SIZE];
|
||||
#if defined(CONFIG_NET_STATISTICS_ETHERNET)
|
||||
struct net_stats_eth stats;
|
||||
#endif
|
||||
};
|
||||
|
||||
static int eth_esp32_send(const struct device *dev, struct net_pkt *pkt)
|
||||
{
|
||||
const int pkt_len = net_pkt_get_len(pkt);
|
||||
|
||||
/* Read the packet payload */
|
||||
if (net_pkt_read(pkt, DEV_DATA(dev)->frame_buf, pkt_len) < 0) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* Enqueue packet for transmission */
|
||||
esp_wifi_internal_tx(ESP_IF_WIFI_STA, (void *)DEV_DATA(dev)->frame_buf, pkt_len);
|
||||
|
||||
LOG_DBG("pkt sent %p len %d", pkt, pkt_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static esp_err_t eth_esp32_rx(void *buffer, uint16_t len, void *eb)
|
||||
{
|
||||
struct net_pkt *pkt;
|
||||
|
||||
if (esp32_wifi_iface == NULL) {
|
||||
LOG_ERR("network interface unavailable");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
pkt = net_pkt_rx_alloc_with_buffer(esp32_wifi_iface, len,
|
||||
AF_UNSPEC, 0, K_NO_WAIT);
|
||||
if (!pkt) {
|
||||
LOG_ERR("Failed to get net buffer");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (net_pkt_write(pkt, buffer, len) < 0) {
|
||||
LOG_ERR("Failed to write pkt");
|
||||
goto pkt_unref;
|
||||
}
|
||||
|
||||
if (net_recv_data(esp32_wifi_iface, pkt) < 0) {
|
||||
LOG_ERR("Failed to push received data");
|
||||
goto pkt_unref;
|
||||
}
|
||||
|
||||
esp_wifi_internal_free_rx_buffer(eb);
|
||||
return ESP_OK;
|
||||
|
||||
pkt_unref:
|
||||
net_pkt_unref(pkt);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
/* internally used by wifi hal layer */
|
||||
void esp_wifi_set_net_state(bool state)
|
||||
{
|
||||
if (esp32_wifi_iface == NULL) {
|
||||
LOG_ERR("network interface unavailable");
|
||||
return;
|
||||
}
|
||||
|
||||
if (state) {
|
||||
net_if_up(esp32_wifi_iface);
|
||||
} else {
|
||||
net_if_down(esp32_wifi_iface);
|
||||
}
|
||||
}
|
||||
|
||||
static void eth_esp32_init(struct net_if *iface)
|
||||
{
|
||||
const struct device *dev = net_if_get_device(iface);
|
||||
struct esp32_wifi_runtime *dev_data = DEV_DATA(dev);
|
||||
|
||||
dev_data->iface = iface;
|
||||
esp32_wifi_iface = iface;
|
||||
|
||||
/* Start interface when we are actually connected with WiFi network */
|
||||
net_if_flag_set(iface, NET_IF_NO_AUTO_START);
|
||||
esp_read_mac(dev_data->mac_addr, ESP_MAC_WIFI_STA);
|
||||
|
||||
/* Assign link local address. */
|
||||
net_if_set_link_addr(iface,
|
||||
dev_data->mac_addr, 6, NET_LINK_ETHERNET);
|
||||
|
||||
ethernet_init(iface);
|
||||
|
||||
esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, eth_esp32_rx);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_NET_STATISTICS_ETHERNET)
|
||||
static struct net_stats_eth *eth_esp32_stats(const struct device *dev)
|
||||
{
|
||||
return &(DEV_DATA(dev)->stats);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int eth_esp32_dev_init(const struct device *dev)
|
||||
{
|
||||
esp_timer_init();
|
||||
esp_event_init();
|
||||
|
||||
wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT();
|
||||
esp_err_t ret = esp_wifi_init(&config);
|
||||
|
||||
ret |= esp_supplicant_init();
|
||||
ret |= esp_wifi_start();
|
||||
|
||||
if (IS_ENABLED(CONFIG_ESP32_WIFI_STA_AUTO)) {
|
||||
wifi_config_t wifi_config = {
|
||||
.sta = {
|
||||
.ssid = CONFIG_ESP32_WIFI_SSID,
|
||||
.password = CONFIG_ESP32_WIFI_PASSWORD,
|
||||
},
|
||||
};
|
||||
|
||||
ret = esp_wifi_set_mode(WIFI_MODE_STA);
|
||||
ret |= esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config);
|
||||
ret |= esp_wifi_connect();
|
||||
}
|
||||
|
||||
if (ret != ESP_OK) {
|
||||
LOG_ERR("Connect failed");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static struct esp32_wifi_runtime eth_data;
|
||||
|
||||
static const struct ethernet_api eth_esp32_apis = {
|
||||
.iface_api.init = eth_esp32_init,
|
||||
.send = eth_esp32_send,
|
||||
#if defined(CONFIG_NET_STATISTICS_ETHERNET)
|
||||
.get_stats = eth_esp32_stats,
|
||||
#endif
|
||||
};
|
||||
|
||||
NET_DEVICE_DT_INST_DEFINE(0,
|
||||
eth_esp32_dev_init, device_pm_control_nop,
|
||||
ð_data, NULL, CONFIG_ETH_INIT_PRIORITY,
|
||||
ð_esp32_apis, ETHERNET_L2,
|
||||
NET_L2_GET_CTX_TYPE(ETHERNET_L2), NET_ETH_MTU);
|
|
@ -50,6 +50,11 @@
|
|||
status = "ok";
|
||||
};
|
||||
|
||||
wifi: wifi {
|
||||
compatible = "espressif,esp32-wifi";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
uart0: uart@3ff40000 {
|
||||
compatible = "espressif,esp32-uart";
|
||||
reg = <0x3ff40000 0x400>;
|
||||
|
@ -161,5 +166,7 @@
|
|||
clocks = <&rtc ESP32_SPI3_MODULE>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -39,6 +39,7 @@ PROVIDE ( crc32_le = 0x4005cfec );
|
|||
PROVIDE ( Cache_Read_Disable_rom = 0x40009ab8 );
|
||||
PROVIDE ( Cache_Read_Enable_rom = 0x40009a84 );
|
||||
PROVIDE ( Cache_Read_Init_rom = 0x40009950 );
|
||||
PROVIDE ( phy_get_romfuncs = 0x40004100 );
|
||||
PROVIDE ( SPI1 = 0x3ff42fff );
|
||||
PROVIDE ( SPI2 = 0x3ff64fff );
|
||||
PROVIDE ( SPI3 = 0x3ff65fff );
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue