diff --git a/arch/risc-v/src/common/espressif/CMakeLists.txt b/arch/risc-v/src/common/espressif/CMakeLists.txt index ccb926cedb8..47b1bbeffbc 100644 --- a/arch/risc-v/src/common/espressif/CMakeLists.txt +++ b/arch/risc-v/src/common/espressif/CMakeLists.txt @@ -164,6 +164,10 @@ if(CONFIG_ESP_MCPWM) list(APPEND SRCS esp_mcpwm.c) endif() +if(CONFIG_ESPRESSIF_EMAC) + list(APPEND SRCS esp_emac.c) +endif() + if(CONFIG_SYSTEM_NXDIAG_ESPRESSIF_CHIP_WO_TOOL) list(APPEND SRCS esp_nxdiag.c) endif() @@ -209,7 +213,7 @@ if(DEFINED ENV{ESP_HAL_3RDPARTY_VERSION}) CACHE STRING "ESP HAL 3rdparty version") else() set(ESP_HAL_3RDPARTY_VERSION - 8630b6b82cb84838f86332e00f39ab72a64cf186 + c32f1ad13f4ce8312de494e8b79c88fda10fe9ed CACHE STRING "ESP HAL 3rdparty version") endif() diff --git a/arch/risc-v/src/common/espressif/Kconfig b/arch/risc-v/src/common/espressif/Kconfig index 7e73d90e6d1..3c16ea9c4a2 100644 --- a/arch/risc-v/src/common/espressif/Kconfig +++ b/arch/risc-v/src/common/espressif/Kconfig @@ -1995,6 +1995,17 @@ config ESPRESSIF_BLE ---help--- Enable BLE support +config ESPRESSIF_EMAC + bool "Ethernet MAC" + depends on ARCH_CHIP_ESP32P4 + default n + select NET + select ARCH_PHY_INTERRUPT + select ESPRESSIF_HR_TIMER + select SCHED_LPWORK + ---help--- + Enable Ethernet MAC support. + config ESP_COEX_SW_COEXIST_ENABLE bool "Software WiFi/Bluetooth/IEEE 802.15.4 coexistence" depends on (ESPRESSIF_WIFI && ESPRESSIF_BLE) || \ @@ -2462,6 +2473,157 @@ endif # ESPRESSIF_ADC_2 endmenu # ADC Configuration +menu "Ethernet Configuration" + depends on ESPRESSIF_EMAC + +config ESPRESSIF_ETH_NRXDESC + int "RX descriptor number" + default 20 + ---help--- + Number of DMA receive descriptors/buffers used by the EMAC. + Each buffer is CONFIG_ESPRESSIF_ETH_DMA_BUFFER_SIZE bytes. + The default of 20 provides headroom for TCP-style ACK bursts + that arrive while the upper layer is busy submitting a TX burst + (otherwise the EMAC asserts RX_BUFF_UNAVAILABLE and silently + drops incoming frames, forcing TCP retransmissions). + +config ESPRESSIF_ETH_NTXDESC + int "TX descriptor number" + default 20 + ---help--- + Number of DMA transmit descriptors/buffers used by the EMAC. + With CONFIG_ESPRESSIF_ETH_DMA_BUFFER_SIZE=1600, each descriptor + holds one Ethernet frame. TCP send() bursts up to ~12 segments + back-to-back; 20 descriptors gives ample headroom so that + esp_eth_transmit() never returns ESP_ERR_NO_MEM mid-burst. + If the ring is exhausted, frames are silently dropped and + retransmissions happen via fast-retransmit/RTO, drastically + degrading throughput. + +config ESPRESSIF_ETH_DMA_BUFFER_SIZE + int "DMA buffer size (bytes)" + default 1600 + range 256 1600 + ---help--- + Size of each DMA buffer used by the EMAC (must match esp_eth's + CONFIG_ETH_DMA_BUFFER_SIZE). At the maximum 1600 bytes one + buffer holds an entire 1518-byte Ethernet frame, so a typical + TX uses exactly one descriptor. Lower values cause the MAC DMA + to chain multiple descriptors per frame, reducing the effective + number of frames the ring can hold. + +config ESPRESSIF_ETH_TX_MAX_RETRIES + int "TX submit retry budget" + default 32 + range 1 256 + ---help--- + Number of times emac_transmit() retries esp_eth_transmit() when + the DMA TX descriptor ring is fully owned by hardware + (ESP_ERR_NO_MEM). Between attempts the driver yields the CPU + via sched_yield() so that the RX worker (and any other peer at + the same priority) can run while the EMAC DMA drains its TX + descriptors in the background. The default of 32 covers a + full ring rotation under sustained TCP bursts while remaining + bounded; increase if the network has very high latency between + TX submissions and DMA descriptor recycling. + +config ESPRESSIF_ETH_PHY_ADDR + int "PHY address" + default 1 + range 0 31 + ---help--- + Address of the external Ethernet PHY on the SMI (MDC/MDIO) bus. + +config ESPRESSIF_ETH_MDC_GPIO + int "MDC GPIO" + default 31 if ARCH_CHIP_ESP32P4 + default -1 + ---help--- + GPIO number connected to the PHY MDC pin. The shipped default + corresponds to the ESP32-P4 Function EV Board V1.5.2; override + for other boards/SoCs. + +config ESPRESSIF_ETH_MDIO_GPIO + int "MDIO GPIO" + default 52 if ARCH_CHIP_ESP32P4 + default -1 + ---help--- + GPIO number connected to the PHY MDIO pin. The shipped default + corresponds to the ESP32-P4 Function EV Board V1.5.2; override + for other boards/SoCs. + +config ESPRESSIF_ETH_RMII_CLK_GPIO + int "RMII REF_CLK GPIO" + default 50 if ARCH_CHIP_ESP32P4 + default -1 + ---help--- + GPIO number for the RMII 50MHz reference clock (input). The + shipped default corresponds to the ESP32-P4 Function EV Board + V1.5.2; override for other boards/SoCs. + +config ESPRESSIF_ETH_RMII_TX_EN_GPIO + int "RMII TX_EN GPIO" + default 49 if ARCH_CHIP_ESP32P4 + default -1 + ---help--- + GPIO number connected to the RMII TX_EN pin. Default is for the + ESP32-P4 Function EV Board V1.5.2. + +config ESPRESSIF_ETH_RMII_TXD0_GPIO + int "RMII TXD0 GPIO" + default 34 if ARCH_CHIP_ESP32P4 + default -1 + ---help--- + GPIO number connected to the RMII TXD0 pin. Default is for the + ESP32-P4 Function EV Board V1.5.2. + +config ESPRESSIF_ETH_RMII_TXD1_GPIO + int "RMII TXD1 GPIO" + default 35 if ARCH_CHIP_ESP32P4 + default -1 + ---help--- + GPIO number connected to the RMII TXD1 pin. Default is for the + ESP32-P4 Function EV Board V1.5.2. + +config ESPRESSIF_ETH_RMII_CRS_DV_GPIO + int "RMII CRS_DV GPIO" + default 28 if ARCH_CHIP_ESP32P4 + default -1 + ---help--- + GPIO number connected to the RMII CRS_DV pin. Default is for + the ESP32-P4 Function EV Board V1.5.2. + +config ESPRESSIF_ETH_RMII_RXD0_GPIO + int "RMII RXD0 GPIO" + default 29 if ARCH_CHIP_ESP32P4 + default -1 + ---help--- + GPIO number connected to the RMII RXD0 pin. Default is for the + ESP32-P4 Function EV Board V1.5.2. + +config ESPRESSIF_ETH_RMII_RXD1_GPIO + int "RMII RXD1 GPIO" + default 30 if ARCH_CHIP_ESP32P4 + default -1 + ---help--- + GPIO number connected to the RMII RXD1 pin. Default is for the + ESP32-P4 Function EV Board V1.5.2. + +config ESPRESSIF_ETH_ENABLE_PHY_RSTPIN + bool "Enable PHY reset pin" + default y + +config ESPRESSIF_ETH_PHY_RST_GPIO + int "PHY reset GPIO" + default 51 if ARCH_CHIP_ESP32P4 + default -1 + depends on ESPRESSIF_ETH_ENABLE_PHY_RSTPIN + ---help--- + GPIO number connected to the PHY reset pin. Default is for the + ESP32-P4 Function EV Board V1.5.2. + +endmenu # Ethernet Configuration + menu "Wi-Fi Configuration" depends on ESPRESSIF_WIFI diff --git a/arch/risc-v/src/common/espressif/Make.defs b/arch/risc-v/src/common/espressif/Make.defs index 8e27bde0839..43b7090d208 100644 --- a/arch/risc-v/src/common/espressif/Make.defs +++ b/arch/risc-v/src/common/espressif/Make.defs @@ -169,6 +169,10 @@ ifeq ($(CONFIG_ESP_MCPWM),y) CHIP_CSRCS += esp_mcpwm.c endif +ifeq ($(CONFIG_ESPRESSIF_EMAC),y) + CHIP_CSRCS += esp_emac.c +endif + ifeq ($(CONFIG_SYSTEM_NXDIAG_ESPRESSIF_CHIP_WO_TOOL),y) CHIP_CSRCS += esp_nxdiag.c endif @@ -217,7 +221,7 @@ endif ESP_HAL_3RDPARTY_REPO = esp-hal-3rdparty ifndef ESP_HAL_3RDPARTY_VERSION - ESP_HAL_3RDPARTY_VERSION = 8630b6b82cb84838f86332e00f39ab72a64cf186 + ESP_HAL_3RDPARTY_VERSION = c32f1ad13f4ce8312de494e8b79c88fda10fe9ed endif ifndef ESP_HAL_3RDPARTY_URL diff --git a/arch/risc-v/src/common/espressif/esp_emac.c b/arch/risc-v/src/common/espressif/esp_emac.c new file mode 100644 index 00000000000..c97bad3812a --- /dev/null +++ b/arch/risc-v/src/common/espressif/esp_emac.c @@ -0,0 +1,791 @@ +/**************************************************************************** + * arch/risc-v/src/common/espressif/esp_emac.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifdef CONFIG_ESPRESSIF_EMAC + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "esp_eth.h" +#include "esp_eth_driver.h" +#include "esp_eth_mac.h" +#include "esp_eth_mac_esp.h" +#include "esp_eth_phy.h" +#include "esp_event.h" +#include "esp_mac.h" + +#include "esp_emac.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ETH_HEADER_LEN (14) +#define ETH_VLANTAG_LEN (4) +#define ETH_MAXPAYLOAD_LEN (1500) +#define ETH_CRC_LEN (4) + +#define ETH_MAXPKT_LEN (ETH_HEADER_LEN + ETH_VLANTAG_LEN + \ + ETH_MAXPAYLOAD_LEN + ETH_CRC_LEN) + +#define EMAC_PHY_ADDR (CONFIG_ESPRESSIF_ETH_PHY_ADDR) +#define NET2PRIV(_dev) ((struct esp_emac_s *)(_dev)) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct esp_emac_s +{ + struct netdev_lowerhalf_s dev; + + esp_eth_handle_t handle; + + bool installed; + bool ifup; + bool link_up; + + spinlock_t lock; + netpkt_queue_t rxq; + uint8_t txbuf[ETH_MAXPKT_LEN]; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct esp_emac_s g_esp_emac; +static mutex_t g_lock = NXMUTEX_INITIALIZER; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int emac_transmit(struct netdev_lowerhalf_s *dev, netpkt_t *pkt); +static netpkt_t *emac_receive(struct netdev_lowerhalf_s *dev); +static esp_err_t emac_stack_input(esp_eth_handle_t hdl, + uint8_t *buffer, uint32_t length, + void *priv_arg); +static void emac_eth_event_handler(void *arg, esp_event_base_t base, + int32_t id, void *data); +static int emac_ifup(struct netdev_lowerhalf_s *dev); +static int emac_ifdown(struct netdev_lowerhalf_s *dev); +#if defined(CONFIG_NET_MCASTGROUP) || defined(CONFIG_NET_ICMPv6) +static int emac_addmac(struct netdev_lowerhalf_s *dev, const uint8_t *mac); +#endif +#ifdef CONFIG_NET_MCASTGROUP +static int emac_rmmac(struct netdev_lowerhalf_s *dev, const uint8_t *mac); +#endif +#ifdef CONFIG_NETDEV_IOCTL +static int emac_ioctl(struct netdev_lowerhalf_s *dev, int cmd, + unsigned long arg); +#endif + +static const struct netdev_ops_s g_emac_ops = +{ + .ifup = emac_ifup, + .ifdown = emac_ifdown, + .transmit = emac_transmit, + .receive = emac_receive, +#ifdef CONFIG_NET_MCASTGROUP + .addmac = emac_addmac, + .rmmac = emac_rmmac, +#endif +#ifdef CONFIG_NETDEV_IOCTL + .ioctl = emac_ioctl, +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: emac_transmit + * + * Description: + * Push one outbound packet from the netdev lower-half TX path to esp_eth. + * + * Backpressure handling: + * + * When a TCP burst is in flight the EMAC DMA TX descriptor ring may be + * fully owned by the DMA engine. In that case esp_eth_transmit() returns + * ESP_ERR_NO_MEM and we must wait until the hardware releases at least + * one descriptor before submitting the frame, otherwise the upper layer + * would treat the frame as lost and only recover via TCP retransmission, + * which collapses throughput. + * + * The wait is implemented with sched_yield() rather than a fixed-time + * delay: it relinquishes the CPU to any runnable peer (most importantly + * the RX worker that consumes inbound TCP ACKs) without imposing an + * arbitrary sleep, while the EMAC DMA hardware drains its TX descriptors + * in parallel with no CPU involvement. + * + * Input Parameters: + * dev - Lower-half network device state. + * pkt - Packet to transmit. + * + * Returned Value: + * OK on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int emac_transmit(struct netdev_lowerhalf_s *dev, netpkt_t *pkt) +{ + struct esp_emac_s *priv = NET2PRIV(dev); + unsigned int len; + esp_err_t err; + unsigned int retries = 0; + int ret; + + len = netpkt_getdatalen(dev, pkt); + + if (!priv->installed || !priv->ifup) + { + return -ENETDOWN; + } + + if (len == 0 || len > ETH_MAXPKT_LEN) + { + return -EMSGSIZE; + } + + ret = netpkt_copyout(dev, priv->txbuf, pkt, len, 0); + if (ret < 0) + { + return ret; + } + + do + { + err = esp_eth_transmit(priv->handle, priv->txbuf, len); + if (err != ESP_ERR_NO_MEM) + { + break; + } + + sched_yield(); + } + while (++retries < CONFIG_ESPRESSIF_ETH_TX_MAX_RETRIES); + + if (err != ESP_OK) + { + nerr("ERROR: esp_eth_transmit failed: %d\n", (int)err); + return -EIO; + } + + netpkt_free(dev, pkt, NETPKT_TX); + netdev_lower_txdone(dev); + return OK; +} + +/**************************************************************************** + * Name: emac_receive + * + * Description: + * Pop one received packet from the RX queue and hand it to upper-half. + * + * Input Parameters: + * dev - Lower-half network device state. + * + * Returned Value: + * Received packet pointer on success; NULL when no packet is queued. + * + ****************************************************************************/ + +static netpkt_t *emac_receive(struct netdev_lowerhalf_s *dev) +{ + struct esp_emac_s *priv = NET2PRIV(dev); + irqstate_t flags; + netpkt_t *pkt; + + flags = spin_lock_irqsave(&priv->lock); + pkt = netpkt_remove_queue(&priv->rxq); + spin_unlock_irqrestore(&priv->lock, flags); + return pkt; +} + +/**************************************************************************** + * Name: emac_stack_input + * + * Description: + * esp_eth input-path callback. Convert the received frame to netpkt and + * queue it to be consumed by netdev upper-half. + * + * Input Parameters: + * hdl - esp_eth driver handle. + * buffer - Frame buffer allocated by esp_eth (ownership transferred). + * length - Frame length in bytes. + * priv_arg - Opaque pointer to struct esp_emac_s. + * + * Returned Value: + * ESP_OK on success; ESP_ERR_NO_MEM on allocation or queue failures. + * + ****************************************************************************/ + +static esp_err_t emac_stack_input(esp_eth_handle_t hdl, + uint8_t *buffer, uint32_t length, + void *priv_arg) +{ + struct esp_emac_s *priv = (struct esp_emac_s *)priv_arg; + netpkt_t *pkt; + irqstate_t flags; + int ret; + + UNUSED(hdl); + + pkt = netpkt_alloc(&priv->dev, NETPKT_RX); + if (pkt == NULL) + { + nerr("ERROR: emac RX netpkt_alloc failed\n"); + free(buffer); + return ESP_ERR_NO_MEM; + } + + ret = netpkt_copyin(&priv->dev, pkt, buffer, length, 0); + free(buffer); + if (ret < 0) + { + netpkt_free(&priv->dev, pkt, NETPKT_RX); + return ESP_ERR_NO_MEM; + } + + flags = spin_lock_irqsave(&priv->lock); + ret = netpkt_tryadd_queue(pkt, &priv->rxq); + spin_unlock_irqrestore(&priv->lock, flags); + + if (ret < 0) + { + nerr("ERROR: emac RX queue full\n"); + netpkt_free(&priv->dev, pkt, NETPKT_RX); + return ESP_ERR_NO_MEM; + } + + netdev_lower_rxready(&priv->dev); + return ESP_OK; +} + +/**************************************************************************** + * Name: emac_eth_event_handler + * + * Description: + * Receive ETH_EVENT notifications posted by esp_eth (link up/down, + * start/stop) and update NuttX carrier state accordingly. + * + * Input Parameters: + * arg - Opaque pointer to struct esp_emac_s. + * base - Event base (unused; expected ETH_EVENT). + * id - Event identifier (ETHERNET_EVENT_*). + * data - Event payload. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void emac_eth_event_handler(void *arg, esp_event_base_t base, + int32_t id, void *data) +{ + struct esp_emac_s *priv = (struct esp_emac_s *)arg; + + UNUSED(base); + UNUSED(data); + + switch (id) + { + case ETHERNET_EVENT_CONNECTED: + ninfo("Ethernet link up\n"); + priv->link_up = true; + netdev_lower_carrier_on(&priv->dev); + break; + + case ETHERNET_EVENT_DISCONNECTED: + ninfo("Ethernet link down\n"); + priv->link_up = false; + netdev_lower_carrier_off(&priv->dev); + break; + + case ETHERNET_EVENT_START: + ninfo("Ethernet started\n"); + break; + + case ETHERNET_EVENT_STOP: + ninfo("Ethernet stopped\n"); + break; + + default: + break; + } +} + +/**************************************************************************** + * Name: emac_ifup + * + * Description: + * Bring the network interface up and start the esp_eth state machine. + * + * Input Parameters: + * dev - NuttX network interface state. + * + * Returned Value: + * OK on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int emac_ifup(struct netdev_lowerhalf_s *dev) +{ + struct esp_emac_s *priv = NET2PRIV(dev); + esp_err_t err; + +#ifdef CONFIG_NET_IPv4 + ninfo("Bringing up: %d.%d.%d.%d\n", + (int)(dev->netdev.d_ipaddr & 0xff), + (int)((dev->netdev.d_ipaddr >> 8) & 0xff), + (int)((dev->netdev.d_ipaddr >> 16) & 0xff), + (int)((dev->netdev.d_ipaddr >> 24) & 0xff)); +#endif + + if (!priv->installed) + { + nerr("ERROR: esp_eth driver not installed\n"); + return -ENODEV; + } + + if (priv->ifup) + { + return OK; + } + + err = esp_eth_start(priv->handle); + if (err != ESP_OK) + { + nerr("ERROR: esp_eth_start failed: %d\n", (int)err); + return -EIO; + } + + priv->ifup = true; + return OK; +} + +/**************************************************************************** + * Name: emac_ifdown + * + * Description: + * Bring the network interface down and stop the esp_eth state machine. + * + * Input Parameters: + * dev - NuttX network interface state. + * + * Returned Value: + * OK. + * + ****************************************************************************/ + +static int emac_ifdown(struct netdev_lowerhalf_s *dev) +{ + struct esp_emac_s *priv = NET2PRIV(dev); + esp_err_t err; + + ninfo("Taking the network down\n"); + + if (!priv->ifup) + { + return OK; + } + + err = esp_eth_stop(priv->handle); + if (err != ESP_OK) + { + nerr("ERROR: esp_eth_stop failed: %d\n", (int)err); + } + + priv->ifup = false; + priv->link_up = false; + netdev_lower_carrier_off(dev); + + return OK; +} + +#if defined(CONFIG_NET_MCASTGROUP) || defined(CONFIG_NET_ICMPv6) +/**************************************************************************** + * Name: emac_addmac + * + * Description: + * Add a multicast MAC address filter entry to the underlying ESP Ethernet + * driver. + * + * Input Parameters: + * dev - NuttX network interface state. + * mac - MAC address to add to the multicast filter list. + * + * Returned Value: + * OK. + * + ****************************************************************************/ + +static int emac_addmac(struct netdev_lowerhalf_s *dev, const uint8_t *mac) +{ + struct esp_emac_s *priv = NET2PRIV(dev); + + ninfo("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + esp_eth_ioctl(priv->handle, ETH_CMD_ADD_MAC_FILTER, (void *)mac); + return OK; +} +#endif + +#ifdef CONFIG_NET_MCASTGROUP +/**************************************************************************** + * Name: emac_rmmac + * + * Description: + * Remove a multicast MAC address filter entry from the underlying ESP + * Ethernet driver. + * + * Input Parameters: + * dev - NuttX network interface state. + * mac - MAC address to remove from the multicast filter list. + * + * Returned Value: + * OK. + * + ****************************************************************************/ + +static int emac_rmmac(struct netdev_lowerhalf_s *dev, const uint8_t *mac) +{ + struct esp_emac_s *priv = NET2PRIV(dev); + + ninfo("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + esp_eth_ioctl(priv->handle, ETH_CMD_DEL_MAC_FILTER, (void *)mac); + return OK; +} +#endif + +#ifdef CONFIG_NETDEV_IOCTL +/**************************************************************************** + * Name: emac_ioctl + * + * Description: + * Handle network device ioctl requests supported by the ESP EMAC driver. + * + * Input Parameters: + * dev - NuttX network interface state. + * cmd - Ioctl command code. + * arg - Command-specific argument. + * + * Returned Value: + * OK on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int emac_ioctl(struct netdev_lowerhalf_s *dev, int cmd, + unsigned long arg) +{ + struct esp_emac_s *priv = NET2PRIV(dev); + int ret; + + ret = nxmutex_lock(&g_lock); + if (ret < 0) + { + return ret; + } + + switch (cmd) + { +#ifdef CONFIG_NETDEV_PHY_IOCTL + case SIOCGMIIPHY: + { + struct mii_ioctl_data_s *req = + (struct mii_ioctl_data_s *)((uintptr_t)arg); + uint32_t phy_addr = 0; + + if (esp_eth_ioctl(priv->handle, ETH_CMD_G_PHY_ADDR, &phy_addr) + == ESP_OK) + { + req->phy_id = (uint16_t)phy_addr; + ret = OK; + } + else + { + ret = -EIO; + } + } + break; + + case SIOCGMIIREG: + { + struct mii_ioctl_data_s *req = + (struct mii_ioctl_data_s *)((uintptr_t)arg); + esp_eth_phy_reg_rw_data_t rw; + uint32_t val = 0; + + rw.reg_addr = req->reg_num; + rw.reg_value_p = &val; + if (esp_eth_ioctl(priv->handle, ETH_CMD_READ_PHY_REG, &rw) + == ESP_OK) + { + req->val_out = (uint16_t)val; + ret = OK; + } + else + { + ret = -EIO; + } + } + break; + + case SIOCSMIIREG: + { + struct mii_ioctl_data_s *req = + (struct mii_ioctl_data_s *)((uintptr_t)arg); + esp_eth_phy_reg_rw_data_t rw; + uint32_t val = req->val_in; + + rw.reg_addr = req->reg_num; + rw.reg_value_p = &val; + if (esp_eth_ioctl(priv->handle, ETH_CMD_WRITE_PHY_REG, &rw) + == ESP_OK) + { + ret = OK; + } + else + { + ret = -EIO; + } + } + break; +#endif /* CONFIG_NETDEV_PHY_IOCTL */ + + default: + ret = -ENOTTY; + break; + } + + nxmutex_unlock(&g_lock); + return ret; +} +#endif /* CONFIG_NETDEV_IOCTL */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_emac_init + * + * Description: + * Create the esp_eth MAC+PHY+driver stack, register our RX callback and + * ETH_EVENT handler, pull the factory-programmed MAC address from eFuse + * and register the interface with the NuttX network stack. + * + * Input Parameters: + * None. + * + * Returned Value: + * OK on success; a negated errno value on failure. + * + ****************************************************************************/ + +int esp_emac_init(void) +{ + struct esp_emac_s *priv = &g_esp_emac; + esp_eth_mac_t *mac = NULL; + esp_eth_phy_t *phy = NULL; + unsigned int quota; + uint8_t mac_addr[6]; + esp_err_t err; + int ret; + + eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG(); + eth_esp32_emac_config_t esp32_cfg = ETH_ESP32_EMAC_DEFAULT_CONFIG(); + eth_phy_config_t phy_cfg = ETH_PHY_DEFAULT_CONFIG(); + + memset(priv, 0, sizeof(*priv)); + IOB_QINIT(&priv->rxq); + spin_lock_init(&priv->lock); + + /* Override default RMII/SMI pin configuration from Kconfig. */ + + esp32_cfg.smi_gpio.mdc_num = CONFIG_ESPRESSIF_ETH_MDC_GPIO; + esp32_cfg.smi_gpio.mdio_num = CONFIG_ESPRESSIF_ETH_MDIO_GPIO; + +#if defined(SOC_EMAC_USE_MULTI_IO_MUX) || defined(SOC_EMAC_MII_USE_GPIO_MATRIX) + esp32_cfg.emac_dataif_gpio.rmii.tx_en_num = + CONFIG_ESPRESSIF_ETH_RMII_TX_EN_GPIO; + esp32_cfg.emac_dataif_gpio.rmii.txd0_num = + CONFIG_ESPRESSIF_ETH_RMII_TXD0_GPIO; + esp32_cfg.emac_dataif_gpio.rmii.txd1_num = + CONFIG_ESPRESSIF_ETH_RMII_TXD1_GPIO; + esp32_cfg.emac_dataif_gpio.rmii.crs_dv_num = + CONFIG_ESPRESSIF_ETH_RMII_CRS_DV_GPIO; + esp32_cfg.emac_dataif_gpio.rmii.rxd0_num = + CONFIG_ESPRESSIF_ETH_RMII_RXD0_GPIO; + esp32_cfg.emac_dataif_gpio.rmii.rxd1_num = + CONFIG_ESPRESSIF_ETH_RMII_RXD1_GPIO; +#endif + + esp32_cfg.clock_config.rmii.clock_gpio = + CONFIG_ESPRESSIF_ETH_RMII_CLK_GPIO; + + phy_cfg.phy_addr = EMAC_PHY_ADDR; +#ifdef CONFIG_ESPRESSIF_ETH_ENABLE_PHY_RSTPIN + phy_cfg.reset_gpio_num = CONFIG_ESPRESSIF_ETH_PHY_RST_GPIO; +#else + phy_cfg.reset_gpio_num = -1; +#endif + + mac = esp_eth_mac_new_esp32(&esp32_cfg, &mac_config); + if (mac == NULL) + { + nerr("ERROR: esp_eth_mac_new_esp32 failed\n"); + return -EIO; + } + + phy = esp_eth_phy_new_generic(&phy_cfg); + if (phy == NULL) + { + nerr("ERROR: esp_eth_phy_new_generic failed\n"); + mac->del(mac); + return -EIO; + } + + { + esp_eth_config_t eth_cfg = ETH_DEFAULT_CONFIG(mac, phy); + + err = esp_eth_driver_install(ð_cfg, &priv->handle); + if (err != ESP_OK) + { + nerr("ERROR: esp_eth_driver_install failed: %d\n", (int)err); + phy->del(phy); + mac->del(mac); + return -EIO; + } + } + + priv->installed = true; + + err = esp_eth_update_input_path(priv->handle, emac_stack_input, priv); + if (err != ESP_OK) + { + nerr("ERROR: esp_eth_update_input_path failed: %d\n", (int)err); + ret = -EIO; + goto errout; + } + + err = esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, + emac_eth_event_handler, priv); + if (err != ESP_OK) + { + nerr("ERROR: esp_event_handler_register(ETH_EVENT) failed: %d\n", + (int)err); + ret = -EIO; + goto errout; + } + + /* Apply the factory-programmed MAC address (eFuse) to the MAC. */ + + err = esp_read_mac(mac_addr, ESP_MAC_ETH); + if (err != ESP_OK) + { + nwarn("WARNING: esp_read_mac(ESP_MAC_ETH) failed: %d\n", (int)err); + mac_addr[0] = 0x02; + mac_addr[1] = 0x00; + mac_addr[2] = 0x00; + mac_addr[3] = 0x00; + mac_addr[4] = 0x00; + mac_addr[5] = 0x01; + } + + esp_eth_ioctl(priv->handle, ETH_CMD_S_MAC_ADDR, mac_addr); + memcpy(priv->dev.netdev.d_mac.ether.ether_addr_octet, mac_addr, 6); + priv->dev.ops = &g_emac_ops; + + /* Keep quotas well below the global netpkt pool size so lower-half + * registration remains valid across different board configurations. + */ + + quota = NETPKT_BUFNUM / 4; + if (quota == 0) + { + quota = 1; + } + + priv->dev.quota[NETPKT_RX] = quota; + priv->dev.quota[NETPKT_TX] = quota; + priv->dev.rxtype = NETDEV_RX_WORK; + priv->dev.priority = LPWORK; + + ret = netdev_lower_register(&priv->dev, NET_LL_ETHERNET); + if (ret != 0) + { + nerr("ERROR: netdev_lower_register failed: %d\n", ret); + goto errout_event; + } + + ninfo("esp_emac: MAC %02x:%02x:%02x:%02x:%02x:%02x\n", + mac_addr[0], mac_addr[1], mac_addr[2], + mac_addr[3], mac_addr[4], mac_addr[5]); + + return OK; + +errout_event: + esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, + emac_eth_event_handler); + +errout: + if (priv->installed) + { + esp_eth_driver_uninstall(priv->handle); + priv->installed = false; + } + + return ret; +} + +#endif /* CONFIG_ESPRESSIF_EMAC */ diff --git a/arch/risc-v/src/common/espressif/esp_emac.h b/arch/risc-v/src/common/espressif/esp_emac.h new file mode 100644 index 00000000000..9f6524a3495 --- /dev/null +++ b/arch/risc-v/src/common/espressif/esp_emac.h @@ -0,0 +1,62 @@ +/**************************************************************************** + * arch/risc-v/src/common/espressif/esp_emac.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_COMMON_ESPRESSIF_ESP_EMAC_H +#define __ARCH_RISCV_SRC_COMMON_ESPRESSIF_ESP_EMAC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_emac_init + * + * Description: + * Initialize the Ethernet driver and register it with the NuttX network + * stack. + * + * Input Parameters: + * None + * + * Returned Value: + * OK on success; a negated errno value on failure. + * + ****************************************************************************/ + +int esp_emac_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __ARCH_RISCV_SRC_COMMON_ESPRESSIF_ESP_EMAC_H */ diff --git a/arch/risc-v/src/common/espressif/esp_wifi_api.c b/arch/risc-v/src/common/espressif/esp_wifi_api.c index 3c90eb7eada..5c2f6e611cc 100644 --- a/arch/risc-v/src/common/espressif/esp_wifi_api.c +++ b/arch/risc-v/src/common/espressif/esp_wifi_api.c @@ -115,6 +115,7 @@ int esp_wifi_api_adapter_init(void) esp_wifi_lock(true); esp_evt_work_init(); + esp_wifi_evt_work_init(); wifi_cfg.nvs_enable = 0; diff --git a/arch/risc-v/src/common/espressif/esp_wifi_event_handler.c b/arch/risc-v/src/common/espressif/esp_wifi_event_handler.c index 19e3a02f98b..67273a9c220 100644 --- a/arch/risc-v/src/common/espressif/esp_wifi_event_handler.c +++ b/arch/risc-v/src/common/espressif/esp_wifi_event_handler.c @@ -27,9 +27,10 @@ #include #include -#include #include +#include +#include "esp_event.h" #include "esp_wifi.h" #include "esp_wifi_utils.h" @@ -69,23 +70,13 @@ struct wifi_notify struct sigwork_s work; /* Signal work private data */ }; -/* Wi-Fi event private data */ - -struct evt_adpt -{ - sq_entry_t entry; /* Sequence entry */ - wifi_event_t id; /* Event ID */ - uint8_t buf[0]; /* Event private data */ -}; - /**************************************************************************** * Private Data ****************************************************************************/ static struct wifi_notify g_wifi_notify[WIFI_EVENT_MAX]; -static struct work_s g_wifi_evt_work; -static sq_queue_t g_wifi_evt_queue; -static spinlock_t g_lock; +static struct work_s g_wifi_reconnect_work; +static bool g_wifi_handler_registered; /**************************************************************************** * Private Functions @@ -102,7 +93,7 @@ static spinlock_t g_lock; * asked to disconnect from the AP. * * Input Parameters: - * None. + * arg - Unused work queue argument. * * Returned Value: * None. @@ -130,146 +121,157 @@ static void esp_reconnect_work_cb(void *arg) } /**************************************************************************** - * Name: esp_evt_work_cb + * Name: esp_wifi_event_handler * * Description: - * Process Wi-Fi events. + * Handler registered against WIFI_EVENT / ESP_EVENT_ANY_ID with the + * generic esp_event dispatcher (see esp_event.c). Translates Wi-Fi + * driver events into NuttX-visible actions (link-layer hooks and the + * optional sigevent notification subsystem). * * Input Parameters: - * arg - Not used. + * arg - Handler-specific argument registered with the event + * dispatcher (unused). + * event_base - Event base identifier; always WIFI_EVENT here (unused). + * event_id - Wi-Fi event ID as defined by the ESP-IDF wifi_event_t + * enumeration. + * event_data - Pointer to the event-specific payload, whose concrete + * type depends on event_id. * * Returned Value: * None. * ****************************************************************************/ -static void esp_evt_work_cb(void *arg) +static void esp_wifi_event_handler(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) { int ret; - irqstate_t flags; - struct evt_adpt *evt_adpt; struct wifi_notify *notify; wifi_ps_type_t ps_type = DEFAULT_PS_MODE; - while (1) + UNUSED(arg); + UNUSED(event_base); + + /* Some of the following logic (eg. esp_wlan_sta_set_linkstatus) + * can take net_lock(). To maintain the consistent locking order, + * we take net_lock() here before taking esp_wifi_lock. Note that + * net_lock() is a recursive lock. + */ + + net_lock(); + esp_wifi_lock(true); + + switch (event_id) { - flags = spin_lock_irqsave(&g_lock); - evt_adpt = (struct evt_adpt *)sq_remfirst(&g_wifi_evt_queue); - spin_unlock_irqrestore(&g_lock, flags); - if (!evt_adpt) - { - break; - } - - /* Some of the following logic (eg. esp_wlan_sta_set_linkstatus) - * can take net_lock(). To maintain the consistent locking order, - * we take net_lock() here before taking esp_wifi_lock. Note that - * net_lock() is a recursive lock. - */ - - net_lock(); - esp_wifi_lock(true); - - switch (evt_adpt->id) - { #ifdef ESP_WLAN_DEVS - case WIFI_EVENT_SCAN_DONE: - esp_wifi_scan_event_parse(); - break; + case WIFI_EVENT_SCAN_DONE: + esp_wifi_scan_event_parse(); + break; #endif - case WIFI_EVENT_HOME_CHANNEL_CHANGE: - wlinfo("Wi-Fi home channel change\n"); - break; + case WIFI_EVENT_HOME_CHANNEL_CHANGE: + wlinfo("Wi-Fi home channel change\n"); + break; #ifdef ESP_WLAN_HAS_STA - case WIFI_EVENT_STA_START: - wlinfo("Wi-Fi sta start\n"); + case WIFI_EVENT_STA_START: + { + wlinfo("Wi-Fi sta start\n"); - ret = esp_wifi_set_ps(ps_type); - if (ret) - { - wlerr("Failed to set power save type\n"); - break; - } - break; + ret = esp_wifi_set_ps(ps_type); + if (ret) + { + wlerr("Failed to set power save type\n"); + break; + } + } + break; - case WIFI_EVENT_STA_STOP: - wlinfo("Wi-Fi station stopped\n"); - break; + case WIFI_EVENT_STA_STOP: + wlinfo("Wi-Fi station stopped\n"); + break; - case WIFI_EVENT_STA_CONNECTED: - wlinfo("Wi-Fi station connected\n"); - esp_wlan_sta_connect_success_hook(); - break; + case WIFI_EVENT_STA_CONNECTED: + { + wlinfo("Wi-Fi station connected\n"); + esp_wlan_sta_connect_success_hook(); + } + break; - case WIFI_EVENT_STA_DISCONNECTED: - wifi_event_sta_disconnected_t *event = - (wifi_event_sta_disconnected_t *)evt_adpt->buf; - wifi_err_reason_t reason = event->reason; + case WIFI_EVENT_STA_DISCONNECTED: + { + wifi_event_sta_disconnected_t *event = + (wifi_event_sta_disconnected_t *)event_data; + wifi_err_reason_t reason = event->reason; - wlinfo("Wi-Fi station disconnected, reason: %u\n", reason); - esp_wlan_sta_disconnect_hook(); - if (reason == WIFI_REASON_ASSOC_LEAVE) - { - work_queue(LPWORK, &g_wifi_evt_work, esp_reconnect_work_cb, - NULL, 0); - } + wlinfo("Wi-Fi station disconnected, reason: %u\n", reason); + esp_wlan_sta_disconnect_hook(); + if (reason == WIFI_REASON_ASSOC_LEAVE) + { + work_queue(LPWORK, &g_wifi_reconnect_work, + esp_reconnect_work_cb, NULL, 0); + } + } + break; - break; - - case WIFI_EVENT_STA_AUTHMODE_CHANGE: - wlinfo("Wi-Fi station auth mode change\n"); - break; + case WIFI_EVENT_STA_AUTHMODE_CHANGE: + wlinfo("Wi-Fi station auth mode change\n"); + break; #endif /* ESP_WLAN_HAS_STA */ #ifdef ESP_WLAN_HAS_SOFTAP - case WIFI_EVENT_AP_START: - wlinfo("INFO: Wi-Fi softap start\n"); - esp_wlan_softap_connect_success_hook(); - ret = esp_wifi_set_ps(ps_type); - if (ret) - { - wlerr("Failed to set power save type\n"); - break; - } - break; - - case WIFI_EVENT_AP_STOP: - wlinfo("Wi-Fi softap stop\n"); - esp_wlan_softap_disconnect_hook(); - break; - - case WIFI_EVENT_AP_STACONNECTED: - wlinfo("Wi-Fi station joined AP\n"); - break; - - case WIFI_EVENT_AP_STADISCONNECTED: - wlinfo("Wi-Fi station left AP\n"); - break; -#endif /* ESP_WLAN_HAS_SOFTAP */ - default: - break; + case WIFI_EVENT_AP_START: + { + wlinfo("INFO: Wi-Fi softap start\n"); + esp_wlan_softap_connect_success_hook(); + ret = esp_wifi_set_ps(ps_type); + if (ret) + { + wlerr("Failed to set power save type\n"); + break; + } } + break; - notify = &g_wifi_notify[evt_adpt->id]; + case WIFI_EVENT_AP_STOP: + { + wlinfo("Wi-Fi softap stop\n"); + esp_wlan_softap_disconnect_hook(); + } + break; + + case WIFI_EVENT_AP_STACONNECTED: + wlinfo("Wi-Fi station joined AP\n"); + break; + + case WIFI_EVENT_AP_STADISCONNECTED: + wlinfo("Wi-Fi station left AP\n"); + break; +#endif /* ESP_WLAN_HAS_SOFTAP */ + + default: + break; + } + + if (event_id >= 0 && event_id < WIFI_EVENT_MAX) + { + notify = &g_wifi_notify[event_id]; if (notify->assigned) { - notify->event.sigev_value.sival_ptr = evt_adpt->buf; + notify->event.sigev_value.sival_ptr = event_data; ret = nxsig_notification(notify->pid, ¬ify->event, SI_QUEUE, ¬ify->work); if (ret < 0) { wlwarn("nxsig_notification event ID=%d failed: %d\n", - evt_adpt->id, ret); + (int)event_id, ret); } } - - esp_wifi_lock(false); - net_unlock(); - - kmm_free(evt_adpt); } + + esp_wifi_lock(false); + net_unlock(); } /**************************************************************************** @@ -277,81 +279,30 @@ static void esp_evt_work_cb(void *arg) ****************************************************************************/ /**************************************************************************** - * Name: esp_event_post + * Name: esp_wifi_evt_work_init * * Description: - * Posts an event to the event loop system. The event is queued in a FIFO - * and processed asynchronously in the low-priority work queue. + * Register the Wi-Fi event handler against the generic esp_event loop. + * Kept under the original name so existing callers (esp_wifi_api.c) + * continue to compile unchanged. Idempotent: subsequent calls after the + * first successful registration are silently ignored. * * Input Parameters: - * event_base - Identifier for the event category (e.g. WIFI_EVENT) - * event_id - Event ID within the event base category - * event_data - Pointer to event data structure - * event_data_size - Size of event data structure - * ticks - Number of ticks to wait (currently unused) + * None. * * Returned Value: - * 0 on success - * -1 on failure with following error conditions: - * - Invalid event ID - * - Memory allocation failure - * - * Assumptions/Limitations: - * - Event data is copied into a new buffer, so the original can be freed - * - Events are processed in FIFO order in the low priority work queue - * - The function is thread-safe and can be called from interrupt context + * None. * ****************************************************************************/ -int esp_event_post(const char *event_base, - int32_t event_id, - void *event_data, - size_t event_data_size, - uint32_t ticks) +void esp_wifi_evt_work_init(void) { - size_t size; - int32_t id; - irqstate_t flags; - struct evt_adpt *evt_adpt; - - wlinfo("Event: base=%s id=%ld data=%p data_size=%u ticks=%lu\n", - event_base, event_id, event_data, event_data_size, ticks); - - size = event_data_size + sizeof(struct evt_adpt); - evt_adpt = kmm_malloc(size); - if (!evt_adpt) + if (g_wifi_handler_registered) { - wlerr("ERROR: Failed to alloc %d memory\n", size); - return -1; + return; } - evt_adpt->id = event_id; - memcpy(evt_adpt->buf, event_data, event_data_size); - - flags = enter_critical_section(); - sq_addlast(&evt_adpt->entry, &g_wifi_evt_queue); - leave_critical_section(flags); - - work_queue(LPWORK, &g_wifi_evt_work, esp_evt_work_cb, NULL, 0); - - return 0; -} - -/**************************************************************************** - * Name: esp_evt_work_init - * - * Description: - * Initialize the event work queue - * - * Input Parameters: - * None. - * - * Returned Value: - * None. - * - ****************************************************************************/ - -void esp_evt_work_init(void) -{ - sq_init(&g_wifi_evt_queue); + esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, + esp_wifi_event_handler, NULL); + g_wifi_handler_registered = true; } diff --git a/arch/risc-v/src/common/espressif/esp_wifi_utils.h b/arch/risc-v/src/common/espressif/esp_wifi_utils.h index 9363f492dac..28025c30705 100644 --- a/arch/risc-v/src/common/espressif/esp_wifi_utils.h +++ b/arch/risc-v/src/common/espressif/esp_wifi_utils.h @@ -99,7 +99,7 @@ int esp_freq_to_channel(uint16_t freq); * Name: esp_evt_work_init * * Description: - * Initialize the event work queue + * Initialize the generic esp_event backend queue. * * Input Parameters: * None @@ -111,6 +111,22 @@ int esp_freq_to_channel(uint16_t freq); void esp_evt_work_init(void); +/**************************************************************************** + * Name: esp_wifi_evt_work_init + * + * Description: + * Initialize the event work queue + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void esp_wifi_evt_work_init(void); + /**************************************************************************** * Name: esp_wifi_start_scan * @@ -212,39 +228,6 @@ wifi_mode_t esp_wifi_mode_translate(uint32_t wireless_mode); int esp_wifi_lock(bool lock); -/**************************************************************************** - * Name: esp_event_post - * - * Description: - * Posts an event to the event loop system. The event is queued in a FIFO - * and processed asynchronously in the low-priority work queue. - * - * Input Parameters: - * event_base - Identifier for the event category (e.g. WIFI_EVENT) - * event_id - Event ID within the event base category - * event_data - Pointer to event data structure - * event_data_size - Size of event data structure - * ticks - Number of ticks to wait (currently unused) - * - * Returned Value: - * 0 on success - * -1 on failure with following error conditions: - * - Invalid event ID - * - Memory allocation failure - * - * Assumptions/Limitations: - * - Event data is copied into a new buffer, so the original can be freed - * - Events are processed in FIFO order in the low priority work queue - * - The function is thread-safe and can be called from interrupt context - * - ****************************************************************************/ - -int esp_event_post(const char *event_base, - int32_t event_id, - void *event_data, - size_t event_data_size, - uint32_t ticks); - #ifdef __cplusplus } #endif diff --git a/arch/risc-v/src/esp32c3/hal_esp32c3.cmake b/arch/risc-v/src/esp32c3/hal_esp32c3.cmake index 4c76692e83c..4ceb670ad4f 100644 --- a/arch/risc-v/src/esp32c3/hal_esp32c3.cmake +++ b/arch/risc-v/src/esp32c3/hal_esp32c3.cmake @@ -507,6 +507,10 @@ list( ${ESP_HAL_3RDPARTY_REPO}/components/upper_hal_rmt/src/rmt_tx.c ${ESP_HAL_3RDPARTY_REPO}/components/upper_hal_uart/src/uart_wakeup.c) +if(CONFIG_ESPRESSIF_WIFI OR CONFIG_ESPRESSIF_EMAC) + list(APPEND HAL_SRCS ${ESP_HAL_3RDPARTY_REPO}/nuttx/src/esp_event.c) +endif() + # Bootloader flash encrypt source list(APPEND HAL_SRCS ${ESP_HAL_3RDPARTY_REPO}/components/bootloader_support/src/flash_encrypt.c) diff --git a/arch/risc-v/src/esp32c3/hal_esp32c3.mk b/arch/risc-v/src/esp32c3/hal_esp32c3.mk index 088761c60f0..a40e98de871 100644 --- a/arch/risc-v/src/esp32c3/hal_esp32c3.mk +++ b/arch/risc-v/src/esp32c3/hal_esp32c3.mk @@ -338,6 +338,10 @@ CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_ CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELIM)platform$(DELIM)os.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELIM)heap_caps.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELIM)components$(DELIM)newlib$(DELIM)newlib$(DELIM)libc$(DELIM)misc$(DELIM)init.c + +ifneq ($(CONFIG_ESPRESSIF_WIFI)$(CONFIG_ESPRESSIF_EMAC),) + CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELIM)esp_event.c +endif CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)upper_hal_gpio$(DELIM)src$(DELIM)gpio.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)upper_hal_gpio$(DELIM)src$(DELIM)rtc_io.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)upper_hal_rmt$(DELIM)src$(DELIM)rmt_common.c diff --git a/arch/risc-v/src/esp32c6/hal_esp32c6.cmake b/arch/risc-v/src/esp32c6/hal_esp32c6.cmake index 643e4199780..76e8a64e592 100644 --- a/arch/risc-v/src/esp32c6/hal_esp32c6.cmake +++ b/arch/risc-v/src/esp32c6/hal_esp32c6.cmake @@ -533,6 +533,10 @@ list( ${ESP_HAL_3RDPARTY_REPO}/nuttx/src/heap_caps.c ${ESP_HAL_3RDPARTY_REPO}/nuttx/src/components/newlib/newlib/libc/misc/init.c) +if(CONFIG_ESPRESSIF_WIFI OR CONFIG_ESPRESSIF_EMAC) + list(APPEND HAL_SRCS ${ESP_HAL_3RDPARTY_REPO}/nuttx/src/esp_event.c) +endif() + # Bootloader flash encrypt list(APPEND HAL_SRCS ${ESP_HAL_3RDPARTY_REPO}/components/bootloader_support/src/flash_encrypt.c) diff --git a/arch/risc-v/src/esp32c6/hal_esp32c6.mk b/arch/risc-v/src/esp32c6/hal_esp32c6.mk index b7af0247826..6da49a12d2a 100644 --- a/arch/risc-v/src/esp32c6/hal_esp32c6.mk +++ b/arch/risc-v/src/esp32c6/hal_esp32c6.mk @@ -382,6 +382,10 @@ CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELI CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELIM)heap_caps.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELIM)components$(DELIM)newlib$(DELIM)newlib$(DELIM)libc$(DELIM)misc$(DELIM)init.c +ifneq ($(CONFIG_ESPRESSIF_WIFI)$(CONFIG_ESPRESSIF_EMAC),) + CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELIM)esp_event.c +endif + # Bootloader files CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)src$(DELIM)flash_encrypt.c diff --git a/arch/risc-v/src/esp32h2/hal_esp32h2.cmake b/arch/risc-v/src/esp32h2/hal_esp32h2.cmake index dde8f481fe8..039eb4b5989 100644 --- a/arch/risc-v/src/esp32h2/hal_esp32h2.cmake +++ b/arch/risc-v/src/esp32h2/hal_esp32h2.cmake @@ -51,6 +51,7 @@ target_include_directories( ${ESP_HAL_3RDPARTY_REPO}/components/esp_adc/${CHIP_SERIES}/include ${ESP_HAL_3RDPARTY_REPO}/components/esp_blockdev/include ${ESP_HAL_3RDPARTY_REPO}/components/esp_common/include + ${ESP_HAL_3RDPARTY_REPO}/components/esp_event/include ${ESP_HAL_3RDPARTY_REPO}/components/esp_hal_ana_conv/${CHIP_SERIES}/include ${ESP_HAL_3RDPARTY_REPO}/components/esp_hal_ana_conv/include ${ESP_HAL_3RDPARTY_REPO}/components/esp_hal_clock/${CHIP_SERIES}/include @@ -492,6 +493,10 @@ list( ${ESP_HAL_3RDPARTY_REPO}/nuttx/src/heap_caps.c ${ESP_HAL_3RDPARTY_REPO}/nuttx/src/components/newlib/newlib/libc/misc/init.c) +if(CONFIG_ESPRESSIF_WIFI OR CONFIG_ESPRESSIF_EMAC) + list(APPEND HAL_SRCS ${ESP_HAL_3RDPARTY_REPO}/nuttx/src/esp_event.c) +endif() + # Bootloader flash encrypt list(APPEND HAL_SRCS ${ESP_HAL_3RDPARTY_REPO}/components/bootloader_support/src/flash_encrypt.c) diff --git a/arch/risc-v/src/esp32h2/hal_esp32h2.mk b/arch/risc-v/src/esp32h2/hal_esp32h2.mk index 60f12a61968..74f8fecb518 100644 --- a/arch/risc-v/src/esp32h2/hal_esp32h2.mk +++ b/arch/risc-v/src/esp32h2/hal_esp32h2.mk @@ -38,6 +38,7 @@ INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_adc$(DELIM)$(CHIP_SERIES)$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_blockdev$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_common$(DELIM)include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_event$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hal_ana_conv$(DELIM)$(CHIP_SERIES)$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hal_ana_conv$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hal_dma$(DELIM)$(CHIP_SERIES)$(DELIM)include @@ -358,6 +359,10 @@ CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)uppe CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)upper_hal_gpio$(DELIM)src$(DELIM)rtc_io.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELIM)components$(DELIM)newlib$(DELIM)newlib$(DELIM)libc$(DELIM)misc$(DELIM)init.c +ifneq ($(CONFIG_ESPRESSIF_WIFI)$(CONFIG_ESPRESSIF_EMAC),) + CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELIM)esp_event.c +endif + CHIP_ASRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)lowpower$(DELIM)port$(DELIM)$(CHIP_SERIES)$(DELIM)sleep_cpu_asm.S # Bootloader files diff --git a/arch/risc-v/src/esp32p4/hal_esp32p4.cmake b/arch/risc-v/src/esp32p4/hal_esp32p4.cmake index 375a34cff74..8a994cbad33 100644 --- a/arch/risc-v/src/esp32p4/hal_esp32p4.cmake +++ b/arch/risc-v/src/esp32p4/hal_esp32p4.cmake @@ -49,6 +49,7 @@ set(ESP32P4_INCLUDES ${ESP_HAL_3RDPARTY_REPO}/components/esp_app_format/include ${ESP_HAL_3RDPARTY_REPO}/components/esp_blockdev/include ${ESP_HAL_3RDPARTY_REPO}/components/esp_common/include + ${ESP_HAL_3RDPARTY_REPO}/components/esp_event/include ${ESP_HAL_3RDPARTY_REPO}/components/esp_hal_ana_conv/${CHIP_SERIES}/include ${ESP_HAL_3RDPARTY_REPO}/components/esp_hal_ana_conv/include ${ESP_HAL_3RDPARTY_REPO}/components/esp_hal_cam/${CHIP_SERIES}/include @@ -436,6 +437,31 @@ list( ${ESP_HAL_3RDPARTY_REPO}/nuttx/src/heap_caps.c ${ESP_HAL_3RDPARTY_REPO}/nuttx/src/platform/os.c) +if(CONFIG_ESPRESSIF_WIFI OR CONFIG_ESPRESSIF_EMAC) + list(APPEND HAL_SRCS ${ESP_HAL_3RDPARTY_REPO}/nuttx/src/esp_event.c) +endif() + +if(CONFIG_ESPRESSIF_EMAC) + list( + APPEND + HAL_SRCS + ${ESP_HAL_3RDPARTY_REPO}/components/esp_hal_emac/emac_hal.c + ${ESP_HAL_3RDPARTY_REPO}/components/esp_hal_emac/${CHIP_SERIES}/emac_periph.c + ${ESP_HAL_3RDPARTY_REPO}/components/esp_eth/src/esp_eth.c + ${ESP_HAL_3RDPARTY_REPO}/components/esp_eth/src/mac/esp_eth_mac_esp.c + ${ESP_HAL_3RDPARTY_REPO}/components/esp_eth/src/mac/esp_eth_mac_esp_dma.c + ${ESP_HAL_3RDPARTY_REPO}/components/esp_eth/src/mac/esp_eth_mac_esp_gpio.c + ${ESP_HAL_3RDPARTY_REPO}/components/esp_eth/src/phy/esp_eth_phy_802_3.c + ${ESP_HAL_3RDPARTY_REPO}/components/esp_eth/src/phy/esp_eth_phy_generic.c + # log_buffers.c provides ESP_LOG_BUFFER_HEXDUMP used by esp_eth_mac_esp.c + # for its dump_hal_registers diagnostic helper; util.c supplies the hex + # conversion helper consumed by log_buffers.c. + ${ESP_HAL_3RDPARTY_REPO}/components/log/src/util.c + ${ESP_HAL_3RDPARTY_REPO}/components/log/src/buffer/log_buffers.c) + target_include_directories( + arch PRIVATE ${ESP_HAL_3RDPARTY_REPO}/components/esp_eth/include) +endif() + # Bootloader common list( APPEND HAL_SRCS diff --git a/arch/risc-v/src/esp32p4/hal_esp32p4.mk b/arch/risc-v/src/esp32p4/hal_esp32p4.mk index 31bfede5c08..39a47c3553d 100644 --- a/arch/risc-v/src/esp32p4/hal_esp32p4.mk +++ b/arch/risc-v/src/esp32p4/hal_esp32p4.mk @@ -39,6 +39,7 @@ INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_app_format$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_blockdev$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_common$(DELIM)include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_event$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hal_ana_conv$(DELIM)$(CHIP_SERIES)$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hal_ana_conv$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hal_cam$(DELIM)$(CHIP_SERIES)$(DELIM)include @@ -359,6 +360,8 @@ CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$ CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)efuse_hal.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)hal_utils.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)hal$(DELIM)mmu_hal.c +CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)log$(DELIM)src$(DELIM)util.c +CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)log$(DELIM)src$(DELIM)buffer$(DELIM)log_buffers.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)log$(DELIM)src$(DELIM)log_level$(DELIM)log_level.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)log$(DELIM)src$(DELIM)log_level$(DELIM)tag_log_level$(DELIM)linked_list$(DELIM)log_linked_list.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)log$(DELIM)src$(DELIM)log_level$(DELIM)tag_log_level$(DELIM)tag_log_level.c @@ -410,6 +413,23 @@ CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELI CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELIM)heap_caps.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELIM)platform$(DELIM)os.c +ifneq ($(CONFIG_ESPRESSIF_WIFI)$(CONFIG_ESPRESSIF_EMAC),) + CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELIM)esp_event.c +endif + +ifeq ($(CONFIG_ESPRESSIF_EMAC),y) + CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hal_emac$(DELIM)emac_hal.c + CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hal_emac$(DELIM)$(CHIP_SERIES)$(DELIM)emac_periph.c + CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_eth$(DELIM)src$(DELIM)esp_eth.c + CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_eth$(DELIM)src$(DELIM)mac$(DELIM)esp_eth_mac_esp.c + CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_eth$(DELIM)src$(DELIM)mac$(DELIM)esp_eth_mac_esp_dma.c + CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_eth$(DELIM)src$(DELIM)mac$(DELIM)esp_eth_mac_esp_gpio.c + CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_eth$(DELIM)src$(DELIM)phy$(DELIM)esp_eth_phy_802_3.c + CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_eth$(DELIM)src$(DELIM)phy$(DELIM)esp_eth_phy_generic.c + + INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_eth$(DELIM)include +endif + # Bootloader files CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bootloader_support$(DELIM)src$(DELIM)bootloader_mem.c