This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 633d67f8867104c7c8d745854f4ef1c71cfb35c7 Author: Marcio Ribeiro <[email protected]> AuthorDate: Wed Sep 9 16:18:14 2026 -0300 arch/risc-v/esp32c2: add wireless adapters Bring in Wi-Fi, BLE, coexistence, and wireless glue for the ESP32-C2 radio. Assisted-by: Claude:claude-opus-5 Signed-off-by: Marcio Ribeiro <[email protected]> --- arch/risc-v/src/common/espressif/Kconfig | 2 +- arch/risc-v/src/common/espressif/Make.defs | 2 +- arch/risc-v/src/common/espressif/Wireless.cmake | 39 +- arch/risc-v/src/common/espressif/Wireless.mk | 19 +- arch/risc-v/src/esp32c2/CMakeLists.txt | 10 + arch/risc-v/src/esp32c2/Make.defs | 10 + arch/risc-v/src/esp32c2/esp_ble.c | 333 +++ arch/risc-v/src/esp32c2/esp_ble.h | 52 + arch/risc-v/src/esp32c2/esp_coex_adapter.c | 593 +++++ arch/risc-v/src/esp32c2/esp_coex_adapter.h | 82 + arch/risc-v/src/esp32c2/esp_wifi_adapter.c | 2992 +++++++++++++++++++++++ 11 files changed, 4122 insertions(+), 12 deletions(-) diff --git a/arch/risc-v/src/common/espressif/Kconfig b/arch/risc-v/src/common/espressif/Kconfig index 01e6ac4ddaa..468347ce4ef 100644 --- a/arch/risc-v/src/common/espressif/Kconfig +++ b/arch/risc-v/src/common/espressif/Kconfig @@ -2092,7 +2092,7 @@ config ESPRESSIF_WIRELESS config ESPRESSIF_WIFI bool "Wi-Fi" - depends on ARCH_CHIP_ESP32C3 || ARCH_CHIP_ESP32C6 + depends on ARCH_CHIP_ESP32C2 || ARCH_CHIP_ESP32C3 || ARCH_CHIP_ESP32C6 default n select ESPRESSIF_WIRELESS ---help--- diff --git a/arch/risc-v/src/common/espressif/Make.defs b/arch/risc-v/src/common/espressif/Make.defs index 7fa482ba8be..8e1203c55fb 100644 --- a/arch/risc-v/src/common/espressif/Make.defs +++ b/arch/risc-v/src/common/espressif/Make.defs @@ -293,7 +293,7 @@ endif ifeq ($(CONFIG_ESPRESSIF_WIRELESS),y) ifneq ($(USE_NXTMPDIR_ESP_REPO_DIRECTLY),y) $(Q) echo "Espressif HAL for 3rd Party Platforms: initializing submodules..." - $(Q) git -C chip/$(ESP_HAL_3RDPARTY_REPO) submodule --quiet update --init $(GIT_DEPTH_PARAMETER) components/esp_phy/lib components/esp_wifi/lib components/bt/controller/lib_esp32c3_family components/bt/controller/lib_esp32c6/esp32c6-bt-lib components/bt/controller/lib_esp32h2/esp32h2-bt-lib components/esp_coex/lib + $(Q) git -C chip/$(ESP_HAL_3RDPARTY_REPO) submodule --quiet update --init $(GIT_DEPTH_PARAMETER) components/esp_phy/lib components/esp_wifi/lib components/bt/controller/lib_esp32c2/esp32c2-bt-lib components/bt/controller/lib_esp32c3_family components/bt/controller/lib_esp32c6/esp32c6-bt-lib components/bt/controller/lib_esp32h2/esp32h2-bt-lib components/esp_coex/lib $(Q) git -C chip/$(ESP_HAL_3RDPARTY_REPO)/components/mbedtls/mbedtls reset --quiet --hard endif $(Q) echo "Applying patches..." diff --git a/arch/risc-v/src/common/espressif/Wireless.cmake b/arch/risc-v/src/common/espressif/Wireless.cmake index cfd6a486b65..db43aace60e 100644 --- a/arch/risc-v/src/common/espressif/Wireless.cmake +++ b/arch/risc-v/src/common/espressif/Wireless.cmake @@ -42,17 +42,23 @@ nuttx_add_extra_library( ${ESP_HAL_3RDPARTY_REPO}/components/esp_phy/lib/${CHIP_SERIES}/libphy.a ${ESP_HAL_3RDPARTY_REPO}/components/esp_coex/lib/${CHIP_SERIES}/libcoexist.a) -if(NOT CONFIG_ARCH_CHIP_ESP32H2) +if(CONFIG_ESPRESSIF_WIFI AND NOT CONFIG_ARCH_CHIP_ESP32H2) + if(NOT CONFIG_ARCH_CHIP_ESP32C2) + nuttx_add_extra_library( + ${ESP_HAL_3RDPARTY_REPO}/components/esp_wifi/lib/${CHIP_SERIES}/libmesh.a) + endif() + nuttx_add_extra_library( - ${ESP_HAL_3RDPARTY_REPO}/components/esp_wifi/lib/${CHIP_SERIES}/libmesh.a ${ESP_HAL_3RDPARTY_REPO}/components/esp_wifi/lib/${CHIP_SERIES}/libespnow.a) endif() # ############################################################################## -# ESP32-C6 / ESP32-H2 BLE host and controller sources +# ESP32-C2 / ESP32-C6 / ESP32-H2 BLE host and controller sources # ############################################################################## -if((CONFIG_ARCH_CHIP_ESP32C6 OR CONFIG_ARCH_CHIP_ESP32H2) +if((CONFIG_ARCH_CHIP_ESP32C2 + OR CONFIG_ARCH_CHIP_ESP32C6 + OR CONFIG_ARCH_CHIP_ESP32H2) AND CONFIG_ESPRESSIF_BLE) target_include_directories( arch @@ -91,6 +97,14 @@ if((CONFIG_ARCH_CHIP_ESP32C6 OR CONFIG_ARCH_CHIP_ESP32H2) target_compile_definitions(arch PRIVATE ESP_PLATFORM=1) + if(CONFIG_ARCH_CHIP_ESP32C2) + target_sources( + arch + PRIVATE + ${ESP_HAL_3RDPARTY_REPO}/components/bt/controller/${CHIP_SERIES}/dummy.c + ) + endif() + if(CONFIG_ARCH_CHIP_ESP32H2) target_sources( arch @@ -109,7 +123,11 @@ if(CONFIG_ESPRESSIF_BLE) nuttx_add_extra_library( ${ESP_HAL_3RDPARTY_REPO}/components/esp_phy/lib/${CHIP_SERIES}/libbtbb.a) - if(CONFIG_ARCH_CHIP_ESP32C3) + if(CONFIG_ARCH_CHIP_ESP32C2) + nuttx_add_extra_library( + ${ESP_HAL_3RDPARTY_REPO}/components/bt/controller/lib_esp32c2/esp32c2-bt-lib/libble_app.a + ) + elseif(CONFIG_ARCH_CHIP_ESP32C3) nuttx_add_extra_library( ${ESP_HAL_3RDPARTY_REPO}/components/bt/controller/lib_esp32c3_family/${CHIP_SERIES}/libbtdm_app.a ) @@ -233,10 +251,19 @@ if(CONFIG_ESPRESSIF_WIFI) ${ESP_HAL_3RDPARTY_REPO}/components/mbedtls/port/esp_hardware.c ${ESP_HAL_3RDPARTY_REPO}/components/mbedtls/port/esp_mem.c ${ESP_HAL_3RDPARTY_REPO}/components/mbedtls/port/esp_timing.c - ${ESP_HAL_3RDPARTY_REPO}/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_opaque.c ${ESP_HAL_3RDPARTY_REPO}/components/mbedtls/port/psa_driver/esp_md/psa_crypto_driver_esp_md5.c ) + # The HMAC peripheral is not available on the ESP32-C2 + + if(NOT CONFIG_ARCH_CHIP_ESP32C2) + list( + APPEND + MBEDTLS_PORT_SRCS + ${ESP_HAL_3RDPARTY_REPO}/components/mbedtls/port/psa_driver/esp_mac/psa_crypto_driver_esp_hmac_opaque.c + ) + endif() + target_sources(arch PRIVATE ${MBEDTLS_SRCS} ${TF_PSA_CORE_SRCS} ${MBEDTLS_PORT_SRCS}) diff --git a/arch/risc-v/src/common/espressif/Wireless.mk b/arch/risc-v/src/common/espressif/Wireless.mk index d3c1389d31a..74faf5b958b 100644 --- a/arch/risc-v/src/common/espressif/Wireless.mk +++ b/arch/risc-v/src/common/espressif/Wireless.mk @@ -30,7 +30,7 @@ INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY ifeq ($(CONFIG_ARCH_CHIP_ESP32C3),y) EXTRA_LIBPATHS += -L $(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bt$(DELIM)controller$(DELIM)lib_esp32c3_family$(DELIM)$(CHIP_SERIES) endif -ifneq ($(filter y,$(CONFIG_ARCH_CHIP_ESP32C6) $(CONFIG_ARCH_CHIP_ESP32H2)),) +ifneq ($(filter y,$(CONFIG_ARCH_CHIP_ESP32C2) $(CONFIG_ARCH_CHIP_ESP32C6) $(CONFIG_ARCH_CHIP_ESP32H2)),) ifeq ($(CONFIG_ESPRESSIF_BLE),y) INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bt$(DELIM)common$(DELIM)osi$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bt$(DELIM)common$(DELIM)tinycrypt$(DELIM)include @@ -63,6 +63,12 @@ CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELI CFLAGS += $(DEFINE_PREFIX)ESP_PLATFORM=1 +ifeq ($(CONFIG_ARCH_CHIP_ESP32C2),y) +EXTRA_LIBPATHS += -L $(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bt$(DELIM)controller$(DELIM)lib_esp32c2$(DELIM)esp32c2-bt-lib + +CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bt$(DELIM)controller$(DELIM)$(CHIP_SERIES)$(DELIM)dummy.c +endif + ifeq ($(CONFIG_ARCH_CHIP_ESP32C6),y) EXTRA_LIBPATHS += -L $(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)bt$(DELIM)controller$(DELIM)lib_esp32c6$(DELIM)esp32c6-bt-lib$(DELIM)esp32c6 endif @@ -83,11 +89,14 @@ EXTRA_LIBPATHS += -L $(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$ EXTRA_LIBS += -lphy -lcoexist +ifeq ($(CONFIG_ESPRESSIF_WIFI),y) + ifneq ($(CONFIG_ARCH_CHIP_ESP32H2),y) -EXTRA_LIBS += -lmesh -lespnow +ifneq ($(CONFIG_ARCH_CHIP_ESP32C2),y) +EXTRA_LIBS += -lmesh +endif +EXTRA_LIBS += -lespnow endif - -ifeq ($(CONFIG_ESPRESSIF_WIFI),y) ifeq ($(CONFIG_WPA_WAPI_PSK),y) EXTRA_LIBS += -lwapi @@ -178,8 +187,10 @@ CHIP_CSRCS += esp_timing.c LDFLAGS += -u mbedtls_psa_crypto_init_include_impl +ifneq ($(CONFIG_ARCH_CHIP_ESP32C2),y) VPATH += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)mbedtls$(DELIM)port$(DELIM)psa_driver$(DELIM)esp_mac CHIP_CSRCS += psa_crypto_driver_esp_hmac_opaque.c +endif VPATH += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)mbedtls$(DELIM)port$(DELIM)psa_driver$(DELIM)esp_md CHIP_CSRCS += psa_crypto_driver_esp_md5.c diff --git a/arch/risc-v/src/esp32c2/CMakeLists.txt b/arch/risc-v/src/esp32c2/CMakeLists.txt index 78f13afecea..aa50654a1df 100644 --- a/arch/risc-v/src/esp32c2/CMakeLists.txt +++ b/arch/risc-v/src/esp32c2/CMakeLists.txt @@ -24,6 +24,16 @@ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../common/espressif espressif) set(SRCS esp_chip_rev.c) +if(CONFIG_ESPRESSIF_WIFI) + list(APPEND SRCS esp_coex_adapter.c esp_wifi_adapter.c) + target_compile_definitions(arch PRIVATE ESP_PLATFORM) +endif() + +if(CONFIG_ESPRESSIF_BLE) + list(APPEND SRCS esp_ble.c) + target_compile_definitions(arch PRIVATE ESP_PLATFORM) +endif() + target_compile_definitions(arch PRIVATE _RETARGETABLE_LOCKING) if(SRCS) diff --git a/arch/risc-v/src/esp32c2/Make.defs b/arch/risc-v/src/esp32c2/Make.defs index 15d8fa2b6c2..aba8f2f587c 100644 --- a/arch/risc-v/src/esp32c2/Make.defs +++ b/arch/risc-v/src/esp32c2/Make.defs @@ -25,4 +25,14 @@ include common/espressif/Make.defs CHIP_CSRCS += esp_chip_rev.c +ifeq ($(CONFIG_ESPRESSIF_WIFI),y) +CHIP_CSRCS += esp_coex_adapter.c esp_wifi_adapter.c +EXTRA_LIBS += -lcore -lnet80211 -lpp +endif + +ifeq ($(CONFIG_ESPRESSIF_BLE),y) +CHIP_CSRCS += esp_ble.c +EXTRA_LIBS += -lbtbb -lble_app +endif + CFLAGS += ${DEFINE_PREFIX}_RETARGETABLE_LOCKING diff --git a/arch/risc-v/src/esp32c2/esp_ble.c b/arch/risc-v/src/esp32c2/esp_ble.c new file mode 100644 index 00000000000..e03dad6248a --- /dev/null +++ b/arch/risc-v/src/esp32c2/esp_ble.c @@ -0,0 +1,333 @@ +/**************************************************************************** + * arch/risc-v/src/esp32c2/esp_ble.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 <sys/types.h> + +#include <sys/socket.h> + +#include <stdbool.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> +#include <nuttx/debug.h> + +#include <nuttx/nuttx.h> +#include <nuttx/kmalloc.h> +#include <nuttx/wqueue.h> +#include <nuttx/net/bluetooth.h> +#include <nuttx/wireless/bluetooth/bt_driver.h> +#include <nuttx/wireless/bluetooth/bt_uart.h> + +#if defined(CONFIG_UART_BTH4) +# include <nuttx/serial/uart_bth4.h> +#endif + +#include "esp_bt.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* BLE packet buffer max size */ + +#define BLE_BUF_SIZE 1024 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct esp_ble_priv_s +{ + struct bt_driver_s drv; /* NuttX BT/BLE driver data */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int esp_ble_open(struct bt_driver_s *drv); +static int esp_ble_send(struct bt_driver_s *drv, + enum bt_buf_type_e type, + void *data, size_t len); +static void esp_ble_close(struct bt_driver_s *drv); +static void esp_ble_send_ready(void); +static int esp_ble_recv_cb(uint8_t *data, uint16_t len); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct esp_ble_priv_s g_ble_priv = +{ + .drv = + { + .head_reserve = H4_HEADER_SIZE, + .open = esp_ble_open, + .send = esp_ble_send, + .close = esp_ble_close + } +}; + +static esp_vhci_host_callback_t vhci_host_cb = +{ + .notify_host_send_available = esp_ble_send_ready, + .notify_host_recv = esp_ble_recv_cb +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_ble_send_ready + * + * Description: + * If the controller could send HCI command will callback this function. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void esp_ble_send_ready(void) +{ +} + +/**************************************************************************** + * Name: esp_ble_recv_cb + * + * Description: + * BLE receive callback function when BLE hardware receive packet + * + * Input Parameters: + * data - BLE packet data pointer + * len - BLE packet length + * + * Returned Value: + * 0 on success or a negated value on failure. + * + ****************************************************************************/ + +static int esp_ble_recv_cb(uint8_t *data, uint16_t len) +{ + int ret; + bool valid; + enum bt_buf_type_e type; + struct esp_ble_priv_s *priv = &g_ble_priv; + + switch (data[0]) + { + case H4_EVT: + type = BT_EVT; + valid = true; + break; + case H4_ACL: + type = BT_ACL_IN; + valid = true; + break; + case H4_ISO: + type = BT_ISO_IN; + valid = true; + break; + default: + valid = false; + break; + } + + if (!valid) + { + ret = ERROR; + } + else + { + /* send packet to host */ + + ret = bt_netdev_receive(&priv->drv, type, + &data[H4_HEADER_SIZE], + len - H4_HEADER_SIZE); + if (ret < 0) + { + wlerr("Failed to receive ret=%d\n", ret); + } + } + + return ret; +} + +/**************************************************************************** + * Name: esp_ble_send + * + * Description: + * ESP32-C2 BLE send callback function for BT driver. + * + * Input Parameters: + * drv - BT driver pointer + * type - BT packet type + * data - BT packet data buffer pointer + * len - BT packet length + * + * Returned Value: + * Sent bytes on success or a negated value on failure. + * + ****************************************************************************/ + +static int esp_ble_send(struct bt_driver_s *drv, + enum bt_buf_type_e type, + void *data, size_t len) +{ + uint8_t *hdr = (uint8_t *)data - drv->head_reserve; + + if ((len + H4_HEADER_SIZE) > BLE_BUF_SIZE) + { + return -EINVAL; + } + + if (type == BT_CMD) + { + *hdr = H4_CMD; + } + else if (type == BT_ACL_OUT) + { + *hdr = H4_ACL; + } + else if (type == BT_ISO_OUT) + { + *hdr = H4_ISO; + } + else + { + return -EINVAL; + } + + if (esp_vhci_host_check_send_available()) + { + esp_vhci_host_send_packet(hdr, len + drv->head_reserve); + } + + return len; +} + +/**************************************************************************** + * Name: esp_ble_close + * + * Description: + * ESP32-C2 BLE close callback function for BT driver. + * + * Input Parameters: + * drv - BT driver pointer + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void esp_ble_close(struct bt_driver_s *drv) +{ +} + +/**************************************************************************** + * Name: esp_ble_open + * + * Description: + * ESP32-C2 BLE open callback function for BT driver. + * + * Input Parameters: + * drv - BT driver pointer + * + * Returned Value: + * OK on success or a negated value on failure. + * + ****************************************************************************/ + +static int esp_ble_open(struct bt_driver_s *drv) +{ + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_ble_initialize + * + * Description: + * Init BT controller + * + * Input Parameters: + * None + * + * Returned Value: + * success or fail + * + ****************************************************************************/ + +int esp_ble_initialize(void) +{ + int ret; + esp_bt_controller_config_t cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + + cfg.controller_task_stack_size = CONFIG_ESPRESSIF_BLE_TASK_STACK_SIZE; + cfg.controller_task_prio = CONFIG_ESPRESSIF_BLE_TASK_PRIORITY; + cfg.controller_run_cpu = CONFIG_BT_CTRL_PINNED_TO_CORE; + + if (esp_bt_controller_init(&cfg) != ESP_OK) + { + wlerr("Failed to initialize BLE\n"); + return ERROR; + } + + if (esp_bt_controller_enable(ESP_BT_MODE_BLE) != ESP_OK) + { + wlerr("Failed to Enable BLE\n"); + return ERROR; + } + + ret = esp_vhci_host_register_callback(&vhci_host_cb); + if (ret != ESP_OK) + { + esp_bt_controller_disable(); + wlerr("Failed to register BLE callback ret=%d\n", ret); + return ERROR; + } + +#if defined(CONFIG_UART_BTH4) + ret = uart_bth4_register(CONFIG_ESPRESSIF_BLE_TTY_NAME, &g_ble_priv.drv); +#else + ret = bt_netdev_register(&g_ble_priv.drv); +#endif + if (ret < 0) + { + wlerr("bt_netdev_register error: %d\n", ret); + return ret; + } + + return OK; +} diff --git a/arch/risc-v/src/esp32c2/esp_ble.h b/arch/risc-v/src/esp32c2/esp_ble.h new file mode 100644 index 00000000000..dcf256a77d4 --- /dev/null +++ b/arch/risc-v/src/esp32c2/esp_ble.h @@ -0,0 +1,52 @@ +/**************************************************************************** + * arch/risc-v/src/esp32c2/esp_ble.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_ESP32C2_ESP_BLE_H +#define __ARCH_RISCV_SRC_ESP32C2_ESP_BLE_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_ble_initialize + * + * Description: + * Init BT controller + * + * Input Parameters: + * None + * + * Returned Value: + * success or fail + * + ****************************************************************************/ + +int esp_ble_initialize(void); + +#endif /* __ARCH_RISCV_SRC_ESP32C2_ESP_BLE_H */ diff --git a/arch/risc-v/src/esp32c2/esp_coex_adapter.c b/arch/risc-v/src/esp32c2/esp_coex_adapter.c new file mode 100644 index 00000000000..0b0971d09bd --- /dev/null +++ b/arch/risc-v/src/esp32c2/esp_coex_adapter.c @@ -0,0 +1,593 @@ +/**************************************************************************** + * arch/risc-v/src/esp32c2/esp_coex_adapter.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 <nuttx/debug.h> +#include <stddef.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> +#include <pthread.h> + +#include <nuttx/spinlock.h> +#include <irq/irq.h> +#include <nuttx/kmalloc.h> + +#include "esp_hr_timer.h" + +#include "esp_attr.h" +#include "esp_timer.h" +#include "soc/rtc.h" +#include "esp_private/esp_clk.h" +#include "private/esp_coexist_adapter.h" +#include "rom/ets_sys.h" +#include "soc/soc_caps.h" +#include "soc/system_reg.h" +#include "private/esp_modem_wrapper.h" + +#include "espressif/esp_wifi_utils.h" + +#include "esp_coex_adapter.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define OSI_FUNCS_TIME_BLOCKING 0xffffffff + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static IRAM_ATTR int64_t esp_coex_esp_timer_get_time_wrapper(void); +static int32_t esp_coex_semphr_take_from_isr_wrapper(void *semphr, + void *hptw); +static int32_t esp_coex_semphr_give_from_isr_wrapper(void *semphr, + void *hptw); +static int esp_coex_is_in_isr_wrapper(void); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +coex_adapter_funcs_t g_coex_adapter_funcs = +{ + ._version = COEX_ADAPTER_VERSION, + ._task_yield_from_isr = esp_coex_common_task_yield_from_isr_wrapper, + ._semphr_create = esp_coex_common_semphr_create_wrapper, + ._semphr_delete = esp_coex_common_semphr_delete_wrapper, + ._semphr_take_from_isr = esp_coex_semphr_take_from_isr_wrapper, + ._semphr_give_from_isr = esp_coex_semphr_give_from_isr_wrapper, + ._semphr_take = esp_coex_common_semphr_take_wrapper, + ._semphr_give = esp_coex_common_semphr_give_wrapper, + ._is_in_isr = esp_coex_is_in_isr_wrapper, + ._malloc_internal = esp_coex_common_malloc_internal_wrapper, + ._free = free, + ._esp_timer_get_time = esp_coex_esp_timer_get_time_wrapper, + ._timer_disarm = esp_coex_common_timer_disarm_wrapper, + ._timer_done = esp_coex_common_timer_done_wrapper, + ._timer_setfn = esp_coex_common_timer_setfn_wrapper, + ._timer_arm_us = esp_coex_common_timer_arm_us_wrapper, + ._magic = COEX_ADAPTER_MAGIC, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_coex_esp_timer_get_time_wrapper + * + * Description: + * This function retrieves the current time of the High Resolution Timer + * in microseconds. It is a wrapper around the esp_hr_timer_time_us + * function, providing a consistent interface for the coexistence module. + * + * Input Parameters: + * None. + * + * Returned Value: + * The current time of the High Resolution Timer in microseconds, as a + * 64-bit integer. + * + ****************************************************************************/ + +static IRAM_ATTR int64_t esp_coex_esp_timer_get_time_wrapper(void) +{ + return esp_hr_timer_time_us(); +} + +/**************************************************************************** + * Name: esp_coex_semphr_take_from_isr_wrapper + * + * Description: + * Take a semaphore from an ISR + * + * Input Parameters: + * semphr - Semaphore data pointer. + * hptw - Unused. + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +static int32_t IRAM_ATTR esp_coex_semphr_take_from_isr_wrapper(void *semphr, + void *hptw) +{ + *(int *)hptw = 0; + + return nuttx_err_to_common_err(nxsem_trywait(semphr)); +} + +/**************************************************************************** + * Name: esp_coex_semphr_give_from_isr_wrapper + * + * Description: + * Post semaphore + * + * Input Parameters: + * semphr - Semaphore data pointer + * hptw - Unused. + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +static int32_t IRAM_ATTR esp_coex_semphr_give_from_isr_wrapper(void *semphr, + void *hptw) +{ + *(int *)hptw = 0; + + return esp_coex_common_semphr_give_wrapper(semphr); +} + +/**************************************************************************** + * Name: esp_coex_is_in_isr_wrapper + * + * Description: + * This function checks if the current context is an interrupt service + * routine (ISR). It is a wrapper around the NuttX up_interrupt_context + * function. + * + * Input Parameters: + * None + * + * Returned Value: + * Returns 1 if the current context is an ISR, 0 otherwise. + * + ****************************************************************************/ + +static int IRAM_ATTR esp_coex_is_in_isr_wrapper(void) +{ + return (int)up_interrupt_context(); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_coex_common_env_is_chip_wrapper + * + * Description: + * This function checks if the environment is a chip or FPGA. + * + * Input Parameters: + * None + * + * Returned Value: + * Returns true if the environment is a chip, false if it's an FPGA. + * + ****************************************************************************/ + +bool IRAM_ATTR esp_coex_common_env_is_chip_wrapper(void) +{ +#ifdef CONFIG_IDF_ENV_FPGA + return false; +#else + return true; +#endif +} + +/**************************************************************************** + * Name: esp_coex_common_spin_lock_create_wrapper + * + * Description: + * Create spin lock in SMP mode + * + * Input Parameters: + * None + * + * Returned Value: + * Spin lock data pointer + * + ****************************************************************************/ + +void *esp_coex_common_spin_lock_create_wrapper(void) +{ + spinlock_t *lock; + int tmp; + + tmp = sizeof(*lock); + lock = kmm_malloc(tmp); + if (!lock) + { + wlerr("Failed to alloc %d memory\n", tmp); + DEBUGPANIC(); + } + + spin_lock_init(lock); + + return lock; +} + +/**************************************************************************** + * Name: esp_coex_common_int_disable_wrapper + * + * Description: + * Enter critical section by disabling interrupts and taking the spin lock + * if in SMP mode. + * + * Input Parameters: + * wifi_int_mux - Spin lock data pointer + * + * Returned Value: + * CPU PS value. + * + ****************************************************************************/ + +uint32_t IRAM_ATTR esp_coex_common_int_disable_wrapper(void *wifi_int_mux) +{ + irqstate_t flags; + + flags = spin_lock_irqsave((spinlock_t *)wifi_int_mux); + + return (uint32_t)flags; +} + +/**************************************************************************** + * Name: esp_coex_common_int_restore_wrapper + * + * Description: + * Exit from critical section by enabling interrupts and releasing the spin + * lock if in SMP mode. + * + * Input Parameters: + * wifi_int_mux - Spin lock data pointer + * tmp - CPU PS value. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void IRAM_ATTR esp_coex_common_int_restore_wrapper(void *wifi_int_mux, + uint32_t tmp) +{ + irqstate_t flags = (irqstate_t)tmp; + + spin_unlock_irqrestore((spinlock_t *)wifi_int_mux, flags); +} + +/**************************************************************************** + * Name: esp_task_yield_from_isr + * + * Description: + * Perform a solicited context switch on FreeRTOS. Do nothing in NuttX. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void IRAM_ATTR esp_coex_common_task_yield_from_isr_wrapper(void) +{ +} + +/**************************************************************************** + * Name: esp_coex_common_semphr_create_wrapper + * + * Description: + * Create and initialize semaphore + * + * Input Parameters: + * max - No meaning for NuttX + * init - semaphore initialization value + * + * Returned Value: + * Semaphore data pointer + * + ****************************************************************************/ + +void *esp_coex_common_semphr_create_wrapper(uint32_t max, uint32_t init) +{ + int ret; + sem_t *sem; + int tmp; + + tmp = sizeof(sem_t); + sem = kmm_malloc(tmp); + if (!sem) + { + wlerr("Failed to alloc %d memory\n", tmp); + return NULL; + } + + ret = nxsem_init(sem, 0, init); + if (ret) + { + wlerr("Failed to initialize sem error=%d\n", ret); + kmm_free(sem); + return NULL; + } + + return sem; +} + +/**************************************************************************** + * Name: esp_coex_common_semphr_delete_wrapper + * + * Description: + * Delete semaphore + * + * Input Parameters: + * semphr - Semaphore data pointer + * + * Returned Value: + * None + * + ****************************************************************************/ + +void esp_coex_common_semphr_delete_wrapper(void *semphr) +{ + sem_t *sem = (sem_t *)semphr; + + nxsem_destroy(sem); + kmm_free(sem); +} + +/**************************************************************************** + * Name: esp_coex_common_semphr_take_wrapper + * + * Description: + * This function attempts to take (wait for) a semaphore within a certain + * period of time. It is a wrapper around the NuttX nxsem_wait and + * nxsem_tickwait functions, providing error handling and translation + * between NuttX and ESP-IDF error codes. + * + * Input Parameters: + * semphr - Pointer to the semaphore data structure. + * block_time_tick - The maximum number of system ticks to wait. + * + * Returned Value: + * Returns 0 if the semaphore was successfully taken, or a negative error + * code if the operation failed or the timeout expired. + * + ****************************************************************************/ + +int32_t esp_coex_common_semphr_take_wrapper(void *semphr, + uint32_t block_time_tick) +{ + int ret; + sem_t *sem = (sem_t *)semphr; + + if (block_time_tick == OSI_FUNCS_TIME_BLOCKING) + { + ret = nxsem_wait(sem); + } + else + { + if (block_time_tick > 0) + { + ret = nxsem_tickwait(sem, block_time_tick); + } + else + { + ret = nxsem_trywait(sem); + } + } + + if (ret) + { + wlerr("ERROR: Failed to wait sem in %lu ticks. Error=%d\n", + block_time_tick, ret); + } + + return nuttx_err_to_common_err(ret); +} + +/**************************************************************************** + * Name: esp_coex_common_semphr_give_wrapper + * + * Description: + * This function posts (releases) a semaphore. It is a wrapper around the + * NuttX nxsem_post function, providing error handling and translation + * between NuttX and ESP-IDF error codes. + * + * Input Parameters: + * semphr - Pointer to the semaphore data structure. + * + * Returned Value: + * Returns 0 if the semaphore was successfully posted, or a negative error + * code if the operation failed. + * + ****************************************************************************/ + +int32_t esp_coex_common_semphr_give_wrapper(void *semphr) +{ + int ret; + sem_t *sem = (sem_t *)semphr; + + ret = nxsem_post(sem); + if (ret) + { + wlerr("Failed to post sem error=%d\n", ret); + } + + return nuttx_err_to_common_err(ret); +} + +/**************************************************************************** + * Name: esp_coex_common_timer_disarm_wrapper + * + * Description: + * Disable timer + * + * Input Parameters: + * timer - timer data pointer + * + * Returned Value: + * None + * + ****************************************************************************/ + +void IRAM_ATTR esp_coex_common_timer_disarm_wrapper(void *timer) +{ + ets_timer_disarm(timer); +} + +/**************************************************************************** + * Name: esp_coex_common_timer_done_wrapper + * + * Description: + * Disable and free timer + * + * Input Parameters: + * ptimer - timer data pointer + * + * Returned Value: + * None + * + ****************************************************************************/ + +void esp_coex_common_timer_done_wrapper(void *ptimer) +{ + ets_timer_done(ptimer); +} + +/**************************************************************************** + * Name: esp_coex_common_timer_setfn_wrapper + * + * Description: + * Set timer callback function and private data + * + * Input Parameters: + * ptimer - Timer data pointer + * pfunction - Callback function + * parg - Callback function private data + * + * Returned Value: + * None + * + ****************************************************************************/ + +void esp_coex_common_timer_setfn_wrapper(void *ptimer, + void *pfunction, + void *parg) +{ + ets_timer_setfn(ptimer, pfunction, parg); +} + +/**************************************************************************** + * Name: esp_coex_common_timer_arm_us_wrapper + * + * Description: + * Set timer timeout period and repeat flag + * + * Input Parameters: + * ptimer - timer data pointer + * us - micro seconds + * repeat - true: run cycle, false: run once + * + * Returned Value: + * None + * + ****************************************************************************/ + +void IRAM_ATTR esp_coex_common_timer_arm_us_wrapper(void *ptimer, + uint32_t us, + bool repeat) +{ + ets_timer_arm_us(ptimer, us, repeat); +} + +/**************************************************************************** + * Name: esp_coex_common_malloc_internal_wrapper + * + * Description: + * Drivers allocate a block of memory + * + * Input Parameters: + * size - memory size + * + * Returned Value: + * Memory pointer + * + ****************************************************************************/ + +IRAM_ATTR void *esp_coex_common_malloc_internal_wrapper(size_t size) +{ + return kmm_malloc(size); +} + +/**************************************************************************** + * Name: esp_coex_common_clk_slowclk_cal_get_wrapper + * + * Description: + * Get the calibration value of RTC slow clock + * + * Input Parameters: + * None + * + * Returned Value: + * The calibration value obtained using rtc_clk_cal + * + ****************************************************************************/ + +uint32_t esp_coex_common_clk_slowclk_cal_get_wrapper(void) +{ + /* The bit width of WiFi light sleep clock calibration is 12 while the one + * of system is 19. It should shift 19 - 12 = 7. + */ + + if (GET_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_XTAL)) + { + uint64_t time_per_us = 1000000ULL; + + return (((time_per_us << RTC_CLK_CAL_FRACT) / (MHZ)) >> + (RTC_CLK_CAL_FRACT - SOC_WIFI_LIGHT_SLEEP_CLK_WIDTH)); + } + else + { + return (esp_clk_slowclk_cal_get() >> + (RTC_CLK_CAL_FRACT - SOC_WIFI_LIGHT_SLEEP_CLK_WIDTH)); + } +} diff --git a/arch/risc-v/src/esp32c2/esp_coex_adapter.h b/arch/risc-v/src/esp32c2/esp_coex_adapter.h new file mode 100644 index 00000000000..2fc38b4c339 --- /dev/null +++ b/arch/risc-v/src/esp32c2/esp_coex_adapter.h @@ -0,0 +1,82 @@ +/**************************************************************************** + * arch/risc-v/src/esp32c2/esp_coex_adapter.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_ESP32C2_ESP_COEX_ADAPTER_H +#define __ARCH_RISCV_SRC_ESP32C2_ESP_COEX_ADAPTER_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> +#include <inttypes.h> + +#include "esp_attr.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +bool IRAM_ATTR esp_coex_common_env_is_chip_wrapper(void); +void *esp_coex_common_spin_lock_create_wrapper(void); +uint32_t IRAM_ATTR esp_coex_common_int_disable_wrapper(void *wifi_int_mux); +void IRAM_ATTR esp_coex_common_int_restore_wrapper(void *wifi_int_mux, + uint32_t tmp); +void IRAM_ATTR esp_coex_common_task_yield_from_isr_wrapper(void); +void *esp_coex_common_semphr_create_wrapper(uint32_t max, uint32_t init); +void esp_coex_common_semphr_delete_wrapper(void *semphr); +int32_t esp_coex_common_semphr_take_wrapper(void *semphr, + uint32_t block_time_tick); +int32_t esp_coex_common_semphr_give_wrapper(void *semphr); +void IRAM_ATTR esp_coex_common_timer_disarm_wrapper(void *timer); +void esp_coex_common_timer_done_wrapper(void *ptimer); +void esp_coex_common_timer_setfn_wrapper(void *ptimer, + void *pfunction, + void *parg); +void IRAM_ATTR esp_coex_common_timer_arm_us_wrapper(void *ptimer, + uint32_t us, + bool repeat); +IRAM_ATTR void *esp_coex_common_malloc_internal_wrapper(size_t size); +uint32_t esp_coex_common_clk_slowclk_cal_get_wrapper(void); + +#ifdef __cplusplus +} +#endif +#undef EXTERN + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_RISCV_SRC_ESP32C2_ESP_COEX_ADAPTER_H */ diff --git a/arch/risc-v/src/esp32c2/esp_wifi_adapter.c b/arch/risc-v/src/esp32c2/esp_wifi_adapter.c new file mode 100644 index 00000000000..30ccd017431 --- /dev/null +++ b/arch/risc-v/src/esp32c2/esp_wifi_adapter.c @@ -0,0 +1,2992 @@ +/**************************************************************************** + * arch/risc-v/src/esp32c2/esp_wifi_adapter.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 <inttypes.h> +#include <nuttx/debug.h> +#include <pthread.h> +#include <clock/clock.h> +#include <sys/time.h> +#include <irq/irq.h> +#include <nuttx/kmalloc.h> +#include <nuttx/mqueue.h> +#include <nuttx/irq.h> +#include <nuttx/kthread.h> +#include <nuttx/tls.h> + +#include "esp_irq.h" +#include "esp_hr_timer.h" + +#include "esp_log.h" +#include "esp_intr_alloc.h" +#include "esp_mac.h" +#include "esp_random.h" +#include "esp_private/wifi_os_adapter.h" +#include "esp_phy_init.h" +#include "esp_private/periph_ctrl.h" +#include "os.h" +#include "platform/os.h" +#include "private/esp_coexist_internal.h" +#include "rom/ets_sys.h" +#include "riscv/interrupt.h" + +#include "espressif/esp_wifi_utils.h" +#include "esp_coex_adapter.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ets_timer _ETSTIMER_ + +#define ESP_MAX_PRIORITIES (25) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +typedef struct shared_vector_desc_t shared_vector_desc_t; +typedef struct vector_desc_t vector_desc_t; + +typedef struct intr_handle_data_t +{ + vector_desc_t *vector_desc; + shared_vector_desc_t *shared_vector_desc; +} intr_handle_data_t; + +struct vector_desc_t +{ + int flags: 16; + unsigned int cpu: 1; + unsigned int intno: 5; + int source: 16; + shared_vector_desc_t *shared_vec_info; + vector_desc_t *next; +}; + +/* From esp_hw_support/intr_alloc.c: returns a pointer to a HAL-owned + * vector descriptor for some intno and cpu. + */ + +extern vector_desc_t *get_desc_for_int(int intno, int cpu); + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Private functions order is defined as: + * - A first block containing the functions in the same order as of the + * ESP-IDF' corresponding `esp_adapter.c` to ease comparison; + * - A second block of auxiliary functions block ordered by ascending; + */ + +/* First block of functions */ + +static void *wifi_zalloc_wrapper(size_t size); +static void *wifi_create_queue(int queue_len, int item_size); +static void wifi_delete_queue(wifi_static_queue_t *queue); +static void *wifi_create_queue_wrapper(int queue_len, int item_size); +static void wifi_delete_queue_wrapper(void *queue); +static void set_intr_wrapper(int32_t cpu_no, uint32_t intr_source, + uint32_t intr_num, int32_t intr_prio); +static void clear_intr_wrapper(uint32_t intr_source, uint32_t intr_num); +static void set_isr_wrapper(int32_t n, void *f, void *arg); +static void enable_intr_wrapper(uint32_t intr_mask); +static void disable_intr_wrapper(uint32_t intr_mask); +static bool is_from_isr_wrapper(void); +static void wifi_thread_semphr_free(void *data); +static void *wifi_thread_semphr_get_wrapper(void); +static void *recursive_mutex_create_wrapper(void); +static void *mutex_create_wrapper(void); +static void mutex_delete_wrapper(void *mutex); +static int32_t mutex_lock_wrapper(void *mutex); +static int32_t mutex_unlock_wrapper(void *mutex); +static void *queue_create_wrapper(uint32_t queue_len, uint32_t item_size); +static int32_t queue_send_wrapper(void *queue, + void *item, + uint32_t block_time_tick); +static int32_t queue_send_from_isr_wrapper(void *queue, + void *item, + void *hptw); +static int32_t queue_send_to_back_wrapper(void *queue, + void *item, + uint32_t block_time_tick); +static int32_t queue_send_to_front_wrapper(void *queue, + void *item, + uint32_t block_time_tick); +static int32_t queue_recv_wrapper(void *queue, + void *item, + uint32_t block_time_tick); +static uint32_t event_group_wait_bits_wrapper(void *event, + uint32_t bits_to_wait_for, + int clear_on_exit, + int wait_for_all_bits, + uint32_t block_time_tick); +static int32_t task_create_pinned_to_core_wrapper(void *task_func, + const char *name, + uint32_t stack_depth, + void *param, + uint32_t prio, + void *task_handle, + uint32_t core_id); +static int32_t task_create_wrapper(void *task_func, + const char *name, + uint32_t stack_depth, + void *param, + uint32_t prio, + void *task_handle); +static int32_t task_ms_to_tick_wrapper(uint32_t ms); +static int32_t task_get_max_priority_wrapper(void); +int32_t esp_event_post_wrapper(const char *event_base, + int32_t event_id, + void *event_data, + size_t event_data_size, + uint32_t ticks); +static void wifi_apb80m_request_wrapper(void); +static void wifi_apb80m_release_wrapper(void); +static void esp_phy_enable_wrapper(void); +static void esp_phy_disable_wrapper(void); +static void timer_arm_wrapper(void *timer, uint32_t tmout, bool repeat); +static void wifi_reset_mac_wrapper(void); +static void wifi_rtc_enable_iso_wrapper(void); +static void IRAM_ATTR wifi_rtc_disable_iso_wrapper(void); +static void wifi_clock_enable_wrapper(void); +static void wifi_clock_disable_wrapper(void); +static int get_time_wrapper(void *t); +static void *realloc_internal_wrapper(void *ptr, size_t size); +static void *calloc_internal_wrapper(size_t n, size_t size); +static void *zalloc_internal_wrapper(size_t size); +static int nvs_open_wrapper(const char *name, unsigned int open_mode, + uint32_t *out_handle); +static void esp_log_writev_wrapper(unsigned int level, + const char *tag, + const char *format, + va_list args); +static void esp_log_write_wrapper(unsigned int level, + const char *tag, + const char *format, ...); +static int esp_read_mac_wrapper(uint8_t *mac, unsigned int type); +static int coex_init_wrapper(void); +static void coex_deinit_wrapper(void); +static int coex_enable_wrapper(void); +static void coex_disable_wrapper(void); +static uint32_t coex_status_get_wrapper(void); +static int coex_wifi_request_wrapper(uint32_t event, + uint32_t latency, + uint32_t duration); +static int coex_wifi_release_wrapper(uint32_t event); +static int coex_wifi_channel_set_wrapper(uint8_t primary, + uint8_t secondary); +static int coex_event_duration_get_wrapper(uint32_t event, + uint32_t *duration); +static int coex_pti_get_wrapper(uint32_t event, uint8_t *pti); +static void coex_schm_status_bit_clear_wrapper(uint32_t type, + uint32_t status); +static void coex_schm_status_bit_set_wrapper(uint32_t type, + uint32_t status); +static int coex_schm_interval_set_wrapper(uint32_t interval); +static uint32_t coex_schm_interval_get_wrapper(void); +static uint8_t coex_schm_curr_period_get_wrapper(void); +static void *coex_schm_curr_phase_get_wrapper(void); +static int coex_register_start_cb_wrapper(int (* cb)(void)); +static int coex_schm_process_restart_wrapper(void); +static int coex_schm_register_cb_wrapper(int type, int(*cb)(int)); +static int coex_schm_flexible_period_set_wrapper(uint8_t period); +static uint8_t coex_schm_flexible_period_get_wrapper(void); +static void esp_empty_wrapper(void); + +/* Second block of functions + * These functions are auxiliary functions that are used by the first block + * of functions or software adapters for the Wi-Fi driver + */ + +static uint32_t esp_get_free_heap_size(void); +static void *event_group_create_wrapper(void); +static void event_group_delete_wrapper(void *event); +static uint32_t event_group_set_bits_wrapper(void *event, uint32_t bits); +static uint32_t event_group_clear_bits_wrapper(void *event, uint32_t bits); +static int esp_nvs_commit(uint32_t handle); +static int esp_nvs_erase_key(uint32_t handle, const char *key); +static int esp_nvs_get_blob(uint32_t handle, + const char *key, + void *out_value, + size_t *length); +static int esp_nvs_set_blob(uint32_t handle, + const char *key, + const void *value, + size_t length); +static int esp_nvs_get_i8(uint32_t handle, + const char *key, + int8_t *out_value); +static int esp_nvs_set_i8(uint32_t handle, const char *key, int8_t value); +static int esp_nvs_get_u8(uint32_t handle, + const char *key, + uint8_t *out_value); +static int esp_nvs_set_u8(uint32_t handle, const char *key, uint8_t value); +static int esp_nvs_get_u16(uint32_t handle, + const char *key, + uint16_t *out_value); +static int esp_nvs_set_u16(uint32_t handle, const char *key, uint16_t value); +static void esp_nvs_close(uint32_t handle); +static void esp_update_time(struct timespec *timespec, uint32_t ticks); +static uint32_t queue_msg_waiting_wrapper(void *queue); +static void task_delay_wrapper(uint32_t tick); +static void task_delete_wrapper(void *task_handle); +static void *task_get_current_task_wrapper(void); +static void vqueue_delete_adapter(void *queue); +static void vsemaphore_delete_adapter(void *semphr); +static void *xqueue_create_adapter(uint32_t queue_len, uint32_t item_size); +static int32_t xqueue_send_adapter(void *queue, + void *item, + uint32_t ticks, + int prio); +void *xsemaphore_create_counting_adapter(uint32_t max, uint32_t init); + +#ifdef CONFIG_PM +extern void wifi_apb80m_request(void); +extern void wifi_apb80m_release(void); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Wi-Fi OS adapter data */ + +wifi_osi_funcs_t g_wifi_osi_funcs = +{ + ._version = ESP_WIFI_OS_ADAPTER_VERSION, + ._env_is_chip = esp_coex_common_env_is_chip_wrapper, + ._set_intr = set_intr_wrapper, + ._clear_intr = clear_intr_wrapper, + ._set_isr = set_isr_wrapper, + ._ints_on = enable_intr_wrapper, + ._ints_off = disable_intr_wrapper, + ._is_from_isr = is_from_isr_wrapper, + ._spin_lock_create = esp_coex_common_spin_lock_create_wrapper, + ._spin_lock_delete = free, + ._wifi_int_disable = esp_coex_common_int_disable_wrapper, + ._wifi_int_restore = esp_coex_common_int_restore_wrapper, + ._task_yield_from_isr = esp_coex_common_task_yield_from_isr_wrapper, + ._semphr_create = esp_coex_common_semphr_create_wrapper, + ._semphr_delete = esp_coex_common_semphr_delete_wrapper, + ._semphr_take = esp_coex_common_semphr_take_wrapper, + ._semphr_give = esp_coex_common_semphr_give_wrapper, + ._wifi_thread_semphr_get = wifi_thread_semphr_get_wrapper, + ._mutex_create = mutex_create_wrapper, + ._recursive_mutex_create = recursive_mutex_create_wrapper, + ._mutex_delete = mutex_delete_wrapper, + ._mutex_lock = mutex_lock_wrapper, + ._mutex_unlock = mutex_unlock_wrapper, + ._queue_create = queue_create_wrapper, + ._queue_delete = vqueue_delete_adapter, + ._queue_send = queue_send_wrapper, + ._queue_send_from_isr = queue_send_from_isr_wrapper, + ._queue_send_to_back = queue_send_to_back_wrapper, + ._queue_send_to_front = queue_send_to_front_wrapper, + ._queue_recv = queue_recv_wrapper, + ._queue_msg_waiting = queue_msg_waiting_wrapper, + ._event_group_create = event_group_create_wrapper, + ._event_group_delete = event_group_delete_wrapper, + ._event_group_set_bits = event_group_set_bits_wrapper, + ._event_group_clear_bits = event_group_clear_bits_wrapper, + ._event_group_wait_bits = event_group_wait_bits_wrapper, + ._task_create_pinned_to_core = task_create_pinned_to_core_wrapper, + ._task_create = task_create_wrapper, + ._task_delete = task_delete_wrapper, + ._task_delay = task_delay_wrapper, + ._task_ms_to_tick = task_ms_to_tick_wrapper, + ._task_get_current_task = task_get_current_task_wrapper, + ._task_get_max_priority = task_get_max_priority_wrapper, + ._malloc = malloc, + ._free = free, + ._event_post = esp_event_post_wrapper, + ._get_free_heap_size = esp_get_free_heap_size, + ._rand = esp_random, + ._dport_access_stall_other_cpu_start_wrap = + esp_empty_wrapper, + ._dport_access_stall_other_cpu_end_wrap = + esp_empty_wrapper, + ._wifi_apb80m_request = wifi_apb80m_request_wrapper, + ._wifi_apb80m_release = wifi_apb80m_release_wrapper, + ._phy_disable = esp_phy_disable_wrapper, + ._phy_enable = esp_phy_enable_wrapper, + ._phy_update_country_info = esp_phy_update_country_info, + ._read_mac = esp_read_mac_wrapper, + ._timer_arm = timer_arm_wrapper, + ._timer_disarm = esp_coex_common_timer_disarm_wrapper, + ._timer_done = esp_coex_common_timer_done_wrapper, + ._timer_setfn = esp_coex_common_timer_setfn_wrapper, + ._timer_arm_us = esp_coex_common_timer_arm_us_wrapper, + ._wifi_reset_mac = wifi_reset_mac_wrapper, + ._wifi_clock_enable = wifi_clock_enable_wrapper, + ._wifi_clock_disable = wifi_clock_disable_wrapper, + ._wifi_rtc_enable_iso = wifi_rtc_enable_iso_wrapper, + ._wifi_rtc_disable_iso = wifi_rtc_disable_iso_wrapper, + ._esp_timer_get_time = (int64_t(*)(void))esp_hr_timer_time_us, + ._nvs_set_i8 = esp_nvs_set_i8, + ._nvs_get_i8 = esp_nvs_get_i8, + ._nvs_set_u8 = esp_nvs_set_u8, + ._nvs_get_u8 = esp_nvs_get_u8, + ._nvs_set_u16 = esp_nvs_set_u16, + ._nvs_get_u16 = esp_nvs_get_u16, + ._nvs_open = nvs_open_wrapper, + ._nvs_close = esp_nvs_close, + ._nvs_commit = esp_nvs_commit, + ._nvs_set_blob = esp_nvs_set_blob, + ._nvs_get_blob = esp_nvs_get_blob, + ._nvs_erase_key = esp_nvs_erase_key, + ._get_random = os_get_random, + ._get_time = get_time_wrapper, + ._random = os_random, + ._slowclk_cal_get = esp_coex_common_clk_slowclk_cal_get_wrapper, + ._log_write = esp_log_write_wrapper, + ._log_writev = esp_log_writev_wrapper, + ._log_timestamp = esp_log_timestamp, + ._malloc_internal = esp_coex_common_malloc_internal_wrapper, + ._realloc_internal = realloc_internal_wrapper, + ._calloc_internal = calloc_internal_wrapper, + ._zalloc_internal = zalloc_internal_wrapper, + ._wifi_malloc = wifi_malloc, + ._wifi_realloc = wifi_realloc, + ._wifi_calloc = wifi_calloc, + ._wifi_zalloc = wifi_zalloc_wrapper, + ._wifi_create_queue = wifi_create_queue_wrapper, + ._wifi_delete_queue = wifi_delete_queue_wrapper, + ._coex_init = coex_init_wrapper, + ._coex_deinit = coex_deinit_wrapper, + ._coex_enable = coex_enable_wrapper, + ._coex_disable = coex_disable_wrapper, + ._coex_status_get = coex_status_get_wrapper, + ._coex_wifi_request = coex_wifi_request_wrapper, + ._coex_wifi_release = coex_wifi_release_wrapper, + ._coex_wifi_channel_set = coex_wifi_channel_set_wrapper, + ._coex_event_duration_get = coex_event_duration_get_wrapper, + ._coex_pti_get = coex_pti_get_wrapper, + ._coex_schm_status_bit_clear = coex_schm_status_bit_clear_wrapper, + ._coex_schm_status_bit_set = coex_schm_status_bit_set_wrapper, + ._coex_schm_interval_set = coex_schm_interval_set_wrapper, + ._coex_schm_interval_get = coex_schm_interval_get_wrapper, + ._coex_schm_curr_period_get = coex_schm_curr_period_get_wrapper, + ._coex_schm_curr_phase_get = coex_schm_curr_phase_get_wrapper, + ._coex_register_start_cb = coex_register_start_cb_wrapper, + ._coex_schm_process_restart = coex_schm_process_restart_wrapper, + ._coex_schm_register_cb = coex_schm_register_cb_wrapper, + ._coex_schm_flexible_period_set = coex_schm_flexible_period_set_wrapper, + ._coex_schm_flexible_period_get = coex_schm_flexible_period_get_wrapper, + ._magic = ESP_WIFI_OS_ADAPTER_MAGIC, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/* Private functions order is defined as: + * - A first block containing the functions in the same order as of the + * ESP-IDF' corresponding `esp_adapter.c` to ease comparison; + * - A second block of auxiliary functions block ordered by ascending; + */ + +/* First block of functions */ + +/**************************************************************************** + * Name: wifi_zalloc_wrapper + * + * Description: + * Applications allocate a block of memory and clear it with 0 + * + * Input Parameters: + * size - memory size + * + * Returned Value: + * New memory pointer + * + ****************************************************************************/ + +static IRAM_ATTR void *wifi_zalloc_wrapper(size_t size) +{ + return zalloc(size); +} + +/**************************************************************************** + * Name: wifi_create_queue + * + * Description: + * Create Wi-Fi static message queue + * + * Input Parameters: + * queue_len - queue message number + * item_size - message size + * + * Returned Value: + * Wi-Fi static message queue data pointer + * + ****************************************************************************/ + +static void *wifi_create_queue(int queue_len, int item_size) +{ + wifi_static_queue_t *wifi_queue; + + wifi_queue = kmm_malloc(sizeof(wifi_static_queue_t)); + if (!wifi_queue) + { + wlerr("Failed to kmm_malloc\n"); + return NULL; + } + + wifi_queue->handle = xqueue_create_adapter(queue_len, item_size); + if (!wifi_queue->handle) + { + wlerr("Failed to create queue\n"); + kmm_free(wifi_queue); + return NULL; + } + + return wifi_queue; +} + +/**************************************************************************** + * Name: wifi_delete_queue + * + * Description: + * Delete message queue + * + * Input Parameters: + * queue - Message queue data pointer + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void wifi_delete_queue(wifi_static_queue_t *queue) +{ + if (queue) + { + vqueue_delete_adapter(queue->handle); + kmm_free(queue); + } +} + +/**************************************************************************** + * Name: wifi_create_queue_wrapper + * + * Description: + * This function creates a new queue for Wi-Fi operations. It is a wrapper + * around the wifi_create_queue function, providing a consistent interface + * for the Wi-Fi module. + * + * Input Parameters: + * queue_len - The maximum number of items that the queue can hold. + * item_size - The size of each item in the queue. + * + * Returned Value: + * A pointer to the newly created queue, or NULL if the operation failed. + * + ****************************************************************************/ + +static void *wifi_create_queue_wrapper(int queue_len, int item_size) +{ + return wifi_create_queue(queue_len, item_size); +} + +/**************************************************************************** + * Name: wifi_delete_queue_wrapper + * + * Description: + * Delete Wi-Fi static message queue + * + * Input Parameters: + * queue - Wi-Fi static message queue data pointer + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void wifi_delete_queue_wrapper(void *queue) +{ + wifi_delete_queue(queue); +} + +/**************************************************************************** + * Name: set_intr_wrapper + * + * Description: + * Route the Wi-Fi interrupt source and attach a handle that uses the HAL + * global vector descriptor list. Mark the CPU line as non-IRAM so + * esp_intr_noniram_disable() masks it while SPI flash holds the cache off. + * + * Input Parameters: + * cpu_no - The CPU which the interrupt number belongs. + * intr_source - The interrupt hardware source number. + * intr_num - The interrupt number CPU. + * intr_prio - The interrupt priority. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void set_intr_wrapper(int32_t cpu_no, uint32_t intr_source, + uint32_t intr_num, int32_t intr_prio) +{ + intr_handle_t handle; + int irq = ESP_SOURCE2IRQ(intr_source); + esp_err_t err; + + wlinfo("cpu_no=%" PRId32 ", intr_source=%" PRIu32 + ", intr_num=%" PRIu32 ", intr_prio=%" PRId32 "\n", + cpu_no, intr_source, intr_num, intr_prio); + + esp_rom_route_intr_matrix(cpu_no, intr_source, intr_num); + esprv_int_set_priority(intr_num, intr_prio); + esprv_int_set_type(intr_num, INTR_TYPE_LEVEL); + + handle = kmm_calloc(1, sizeof(intr_handle_data_t)); + if (handle == NULL) + { + wlerr("Failed to kmm_calloc\n"); + return; + } + + handle->vector_desc = get_desc_for_int(intr_num, cpu_no); + if (handle->vector_desc == NULL) + { + wlerr("get_desc_for_int failed\n"); + kmm_free(handle); + return; + } + + handle->vector_desc->source = intr_source; + handle->shared_vector_desc = NULL; + + esp_set_handle(cpu_no, irq, handle); + + err = esp_intr_set_in_iram(handle, false); + if (err != ESP_OK) + { + wlerr("esp_intr_set_in_iram failed: %d\n", err); + } +} + +/**************************************************************************** + * Name: clear_intr_wrapper + * + * Description: + * This function is intended to clear a specific interrupt. However, this + * functionality is not supported in the current implementation. + * + * Input Parameters: + * intr_source - The source of the interrupt. + * intr_num - The number of the interrupt. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void IRAM_ATTR clear_intr_wrapper(uint32_t intr_source, + uint32_t intr_num) +{ +} + +/**************************************************************************** + * Name: set_isr_wrapper + * + * Description: + * Register interrupt function + * + * Input Parameters: + * n - CPU interrupt number + * f - Interrupt function + * arg - Function private data + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void set_isr_wrapper(int32_t n, void *f, void *arg) +{ + intr_handler_set(n, (intr_handler_t)f, arg); +} + +/**************************************************************************** + * Name: enable_intr_wrapper + * + * Description: + * Enable a specific Wi-Fi interrupt. + * + * Input Parameters: + * intr_mask - A mask where the bit corresponding to the interrupt to be + * enabled is set. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void enable_intr_wrapper(uint32_t intr_mask) +{ + int cpuint = __builtin_ffs(intr_mask) - 1; + int irq = esp_cpuint_to_irq(cpuint, this_cpu()); + + wlinfo("intr_mask=%08lx cpuint=%d irq=%d\n", intr_mask, cpuint, irq); + + esprv_int_enable(intr_mask); +} + +/**************************************************************************** + * Name: disable_intr_wrapper + * + * Description: + * Disable a specific Wi-Fi interrupt. + * + * Input Parameters: + * intr_mask - A mask where the bit corresponding to the interrupt to be + * disabled is set. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void disable_intr_wrapper(uint32_t intr_mask) +{ + int cpuint = __builtin_ffs(intr_mask) - 1; + int irq = esp_cpuint_to_irq(cpuint, this_cpu()); + + wlinfo("intr_mask=%08lx cpuint=%d irq=%d\n", intr_mask, cpuint, irq); + + up_disable_irq(irq); +} + +/**************************************************************************** + * Name: is_from_isr_wrapper + * + * Description: + * Check current is in interrupt + * + * Input Parameters: + * None + * + * Returned Value: + * true if in interrupt or false if not + * + ****************************************************************************/ + +static bool IRAM_ATTR is_from_isr_wrapper(void) +{ + return up_interrupt_context(); +} + +/**************************************************************************** + * Name: wifi_thread_semphr_free + * + * Description: + * Delete thread self's semaphore + * + * Input Parameters: + * data - Semaphore data pointer + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void wifi_thread_semphr_free(void *data) +{ + void *sem = (void *)data; + + if (sem) + { + vsemaphore_delete_adapter(sem); + } +} + +/**************************************************************************** + * Name: wifi_thread_semphr_get_wrapper + * + * Description: + * Get thread self's semaphore + * + * Input Parameters: + * None + * + * Returned Value: + * Semaphore data pointer + * + ****************************************************************************/ + +static void *wifi_thread_semphr_get_wrapper(void) +{ + static int wifi_task_key = -1; + int ret; + void *sem; + + if (wifi_task_key < 0) + { + ret = task_tls_alloc(wifi_thread_semphr_free); + if (ret < 0) + { + wlerr("Failed to create task local key\n"); + return NULL; + } + + wifi_task_key = ret; + } + + sem = (void *)task_tls_get_value(wifi_task_key); + if (sem == NULL) + { + sem = xsemaphore_create_counting_adapter(1, 0); + if (!sem) + { + wlerr("Failed to create semaphore\n"); + return NULL; + } + + ret = task_tls_set_value(wifi_task_key, (uintptr_t)sem); + if (ret != OK) + { + wlerr("Failed to save semaphore on task local storage: %d\n", ret); + vsemaphore_delete_adapter(sem); + return NULL; + } + } + + return sem; +} + +/**************************************************************************** + * Name: recursive_mutex_create_wrapper + * + * Description: + * Create recursive mutex + * + * Input Parameters: + * None + * + * Returned Value: + * Recursive mutex data pointer + * + ****************************************************************************/ + +static void *recursive_mutex_create_wrapper(void) +{ + int ret; + pthread_mutex_t *mutex; + pthread_mutexattr_t attr; + int tmp; + + ret = pthread_mutexattr_init(&attr); + if (ret) + { + wlerr("Failed to initialize attr error=%d\n", ret); + return NULL; + } + + ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + if (ret) + { + wlerr("Failed to set attr type error=%d\n", ret); + return NULL; + } + + tmp = sizeof(pthread_mutex_t); + mutex = kmm_malloc(tmp); + if (!mutex) + { + wlerr("Failed to alloc %d memory\n", tmp); + return NULL; + } + + ret = pthread_mutex_init(mutex, &attr); + if (ret) + { + wlerr("Failed to initialize mutex error=%d\n", ret); + kmm_free(mutex); + return NULL; + } + + return mutex; +} + +/**************************************************************************** + * Name: mutex_create_wrapper + * + * Description: + * Create mutex + * + * Input Parameters: + * None + * + * Returned Value: + * Mutex data pointer + * + ****************************************************************************/ + +static void *mutex_create_wrapper(void) +{ + int ret; + pthread_mutex_t *mutex; + int tmp; + + tmp = sizeof(pthread_mutex_t); + mutex = kmm_malloc(tmp); + if (!mutex) + { + wlerr("Failed to alloc %d memory\n", tmp); + return NULL; + } + + ret = pthread_mutex_init(mutex, NULL); + if (ret) + { + wlerr("Failed to initialize mutex error=%d\n", ret); + kmm_free(mutex); + return NULL; + } + + return mutex; +} + +/**************************************************************************** + * Name: mutex_delete_wrapper + * + * Description: + * Delete mutex + * + * Input Parameters: + * mutex - mutex data pointer + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void mutex_delete_wrapper(void *mutex) +{ + pthread_mutex_t *mutex_data = (pthread_mutex_t *)mutex; + + pthread_mutex_destroy(mutex_data); + kmm_free(mutex_data); +} + +/**************************************************************************** + * Name: mutex_lock_wrapper + * + * Description: + * Lock mutex + * + * Input Parameters: + * mutex - mutex data pointer + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +static int32_t IRAM_ATTR mutex_lock_wrapper(void *mutex) +{ + int ret; + pthread_mutex_t *mutex_data = (pthread_mutex_t *)mutex; + + ret = pthread_mutex_lock(mutex_data); + if (ret) + { + wlerr("Failed to lock mutex error=%d\n", ret); + } + + return nuttx_err_to_common_err(ret); +} + +/**************************************************************************** + * Name: mutex_unlock_wrapper + * + * Description: + * Unlock mutex + * + * Input Parameters: + * mutex - mutex data pointer + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +static int32_t IRAM_ATTR mutex_unlock_wrapper(void *mutex) +{ + int ret; + pthread_mutex_t *mutex_data = (pthread_mutex_t *)mutex; + + ret = pthread_mutex_unlock(mutex_data); + if (ret) + { + wlerr("Failed to unlock mutex error=%d\n", ret); + } + + return nuttx_err_to_common_err(ret); +} + +/**************************************************************************** + * Name: queue_create_wrapper + * + * Description: + * This function creates a new queue adapter with the specified length and + * item size. It is a wrapper around the xqueue_create_adapter function. + * + * Input Parameters: + * queue_len - The maximum number of items that the queue can hold. + * item_size - The size of each item in the queue. + * + * Returned Value: + * A pointer to the newly created queue adapter, or NULL if the operation + * failed. + * + ****************************************************************************/ + +static void *queue_create_wrapper(uint32_t queue_len, uint32_t item_size) +{ + return xqueue_create_adapter(queue_len, item_size); +} + +/**************************************************************************** + * Name: queue_send_wrapper + * + * Description: + * Send message of low priority to queue within a certain period of time + * + * Input Parameters: + * queue - Message queue data pointer + * item - Message data pointer + * ticks - Wait ticks + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +static int32_t queue_send_wrapper(void *queue, void *item, uint32_t ticks) +{ + return xqueue_send_adapter(queue, item, ticks, 0); +} + +/**************************************************************************** + * Name: queue_send_from_isr_wrapper + * + * Description: + * Send message of low priority to queue in ISR within + * a certain period of time + * + * Input Parameters: + * queue - Message queue data pointer + * item - Message data pointer + * hptw - Unused. + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +static int32_t IRAM_ATTR queue_send_from_isr_wrapper(void *queue, + void *item, + void *hptw) +{ + *(int *)hptw = 0; + + return xqueue_send_adapter(queue, item, 0, 0); +} + +/**************************************************************************** + * Name: queue_send_to_back_wrapper + * + * Description: + * Send message of low priority to queue within a certain period of time + * + * Input Parameters: + * queue - Message queue data pointer + * item - Message data pointer + * ticks - Wait ticks + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +static int32_t queue_send_to_back_wrapper(void *queue, + void *item, + uint32_t ticks) +{ + return xqueue_send_adapter(queue, item, ticks, 0); +} + +/**************************************************************************** + * Name: queue_send_to_front_wrapper + * + * Description: + * Send message of high priority to queue within a certain period of time + * + * Input Parameters: + * queue - Message queue data pointer + * item - Message data pointer + * ticks - Wait ticks + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +static int32_t queue_send_to_front_wrapper(void *queue, + void *item, + uint32_t ticks) +{ + return xqueue_send_adapter(queue, item, ticks, 1); +} + +/**************************************************************************** + * Name: queue_recv_wrapper + * + * Description: + * Receive message from queue within a certain period of time + * + * Input Parameters: + * queue - Message queue data pointer + * item - Message data pointer + * ticks - Wait ticks + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +static int32_t queue_recv_wrapper(void *queue, void *item, uint32_t ticks) +{ + ssize_t ret; + struct timespec timeout; + unsigned int prio; + struct mq_adpt *mq_adpt = (struct mq_adpt *)queue; + + if (ticks == OSI_FUNCS_TIME_BLOCKING) + { + ret = file_mq_receive(&mq_adpt->mq, (char *)item, + mq_adpt->msgsize, &prio); + if (ret < 0) + { + wlerr("Failed to receive from mqueue error=%d\n", ret); + } + } + else + { + ret = clock_gettime(CLOCK_REALTIME, &timeout); + if (ret < 0) + { + wlerr("Failed to get time\n"); + return false; + } + + if (ticks) + { + esp_update_time(&timeout, ticks); + } + + ret = file_mq_timedreceive(&mq_adpt->mq, (char *)item, + mq_adpt->msgsize, &prio, &timeout); + if (ret < 0) + { + wlerr("Failed to timedreceive from mqueue error=%d\n", + ret); + } + } + + return ret > 0 ? true : false; +} + +/**************************************************************************** + * Name: event_group_wait_bits_wrapper + * + * Description: + * Don't support + * + ****************************************************************************/ + +static uint32_t event_group_wait_bits_wrapper(void *event, + uint32_t bits_to_wait_for, + int clear_on_exit, + int wait_for_all_bits, + uint32_t block_time_tick) +{ + DEBUGPANIC(); + + return false; +} + +/**************************************************************************** + * Name: task_create_pinned_to_core_wrapper + * + * Description: + * Create task and bind it to target CPU, the task will run when it + * is created + * + * Input Parameters: + * entry - Task entry + * name - Task name + * stack_depth - Task stack size + * param - Task private data + * prio - Task priority + * task_handle - Task handle pointer which is used to pause, resume + * and delete the task + * core_id - CPU which the task runs in + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +static int32_t task_create_pinned_to_core_wrapper(void *entry, + const char *name, + uint32_t stack_depth, + void *param, + uint32_t prio, + void *task_handle, + uint32_t core_id) +{ + int pid; +#ifdef CONFIG_SMP + int ret; + cpu_set_t cpuset; +#endif + uint32_t target_prio = prio; + + if (target_prio < ESP_MAX_PRIORITIES) + { + target_prio += task_get_max_priority_wrapper() - ESP_MAX_PRIORITIES; + } + + pid = kthread_create(name, target_prio, stack_depth, entry, + (char * const *)param); + if (pid > 0) + { + if (task_handle != NULL) + { + *((int *)task_handle) = pid; + } + +#ifdef CONFIG_SMP + if (core_id < CONFIG_SMP_NCPUS) + { + CPU_ZERO(&cpuset); + CPU_SET(core_id, &cpuset); + ret = nxsched_set_affinity(pid, sizeof(cpuset), &cpuset); + if (ret) + { + wlerr("Failed to set affinity error=%d\n", ret); + return false; + } + } +#endif + } + else + { + wlerr("Failed to create task\n"); + } + + return pid > 0; +} + +/**************************************************************************** + * Name: task_create_wrapper + * + * Description: + * Create task and the task will run when it is created + * + * Input Parameters: + * entry - Task entry + * name - Task name + * stack_depth - Task stack size + * param - Task private data + * prio - Task priority + * task_handle - Task handle pointer which is used to pause, resume + * and delete the task + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +static int32_t task_create_wrapper(void *entry, + const char *name, + uint32_t stack_depth, + void *param, + uint32_t prio, + void *task_handle) +{ + return task_create_pinned_to_core_wrapper(entry, + name, + stack_depth, + param, + prio, + task_handle, + UINT32_MAX); +} + +/**************************************************************************** + * Name: task_ms_to_tick_wrapper + * + * Description: + * This function converts a duration from milliseconds to system ticks. + * It is a wrapper around the NuttX MSEC2TICK macro. + * + * Input Parameters: + * ms - The duration in milliseconds. + * + * Returned Value: + * The duration in system ticks. + * + ****************************************************************************/ + +static int32_t task_ms_to_tick_wrapper(uint32_t ms) +{ + return MSEC2TICK(ms); +} + +/**************************************************************************** + * Name: task_get_max_priority_wrapper + * + * Description: + * Get OS task maximum priority + * + * Input Parameters: + * None + * + * Returned Value: + * Task maximum priority + * + ****************************************************************************/ + +static int32_t task_get_max_priority_wrapper(void) +{ + return SCHED_PRIORITY_MAX; +} + +/**************************************************************************** + * Name: esp_event_post_wrapper + * + * Description: + * Active work queue and let the work to process the cached event + * + * Input Parameters: + * event_base - Event set name + * event_id - Event ID + * event_data - Event private data + * event_data_size - Event data size + * ticks - Waiting system ticks + * + * Returned Value: + * 0 if success or -1 if fail + * + ****************************************************************************/ + +int32_t esp_event_post_wrapper(const char *event_base, + int32_t event_id, + void *event_data, + size_t event_data_size, + uint32_t ticks) +{ + return (int32_t)esp_event_post(event_base, + event_id, + event_data, + event_data_size, + ticks); +} + +/**************************************************************************** + * Name: wifi_apb80m_request_wrapper + * + * Description: + * This function acquires the Wi-Fi lock in auto-sleep mode. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void IRAM_ATTR wifi_apb80m_request_wrapper(void) +{ +#ifdef CONFIG_PM + wifi_apb80m_request(); +#endif +} + +/**************************************************************************** + * Name: wifi_apb80m_release_wrapper + * + * Description: + * This function releases the Wi-Fi lock in auto-sleep mode. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void IRAM_ATTR wifi_apb80m_release_wrapper(void) +{ +#ifdef CONFIG_PM + wifi_apb80m_release(); +#endif +} + +/**************************************************************************** + * Name: esp_phy_enable_wrapper + * + * Description: + * This function enables the WiFi PHY. It first enables the PHY for the + * WiFi modem, then sets the WiFi PHY enable flag to 1. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void esp_phy_enable_wrapper(void) +{ + esp_phy_enable(PHY_MODEM_WIFI); + phy_wifi_enable_set(1); +} + +/**************************************************************************** + * Name: esp_phy_disable_wrapper + * + * Description: + * This function disables the WiFi PHY. It first sets the WiFi PHY enable + * flag to 0, then disables the PHY for the WiFi modem. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void esp_phy_disable_wrapper(void) +{ + phy_wifi_enable_set(0); + esp_phy_disable(PHY_MODEM_WIFI); +} + +/**************************************************************************** + * Name: timer_arm_wrapper + * + * Description: + * Set timer timeout period and repeat flag + * + * Input Parameters: + * ptimer - timer data pointer + * ms - millim seconds + * repeat - true: run cycle, false: run once + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void IRAM_ATTR timer_arm_wrapper(void *ptimer, + uint32_t tmout, + bool repeat) +{ + ets_timer_arm(ptimer, tmout, repeat); +} + +/**************************************************************************** + * Name: wifi_reset_mac_wrapper + * + * Description: + * Reset Wi-Fi hardware MAC + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void wifi_reset_mac_wrapper(void) +{ + periph_module_reset(PERIPH_WIFI_MODULE); +} + +/**************************************************************************** + * Name: wifi_rtc_enable_iso_wrapper + * + * Description: + * This function is a wrapper for enabling the isolation of the Wi-Fi + * Real-Time Clock (RTC). If the MAC/BB power down configuration option + * is set, it powers down the MAC/BB. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void IRAM_ATTR wifi_rtc_enable_iso_wrapper(void) +{ +#if CONFIG_MAC_BB_PD + esp_mac_bb_power_down(); +#endif +} + +/**************************************************************************** + * Name: wifi_rtc_disable_iso_wrapper + * + * Description: + * This function is a wrapper for disabling the isolation of the Wi-Fi + * Real-Time Clock (RTC). If the MAC/BB power down configuration option + * is set, it powers up the MAC/BB. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void IRAM_ATTR wifi_rtc_disable_iso_wrapper(void) +{ +#if CONFIG_MAC_BB_PD + esp_mac_bb_power_up(); +#endif +} + +/**************************************************************************** + * Name: wifi_clock_enable_wrapper + * + * Description: + * Enable Wi-Fi clock + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void wifi_clock_enable_wrapper(void) +{ + wifi_module_enable(); +} + +/**************************************************************************** + * Name: wifi_clock_disable_wrapper + * + * Description: + * Disable Wi-Fi clock + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void wifi_clock_disable_wrapper(void) +{ + wifi_module_disable(); +} + +/**************************************************************************** + * Name: get_time_wrapper + * + * Description: + * Get std C time + * + * Input Parameters: + * t - buffer to store time of type timeval + * + * Returned Value: + * Zero (OK) on success; -1 is returned on failure with the errno variable + * set appropriately. + * + ****************************************************************************/ + +static int get_time_wrapper(void *t) +{ + return os_get_time(t); +} + +/**************************************************************************** + * Name: realloc_internal_wrapper + * + * Description: + * Drivers allocate a block of memory by old memory block + * + * Input Parameters: + * ptr - old memory pointer + * size - memory size + * + * Returned Value: + * New memory pointer + * + ****************************************************************************/ + +static IRAM_ATTR void *realloc_internal_wrapper(void *ptr, size_t size) +{ + return kmm_realloc(ptr, size); +} + +/**************************************************************************** + * Name: calloc_internal_wrapper + * + * Description: + * Drivers allocate some continuous blocks of memory + * + * Input Parameters: + * n - memory block number + * size - memory block size + * + * Returned Value: + * New memory pointer + * + ****************************************************************************/ + +static IRAM_ATTR void *calloc_internal_wrapper(size_t n, size_t size) +{ + return kmm_calloc(n, size); +} + +/**************************************************************************** + * Name: zalloc_internal_wrapper + * + * Description: + * Drivers allocate a block of memory and clear it with 0 + * + * Input Parameters: + * size - memory size + * + * Returned Value: + * New memory pointer + * + ****************************************************************************/ + +static IRAM_ATTR void *zalloc_internal_wrapper(size_t size) +{ + return kmm_zalloc(size); +} + +/**************************************************************************** + * Name: nvs_open_wrapper + * + * Description: + * Create a file system storage data object + * + * Input Parameters: + * name - Storage index + * open_mode - Storage mode + * out_handle - Storage handle + * + * Returned Value: + * 0 if success or -1 if fail + * + ****************************************************************************/ + +static int nvs_open_wrapper(const char *name, + unsigned int open_mode, + uint32_t *out_handle) +{ + DEBUGPANIC(); + + return -1; +} + +/**************************************************************************** + * Name: esp_log_writev_wrapper + * + * Description: + * Output log with by format string and its arguments + * + * Input Parameters: + * level - log level, no mean here + * tag - log TAG, no mean here + * format - format string + * args - arguments list + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void esp_log_writev_wrapper(unsigned int level, + const char *tag, + const char *format, + va_list args) +{ + esp_log_level_t max_level; + +#if defined (CONFIG_DEBUG_WIRELESS_INFO) + max_level = ESP_LOG_VERBOSE; +#elif defined (CONFIG_DEBUG_WIRELESS_WARN) + max_level = ESP_LOG_WARN; +#elif defined (CONFIG_DEBUG_WIRELESS_ERROR) + max_level = ESP_LOG_ERROR; +#else + max_level = ESP_LOG_NONE; +#endif + + if (level <= max_level) + { + esp_log_writev(level, tag, format, args); + } +} + +/**************************************************************************** + * Name: esp_log_write_wrapper + * + * Description: + * Output log with by format string and its arguments + * + * Input Parameters: + * level - log level, no mean here + * tag - log TAG, no mean here + * format - format string + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void esp_log_write_wrapper(unsigned int level, + const char *tag, + const char *format, ...) +{ + esp_log_level_t max_level; + +#if defined (CONFIG_DEBUG_WIRELESS_INFO) + max_level = ESP_LOG_VERBOSE; +#elif defined (CONFIG_DEBUG_WIRELESS_WARN) + max_level = ESP_LOG_WARN; +#elif defined (CONFIG_DEBUG_WIRELESS_ERROR) + max_level = ESP_LOG_ERROR; +#else + max_level = ESP_LOG_NONE; +#endif + + if (level <= max_level) + { + va_list list; + + va_start(list, format); + esp_log_writev(level, tag, format, list); + va_end(list); + } +} + +/**************************************************************************** + * Name: esp_read_mac_wrapper + * + * Description: + * Read MAC address from efuse + * + * Input Parameters: + * mac - MAC address buffer pointer + * type - MAC address type + * + * Returned Value: + * 0 if success or -1 if fail + * + ****************************************************************************/ + +static int esp_read_mac_wrapper(uint8_t *mac, unsigned int type) +{ + return esp_read_mac(mac, type); +} + +/**************************************************************************** + * Name: coex_init_wrapper + * + * Description: + * Init software coexist + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. + * + ****************************************************************************/ + +static int coex_init_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + return coex_init(); +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: coex_deinit_wrapper + * + * Description: + * De-init software coexist + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void coex_deinit_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + coex_deinit(); +#endif +} + +/**************************************************************************** + * Name: coex_enable_wrapper + * + * Description: + * Enable software coexist + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. + * + ****************************************************************************/ + +static int coex_enable_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + return coex_enable(); +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: coex_disable_wrapper + * + * Description: + * Disable software coexist + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void coex_disable_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + coex_disable(); +#endif +} + +/**************************************************************************** + * Name: coex_status_get_wrapper + * + * Description: + * Get software coexist status. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. + * + ****************************************************************************/ + +static IRAM_ATTR uint32_t coex_status_get_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + return coex_status_get(); +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: coex_wifi_request_wrapper + * + * Description: + * Request Wi-Fi coexistence. + * + * Input Parameters: + * event - WiFi event + * latency - WiFi will request coexistence after latency + * duration - duration for WiFi to request coexistence + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. + * + ****************************************************************************/ + +static int coex_wifi_request_wrapper(uint32_t event, + uint32_t latency, + uint32_t duration) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + return coex_wifi_request(event, latency, duration); +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: coex_wifi_release_wrapper + * + * Description: + * Release Wi-Fi coexistence. + * + * Input Parameters: + * event - WiFi event + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. + * + ****************************************************************************/ + +static IRAM_ATTR int coex_wifi_release_wrapper(uint32_t event) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + return coex_wifi_release(event); +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: coex_wifi_channel_set_wrapper + * + * Description: + * Set Wi-Fi channel to coexistence module. + * + * Input Parameters: + * primary - WiFi primary channel + * secondary - WiFi secondary channel + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. + * + ****************************************************************************/ + +static int coex_wifi_channel_set_wrapper(uint8_t primary, uint8_t secondary) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + return coex_wifi_channel_set(primary, secondary); +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: coex_event_duration_get_wrapper + * + * Description: + * Get coexistence event duration. + * + * Input Parameters: + * event - Coexistence event + * duration - Coexistence event duration + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. + * + ****************************************************************************/ + +static IRAM_ATTR int coex_event_duration_get_wrapper(uint32_t event, + uint32_t *duration) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + return coex_event_duration_get(event, duration); +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: coex_pti_get_wrapper + * + * Description: + * Get coexistence event priority. + * + * Input Parameters: + * event - Coexistence event + * pti - Coexistence event priority + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. + * + ****************************************************************************/ + +static int coex_pti_get_wrapper(uint32_t event, uint8_t *pti) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + return coex_pti_get(event, pti); +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: coex_schm_status_bit_clear_wrapper + * + * Description: + * Clear coexistence status. + * + * Input Parameters: + * type - Coexistence status type + * status - Coexistence status + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void coex_schm_status_bit_clear_wrapper(uint32_t type, + uint32_t status) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + coex_schm_status_bit_clear(type, status); +#endif +} + +/**************************************************************************** + * Name: coex_schm_status_bit_set_wrapper + * + * Description: + * Set coexistence status. + * + * Input Parameters: + * type - Coexistence status type + * status - Coexistence status + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void coex_schm_status_bit_set_wrapper(uint32_t type, uint32_t status) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + coex_schm_status_bit_set(type, status); +#endif +} + +/**************************************************************************** + * Name: coex_schm_interval_set_wrapper + * + * Description: + * Set coexistence scheme interval. + * + * Input Parameters: + * interval - Coexistence scheme interval + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. + * + ****************************************************************************/ + +static IRAM_ATTR int coex_schm_interval_set_wrapper(uint32_t interval) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + return coex_schm_interval_set(interval); +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: coex_schm_interval_get_wrapper + * + * Description: + * Get coexistence scheme interval. + * + * Input Parameters: + * None + * + * Returned Value: + * Coexistence scheme interval + * + ****************************************************************************/ + +static uint32_t coex_schm_interval_get_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + return coex_schm_interval_get(); +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: coex_schm_curr_period_get_wrapper + * + * Description: + * Get current coexistence scheme period. + * + * Input Parameters: + * None + * + * Returned Value: + * Coexistence scheme period + * + ****************************************************************************/ + +static uint8_t coex_schm_curr_period_get_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + return coex_schm_curr_period_get(); +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: coex_schm_curr_phase_get_wrapper + * + * Description: + * Get current coexistence scheme phase. + * + * Input Parameters: + * None + * + * Returned Value: + * Coexistence scheme phase + * + ****************************************************************************/ + +static void *coex_schm_curr_phase_get_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE + return coex_schm_curr_phase_get(); +#else + return NULL; +#endif +} + +/**************************************************************************** + * Name: coex_register_start_cb_wrapper + * + * Description: + * Register Wi-Fi callback for coexistence starts. + * + * Input Parameters: + * cb - WiFi callback + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. + * + ****************************************************************************/ + +static int coex_register_start_cb_wrapper(int (* cb)(void)) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_register_start_cb(cb); +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: coex_schm_process_restart_wrapper + * + * Description: + * Restart current coexistence scheme. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. + * + ****************************************************************************/ + +static int coex_schm_process_restart_wrapper(void) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_schm_process_restart(); +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: coex_schm_register_cb_wrapper + * + * Description: + * Register callback for coexistence scheme. + * + * Input Parameters: + * type - callback type + * cb - callback + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned + * on failure. + * + ****************************************************************************/ + +static int coex_schm_register_cb_wrapper(int type, int(*cb)(int)) +{ +#if CONFIG_SW_COEXIST_ENABLE + return coex_schm_register_callback(type, cb); +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: coex_schm_flexible_period_set_wrapper + * + * Description: + * This function sets the coexistence scheme flexible period. If the + * coexistence power management feature is enabled + * (CONFIG_ESP_COEX_POWER_MANAGEMENT), it calls the function + * coex_schm_flexible_period_set with the given period and returns its + * result. If the feature is not enabled, it returns 0. + * + * Input Parameters: + * period - The flexible period to set. + * + * Returned Value: + * ESP_OK on success, or the result of coex_schm_flexible_period_set. + * + ****************************************************************************/ + +static int coex_schm_flexible_period_set_wrapper(uint8_t period) +{ +#if CONFIG_ESP_COEX_POWER_MANAGEMENT + return coex_schm_flexible_period_set(period); +#else + return 0; +#endif +} + +/**************************************************************************** + * Name: coex_schm_flexible_period_get_wrapper + * + * Description: + * This function gets the coexistence scheme flexible period. If the + * coexistence power management feature is enabled + * (CONFIG_ESP_COEX_POWER_MANAGEMENT), it calls the function + * coex_schm_flexible_period_get and returns its result. If the feature is + * not enabled, it returns 1. + * + * Input Parameters: + * None + * + * Returned Value: + * The coexistence scheme flexible period. + * + ****************************************************************************/ + +static uint8_t coex_schm_flexible_period_get_wrapper(void) +{ +#if CONFIG_ESP_COEX_POWER_MANAGEMENT + return coex_schm_flexible_period_get(); +#else + return 1; +#endif +} + +/**************************************************************************** + * Name: esp_empty_wrapper + * + * Description: + * This function is an empty wrapper, designed to be used where a function + * pointer is required but no operation is needed. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void IRAM_ATTR esp_empty_wrapper(void) +{ +} + +/**************************************************************************** + * Name: esp_get_free_heap_size + * + * Description: + * Get free heap size by byte + * + * Input Parameters: + * None + * + * Returned Value: + * Free heap size + * + ****************************************************************************/ + +static uint32_t esp_get_free_heap_size(void) +{ + struct mallinfo info; + + info = kmm_mallinfo(); + return info.fordblks; +} + +/**************************************************************************** + * Name: event_group_create_wrapper + * + * Description: + * Don't support + * + ****************************************************************************/ + +static void *event_group_create_wrapper(void) +{ + DEBUGPANIC(); + + return NULL; +} + +/**************************************************************************** + * Name: event_group_delete_wrapper + * + * Description: + * Don't support + * + ****************************************************************************/ + +static void event_group_delete_wrapper(void *event) +{ + DEBUGPANIC(); +} + +/**************************************************************************** + * Name: event_group_set_bits_wrapper + * + * Description: + * Don't support + * + ****************************************************************************/ + +static uint32_t event_group_set_bits_wrapper(void *event, uint32_t bits) +{ + DEBUGPANIC(); + + return false; +} + +/**************************************************************************** + * Name: event_group_clear_bits_wrapper + * + * Description: + * Don't support + * + ****************************************************************************/ + +static uint32_t event_group_clear_bits_wrapper(void *event, uint32_t bits) +{ + DEBUGPANIC(); + + return false; +} + +/**************************************************************************** + * Name: esp_nvs_commit + * + * Description: + * This function has no practical effect + * + ****************************************************************************/ + +static int esp_nvs_commit(uint32_t handle) +{ + return 0; +} + +/**************************************************************************** + * Name: esp_nvs_erase_key + * + * Description: + * Read a block of data from file system + * + * Input Parameters: + * handle - NVS handle + * key - Data index + * + * Returned Value: + * 0 if success or -1 if fail + * + ****************************************************************************/ + +static int esp_nvs_erase_key(uint32_t handle, const char *key) +{ + DEBUGPANIC(); + + return -1; +} + +/**************************************************************************** + * Name: esp_nvs_get_blob + * + * Description: + * Read a block of data from file system + * + * Input Parameters: + * handle - NVS handle + * key - Data index + * out_value - Read buffer pointer + * length - Buffer length + * + * Returned Value: + * 0 if success or -1 if fail + * + ****************************************************************************/ + +static int esp_nvs_get_blob(uint32_t handle, + const char *key, + void *out_value, + size_t *length) +{ + DEBUGPANIC(); + + return -1; +} + +/**************************************************************************** + * Name: esp_nvs_set_blob + * + * Description: + * Save a block of data into file system + * + * Input Parameters: + * handle - NVS handle + * key - Data index + * value - Stored buffer pointer + * length - Buffer length + * + * Returned Value: + * 0 if success or -1 if fail + * + ****************************************************************************/ + +static int esp_nvs_set_blob(uint32_t handle, + const char *key, + const void *value, + size_t length) +{ + DEBUGPANIC(); + + return -1; +} + +/**************************************************************************** + * Name: esp_nvs_get_i8 + * + * Description: + * Read data of type int8_t from file system + * + * Input Parameters: + * handle - NVS handle + * key - Data index + * out_value - Read buffer pointer + * + * Returned Value: + * 0 if success or -1 if fail + * + ****************************************************************************/ + +static int esp_nvs_get_i8(uint32_t handle, + const char *key, + int8_t *out_value) +{ + DEBUGPANIC(); + + return -1; +} + +/**************************************************************************** + * Name: esp_nvs_set_i8 + * + * Description: + * Save data of type int8_t into file system + * + * Input Parameters: + * handle - NVS handle + * key - Data index + * value - Stored data + * + * Returned Value: + * 0 if success or -1 if fail + * + ****************************************************************************/ + +static int esp_nvs_set_i8(uint32_t handle, + const char *key, + int8_t value) +{ + DEBUGPANIC(); + + return -1; +} + +/**************************************************************************** + * Name: esp_nvs_get_u8 + * + * Description: + * Read data of type uint8_t from file system + * + * Input Parameters: + * handle - NVS handle + * key - Data index + * out_value - Read buffer pointer + * + * Returned Value: + * 0 if success or -1 if fail + * + ****************************************************************************/ + +static int esp_nvs_get_u8(uint32_t handle, + const char *key, + uint8_t *out_value) +{ + DEBUGPANIC(); + + return -1; +} + +/**************************************************************************** + * Name: esp_nvs_set_u8 + * + * Description: + * Save data of type uint8_t into file system + * + * Input Parameters: + * handle - NVS handle + * key - Data index + * value - Stored data + * + * Returned Value: + * 0 if success or -1 if fail + * + ****************************************************************************/ + +static int esp_nvs_set_u8(uint32_t handle, + const char *key, + uint8_t value) +{ + DEBUGPANIC(); + + return -1; +} + +/**************************************************************************** + * Name: esp_nvs_get_u16 + * + * Description: + * Read data of type uint16_t from file system + * + * Input Parameters: + * handle - NVS handle + * key - Data index + * out_value - Read buffer pointer + * + * Returned Value: + * 0 if success or -1 if fail + * + ****************************************************************************/ + +static int esp_nvs_get_u16(uint32_t handle, + const char *key, + uint16_t *out_value) +{ + DEBUGPANIC(); + + return -1; +} + +/**************************************************************************** + * Name: esp_nvs_set_u16 + * + * Description: + * Save data of type uint16_t into file system + * + * Input Parameters: + * handle - NVS handle + * key - Data index + * value - Stored data + * + * Returned Value: + * 0 if success or -1 if fail + * + ****************************************************************************/ + +static int esp_nvs_set_u16(uint32_t handle, + const char *key, + uint16_t value) +{ + DEBUGPANIC(); + + return -1; +} + +/**************************************************************************** + * Name: esp_nvs_close + * + * Description: + * Close storage data object and free resource + * + * Input Parameters: + * handle - NVS handle + * + * Returned Value: + * 0 if success or -1 if fail + * + ****************************************************************************/ + +static void esp_nvs_close(uint32_t handle) +{ + DEBUGPANIC(); +} + +/**************************************************************************** + * Name: esp_update_time + * + * Description: + * Transform ticks to time and add this time to timespec value + * + * Input Parameters: + * timespec - Input timespec data pointer + * ticks - System ticks + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void esp_update_time(struct timespec *timespec, uint32_t ticks) +{ + struct timespec ts; + + clock_ticks2time(&ts, ticks); + clock_timespec_add(timespec, &ts, timespec); +} + +/**************************************************************************** + * Name: queue_msg_waiting_wrapper + * + * Description: + * Get message number in the message queue + * + * Input Parameters: + * queue - Message queue data pointer + * + * Returned Value: + * Message number + * + ****************************************************************************/ + +static uint32_t queue_msg_waiting_wrapper(void *queue) +{ + int ret; + struct mq_attr attr; + struct mq_adpt *mq_adpt = (struct mq_adpt *)queue; + + ret = file_mq_getattr(&mq_adpt->mq, &attr); + if (ret < 0) + { + wlerr("Failed to get attr from mqueue error=%d\n", ret); + return 0; + } + + return attr.mq_curmsgs; +} + +/**************************************************************************** + * Name: task_delay_wrapper + * + * Description: + * Current task wait for some ticks + * + * Input Parameters: + * tick - Waiting ticks + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void task_delay_wrapper(uint32_t tick) +{ + useconds_t us = TICK2USEC(tick); + + nxsched_usleep(us); +} + +/**************************************************************************** + * Name: task_delete_wrapper + * + * Description: + * Delete the target task + * + * Input Parameters: + * task_handle - Task handle pointer which is used to pause, resume + * and delete the task + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void task_delete_wrapper(void *task_handle) +{ + pid_t pid = (pid_t)((uintptr_t)task_handle); + + kthread_delete(pid); +} + +/**************************************************************************** + * Name: task_get_current_task_wrapper + * + * Description: + * This function gets the current task's PID and returns it as a void + * pointer. This is a wrapper around the NuttX function nxsched_gettid. + * + * Input Parameters: + * None + * + * Returned Value: + * The current task's PID as a void pointer. + * + ****************************************************************************/ + +static void *task_get_current_task_wrapper(void) +{ + pid_t pid = nxsched_gettid(); + + return (void *)((uintptr_t)pid); +} + +/**************************************************************************** + * Name: vqueue_delete_adapter + * + * Description: + * This function deletes a queue adapter. It closes the message queue, + * unlinks it, and then frees the memory allocated for the queue adapter. + * + * Input Parameters: + * queue - A pointer to the queue adapter to be deleted. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void vqueue_delete_adapter(void *queue) +{ + struct mq_adpt *mq_adpt = (struct mq_adpt *)queue; + + file_mq_close(&mq_adpt->mq); + file_mq_unlink(mq_adpt->name); + kmm_free(mq_adpt); +} + +/**************************************************************************** + * Name: vsemaphore_delete_adapter + * + * Description: + * Delete semaphore + * + * Input Parameters: + * semphr - Semaphore data pointer + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void vsemaphore_delete_adapter(void *semphr) +{ + sem_t *sem = (sem_t *)semphr; + + nxsem_destroy(sem); + kmm_free(sem); +} + +/**************************************************************************** + * Name: xqueue_create_adapter + * + * Description: + * Create message queue + * + * Input Parameters: + * queue_len - queue message number + * item_size - message size + * + * Returned Value: + * Message queue data pointer + * + ****************************************************************************/ + +static void *xqueue_create_adapter(uint32_t queue_len, uint32_t item_size) +{ + struct mq_attr attr; + struct mq_adpt *mq_adpt; + int ret; + + mq_adpt = kmm_malloc(sizeof(struct mq_adpt)); + if (!mq_adpt) + { + wlerr("Failed to kmm_malloc\n"); + return NULL; + } + + snprintf(mq_adpt->name, sizeof(mq_adpt->name), + "/tmp/%p", mq_adpt); + + attr.mq_maxmsg = queue_len; + attr.mq_msgsize = item_size; + attr.mq_curmsgs = 0; + attr.mq_flags = 0; + + ret = file_mq_open(&mq_adpt->mq, mq_adpt->name, + O_RDWR | O_CREAT, 0644, &attr); + if (ret < 0) + { + wlerr("Failed to create mqueue\n"); + kmm_free(mq_adpt); + return NULL; + } + + mq_adpt->msgsize = item_size; + + return (void *)mq_adpt; +} + +/**************************************************************************** + * Name: xqueue_send_adapter + * + * Description: + * Generic send message to queue within a certain period of time + * + * Input Parameters: + * queue - Message queue data pointer + * item - Message data pointer + * ticks - Wait ticks + * prio - Message priority + * + * Returned Value: + * True if success or false if fail + * + ****************************************************************************/ + +static int32_t xqueue_send_adapter(void *queue, + void *item, + uint32_t ticks, + int prio) +{ + int ret; + struct timespec timeout; + struct mq_adpt *mq_adpt = (struct mq_adpt *)queue; + + if (ticks == OSI_FUNCS_TIME_BLOCKING || ticks == 0) + { + /* Wi-Fi interrupt function will call this adapter function to send + * message to message queue, so here we should call kernel API + * instead of application API + */ + + ret = file_mq_send(&mq_adpt->mq, (const char *)item, + mq_adpt->msgsize, prio); + if (ret < 0) + { + wlerr("Failed to send message to mqueue error=%d\n", + ret); + } + } + else + { + ret = clock_gettime(CLOCK_REALTIME, &timeout); + if (ret < 0) + { + wlerr("Failed to get time\n"); + return false; + } + + if (ticks) + { + esp_update_time(&timeout, ticks); + } + + ret = file_mq_timedsend(&mq_adpt->mq, (const char *)item, + mq_adpt->msgsize, prio, &timeout); + if (ret < 0) + { + wlerr("Failed to timedsend message to mqueue error=%d\n", + ret); + } + } + + return nuttx_err_to_common_err(ret); +} + +/**************************************************************************** + * Name: xsemaphore_create_counting_adapter + * + * Description: + * Create and initialize semaphore + * + * Input Parameters: + * max - No meaning for NuttX + * init - semaphore initialization value + * + * Returned Value: + * Semaphore data pointer + * + ****************************************************************************/ + +void *xsemaphore_create_counting_adapter(uint32_t max, uint32_t init) +{ + int ret; + sem_t *sem; + int tmp; + + tmp = sizeof(sem_t); + sem = kmm_malloc(tmp); + if (!sem) + { + wlerr("Failed to alloc %d memory\n", tmp); + return NULL; + } + + ret = nxsem_init(sem, 0, init); + if (ret) + { + wlerr("Failed to initialize sem error=%d\n", ret); + kmm_free(sem); + return NULL; + } + + return sem; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: wifi_malloc + * + * Description: + * Applications allocate a block of memory + * + * Input Parameters: + * size - memory size + * + * Returned Value: + * Memory pointer + * + ****************************************************************************/ + +IRAM_ATTR void *wifi_malloc(size_t size) +{ + return malloc(size); +} + +/**************************************************************************** + * Name: wifi_realloc + * + * Description: + * Applications allocate a block of memory by old memory block + * + * Input Parameters: + * ptr - old memory pointer + * size - memory size + * + * Returned Value: + * New memory pointer + * + ****************************************************************************/ + +IRAM_ATTR void *wifi_realloc(void *ptr, size_t size) +{ + return realloc(ptr, size); +} + +/**************************************************************************** + * Name: wifi_calloc + * + * Description: + * Applications allocate some continuous blocks of memory + * + * Input Parameters: + * n - memory block number + * size - memory block size + * + * Returned Value: + * New memory pointer + * + ****************************************************************************/ + +IRAM_ATTR void *wifi_calloc(size_t n, size_t size) +{ + return calloc(n, size); +}
