You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by gu...@apache.org on 2021/10/04 18:10:43 UTC
[incubator-nuttx] branch master updated: esp32: Add initial support
to Bluetooth Low Energy
This is an automated email from the ASF dual-hosted git repository.
gustavonihei pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 867c6d0 esp32: Add initial support to Bluetooth Low Energy
867c6d0 is described below
commit 867c6d0636c105781107fc0a46a411dd69f5a607
Author: Alan C. Assis <ac...@gmail.com>
AuthorDate: Fri Sep 10 10:36:11 2021 -0300
esp32: Add initial support to Bluetooth Low Energy
Co-authored-by: saramonteiro <sa...@gmail.com>
Co-authored-by: Gustavo Henrique Nihei <gu...@gmail.com>
---
arch/xtensa/include/esp32/irq.h | 2 +-
arch/xtensa/src/esp32/Kconfig | 41 +-
arch/xtensa/src/esp32/Make.defs | 7 +-
arch/xtensa/src/esp32/esp32_allocateheap.c | 2 +-
arch/xtensa/src/esp32/esp32_ble.c | 346 +++
arch/xtensa/src/esp32/esp32_ble.h | 50 +
arch/xtensa/src/esp32/esp32_ble_adapter.c | 2953 ++++++++++++++++++++
arch/xtensa/src/esp32/esp32_ble_adapter.h | 200 ++
arch/xtensa/src/esp32/esp32_irq.c | 29 +-
arch/xtensa/src/esp32/esp32_wifi_adapter.c | 21 +-
arch/xtensa/src/esp32/esp32_wifi_adapter.h | 1 +
arch/xtensa/src/esp32/hardware/esp32_dport.h | 3 +-
boards/xtensa/esp32/common/scripts/esp32.ld | 20 +
.../xtensa/esp32/common/scripts/esp32.template.ld | 1 +
.../xtensa/esp32/common/scripts/esp32_aliases.ld | 31 +
boards/xtensa/esp32/common/scripts/esp32_rom.ld | 192 +-
.../esp32/esp32-devkitc/configs/ble/defconfig | 60 +
boards/xtensa/esp32/esp32-devkitc/src/Make.defs | 2 +-
.../xtensa/esp32/esp32-devkitc/src/esp32_bringup.c | 12 +
.../esp32/esp32-ethernet-kit/src/esp32_bringup.c | 12 +
.../esp32/esp32-wrover-kit/src/esp32_bringup.c | 12 +
.../esp32/ttgo_lora_esp32/src/esp32_bringup.c | 12 +
22 files changed, 3999 insertions(+), 10 deletions(-)
diff --git a/arch/xtensa/include/esp32/irq.h b/arch/xtensa/include/esp32/irq.h
index 66d330f..f85eccb 100644
--- a/arch/xtensa/include/esp32/irq.h
+++ b/arch/xtensa/include/esp32/irq.h
@@ -396,7 +396,7 @@
#define ESP32_NCPUINTS 32
#define ESP32_CPUINT_MAX (ESP32_NCPUINTS - 1)
-#define ESP32_CPUINT_PERIPHSET 0xdffe773f
+#define ESP32_CPUINT_PERIPHSET 0xdffe741f
#define ESP32_CPUINT_INTERNALSET 0x200188c0
/* Priority 1: 0-10, 12-13, 17-18 (15)
diff --git a/arch/xtensa/src/esp32/Kconfig b/arch/xtensa/src/esp32/Kconfig
index 204cca9..6b2e60d 100644
--- a/arch/xtensa/src/esp32/Kconfig
+++ b/arch/xtensa/src/esp32/Kconfig
@@ -509,6 +509,13 @@ config ESP32_WIRELESS
---help---
Enable Wireless support
+config ESP32_BLE
+ bool "BLE"
+ default n
+ select ESP32_WIRELESS
+ ---help---
+ Enable BLE support
+
config ESP32_I2C0
bool "I2C 0"
default n
@@ -525,11 +532,16 @@ config ESP32_AES_ACCELERATOR
endmenu # ESP32 Peripheral Selection
+menuconfig ESP32_WIFI_BT_COEXIST
+ bool "Wi-Fi and BT coexist"
+ default n
+ depends on ESP32_WIRELESS && ESP32_BLE
+
menu "Memory Configuration"
config ESP32_BT_RESERVE_DRAM
int "Reserved BT DRAM"
- default 0
+ default 65536
config ESP32_TRACEMEM_RESERVE_DRAM
int "Reserved trace memory DRAM"
@@ -1170,6 +1182,33 @@ endchoice
endmenu # ESP32_WIRELESS
+menu "BLE Configuration"
+ depends on ESP32_BLE
+
+config ESP32_BLE_PKTBUF_NUM
+ int "BLE netcard packet buffer number per netcard"
+ default 16
+
+config ESP32_BLE_TTY_NAME
+ string "BLE TTY device name"
+ default "/dev/ttyHCI0"
+ depends on UART_BTH4
+
+config ESP32_BLE_TASK_STACK_SIZE
+ int "Controller task stack size"
+ default 4096
+
+config ESP32_BLE_TASK_PRIORITY
+ int "Controller task priority"
+ default 110
+
+config ESP32_BLE_MAX_CONN
+ int "Maximum BLE simultaneous connections"
+ range 1 3
+ default 1
+
+endmenu # BLE Configuration
+
menu "Real-Time Timer"
depends on ESP32_RT_TIMER
diff --git a/arch/xtensa/src/esp32/Make.defs b/arch/xtensa/src/esp32/Make.defs
index 9ac87e3..da00928 100644
--- a/arch/xtensa/src/esp32/Make.defs
+++ b/arch/xtensa/src/esp32/Make.defs
@@ -231,7 +231,12 @@ INCLUDES += $(shell $(INCDIR) "$(CC)" $(ARCH_SRCDIR)$(DELIM)chip$(DELIM)esp-wire
CHIP_CSRCS += esp32_wlan.c esp32_wifi_utils.c esp32_wifi_adapter.c
EXTRA_LIBPATHS += -L $(ARCH_SRCDIR)$(DELIM)chip$(DELIM)esp-wireless-drivers-3rdparty$(DELIM)libs$(DELIM)esp32
-EXTRA_LIBS += -lcore -lrtc -lnet80211 -lpp -lsmartconfig -lcoexist -lespnow -lphy -lwpa_supplicant
+EXTRA_LIBS += -lcore -lrtc -lnet80211 -lpp -lsmartconfig -lespnow -lphy -lwpa_supplicant
+
+ifeq ($(CONFIG_ESP32_BLE),y)
+CHIP_CSRCS += esp32_ble_adapter.c esp32_ble.c
+EXTRA_LIBS += -lbtdm_app -lcoexist
+endif
# Due to some Wi-Fi related libraries, the option is need to avoid linking too much
# unused functions.
diff --git a/arch/xtensa/src/esp32/esp32_allocateheap.c b/arch/xtensa/src/esp32/esp32_allocateheap.c
index a43ae4e..7757512 100644
--- a/arch/xtensa/src/esp32/esp32_allocateheap.c
+++ b/arch/xtensa/src/esp32/esp32_allocateheap.c
@@ -133,7 +133,7 @@ void xtensa_add_region(void)
#endif
#endif
-#ifndef CONFIG_ESP32_QEMU_IMAGE
+#if !defined(CONFIG_ESP32_QEMU_IMAGE) && !defined(CONFIG_ESP32_BLE)
start = (void *)HEAP_REGION0_START;
size = (size_t)(HEAP_REGION0_END - HEAP_REGION0_START);
umm_addregion(start, size);
diff --git a/arch/xtensa/src/esp32/esp32_ble.c b/arch/xtensa/src/esp32/esp32_ble.c
new file mode 100644
index 0000000..e6cb85d
--- /dev/null
+++ b/arch/xtensa/src/esp32/esp32_ble.c
@@ -0,0 +1,346 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_ble.c
+ *
+ * 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 <queue.h>
+#include <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 "esp32_ble_adapter.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* BLE packet buffer max number */
+
+#define BLE_BUF_NUM CONFIG_ESP32_BLE_PKTBUF_NUM
+
+/* BLE packet buffer max size */
+
+#define BLE_BUF_SIZE 1024
+
+/* Low-priority work queue process RX/TX */
+
+#define BLE_WORK LPWORK
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct esp32_ble_priv_s
+{
+ struct bt_driver_s drv; /* NuttX BT/BLE driver data */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int esp32_ble_open(struct bt_driver_s *drv);
+static int esp32_ble_send(struct bt_driver_s *drv,
+ enum bt_buf_type_e type,
+ void *data, size_t len);
+static void esp32_ble_close(struct bt_driver_s *drv);
+
+static void esp32_ble_send_ready(void);
+static int esp32_ble_recv_cb(uint8_t *data, uint16_t len);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct esp32_ble_priv_s g_ble_priv =
+{
+ .drv =
+ {
+ .head_reserve = H4_HEADER_SIZE,
+ .open = esp32_ble_open,
+ .send = esp32_ble_send,
+ .close = esp32_ble_close
+ }
+};
+
+static esp_vhci_host_callback_t vhci_host_cb =
+{
+ .notify_host_send_available = esp32_ble_send_ready,
+ .notify_host_recv = esp32_ble_recv_cb
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_ble_send_ready
+ *
+ * Description:
+ * If the controller could send an HCI command, this function is called.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void esp32_ble_send_ready(void)
+{
+}
+
+/****************************************************************************
+ * Name: esp32_ble_recv_cb
+ *
+ * Description:
+ * BLE receive callback function when BLE hardware receives a 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 esp32_ble_recv_cb(uint8_t *data, uint16_t len)
+{
+ int ret;
+ bool valid;
+ enum bt_buf_type_e type;
+ struct esp32_ble_priv_s *priv = &g_ble_priv;
+
+ wlinfo("len = %d\n", len);
+ wlinfo("host recv pkt: ");
+ for (uint16_t i = 0; i < len; i++)
+ {
+ wlinfo("%02x\n", data[i]);
+ }
+
+ 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)
+ {
+ wlerr("Invalid H4 header \n");
+ 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: esp32_ble_send
+ *
+ * Description:
+ * ESP32 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 esp32_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 -EOVERFLOW;
+ }
+
+ 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
+ {
+ wlerr("Unknown BT packet type 0x%x\n", type);
+ return -EINVAL;
+ }
+
+ if (esp32_vhci_host_check_send_available())
+ {
+ esp32_vhci_host_send_packet(hdr, len + drv->head_reserve);
+ }
+
+ return len;
+}
+
+/****************************************************************************
+ * Name: esp32_ble_close
+ *
+ * Description:
+ * ESP32-C3 BLE close callback function for BT driver.
+ *
+ * Input Parameters:
+ * drv - BT driver pointer
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void esp32_ble_close(struct bt_driver_s *drv)
+{
+}
+
+/****************************************************************************
+ * Name: esp32_ble_open
+ *
+ * Description:
+ * ESP32-C3 BLE open callback function for BT driver.
+ *
+ * Input Parameters:
+ * drv - BT driver pointer
+ *
+ * Returned Value:
+ * OK
+ *
+ ****************************************************************************/
+
+static int esp32_ble_open(struct bt_driver_s *drv)
+{
+ return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_ble_initialize
+ *
+ * Description:
+ * Init BT controller
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * OK on success or a negated value on failure.
+ *
+ ****************************************************************************/
+
+int esp32_ble_initialize(void)
+{
+ int ret;
+
+ ret = esp32_bt_controller_init();
+ if (ret)
+ {
+ wlerr("Failed to initialize BLE ret=%d\n", ret);
+ return ERROR;
+ }
+
+ ret = esp32_bt_controller_enable(ESP_BT_MODE_BLE);
+ if (ret)
+ {
+ wlerr("Failed to Enable BLE ret=%d\n", ret);
+ return ERROR;
+ }
+
+ ret = esp32_vhci_register_callback(&vhci_host_cb);
+ if (ret)
+ {
+ wlerr("Failed to register BLE callback ret=%d\n", ret);
+ return ERROR;
+ }
+
+#if defined(CONFIG_UART_BTH4)
+ ret = uart_bth4_register(CONFIG_BT_UART_ON_DEV_NAME, &g_ble_priv.drv);
+#else
+ ret = bt_netdev_register(&g_ble_priv.drv);
+#endif
+ if (ret < 0)
+ {
+ wlerr("bt_netdev_register or uart_bth4_register error: %d\n", ret);
+ return ret;
+ }
+
+ return OK;
+}
diff --git a/arch/xtensa/src/esp32/esp32_ble.h b/arch/xtensa/src/esp32/esp32_ble.h
new file mode 100644
index 0000000..736edc5
--- /dev/null
+++ b/arch/xtensa/src/esp32/esp32_ble.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_ble.h
+ *
+ * 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_XTENSA_SRC_ESP32_ESP32_BLE_H
+#define __ARCH_XTENSA_SRC_ESP32_ESP32_BLE_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_ble_initialize
+ *
+ * Description:
+ * Init BT controller
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * success or fail
+ *
+ ****************************************************************************/
+
+int esp32_ble_initialize(void);
+
+#endif /* __ARCH_XTENSA_SRC_ESP32_ESP32_BLE_H */
diff --git a/arch/xtensa/src/esp32/esp32_ble_adapter.c b/arch/xtensa/src/esp32/esp32_ble_adapter.c
new file mode 100644
index 0000000..ad25f82
--- /dev/null
+++ b/arch/xtensa/src/esp32/esp32_ble_adapter.c
@@ -0,0 +1,2953 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_ble_adapter.c
+ *
+ * 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/config.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <debug.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <clock/clock.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/mqueue.h>
+#include <nuttx/spinlock.h>
+#include <nuttx/irq.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/kthread.h>
+#include <nuttx/wdog.h>
+#include <nuttx/wqueue.h>
+#include <nuttx/sched.h>
+#include <nuttx/signal.h>
+#include <irq/irq.h>
+
+#include "hardware/esp32_dport.h"
+#include "espidf_wifi.h"
+#include "xtensa.h"
+#include "xtensa_attr.h"
+#include "esp32_rt_timer.h"
+#include "esp32_ble_adapter.h"
+
+#ifdef CONFIG_ESP32_WIFI_BT_COEXIST
+# include "esp_coexist_internal.h"
+# include "esp_coexist_adapter.h"
+#endif
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+typedef void (*xt_handler)(void *);
+typedef void (*coex_func_cb_t)(uint32_t event, int sched_cnt);
+
+#define XTHAL_SET_INTSET(v) \
+do {\
+ int __interrupt = (int)(v);\
+ __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory");\
+} while(0)
+
+#define MSG_QUEUE_NAME_SIZE 16
+
+#define ESP_ERR_INVALID_STATE 0x103
+
+#define OSI_FUNCS_TIME_BLOCKING 0xffffffff
+#define OSI_VERSION 0x00010002
+#define OSI_MAGIC_VALUE 0xfadebead
+
+#define BTDM_ASYNC_WAKEUP_REQ_HCI 0
+#define BTDM_ASYNC_WAKEUP_REQ_COEX 1
+#define BTDM_ASYNC_WAKEUP_REQMAX 2
+
+#ifdef CONFIG_PM
+#define BTDM_MIN_TIMER_UNCERTAINTY_US (1800)
+
+/* Low Power Clock Selection */
+
+#define BTDM_LPCLK_SEL_XTAL (0)
+#define BTDM_LPCLK_SEL_XTAL32K (1)
+#define BTDM_LPCLK_SEL_RTC_SLOW (2)
+#define BTDM_LPCLK_SEL_8M (3)
+
+/* Sleep and wakeup interval control */
+
+#define BTDM_MIN_SLEEP_DURATION (24) /* Threshold of interval in half slots to allow to fall into sleep mode */
+#define BTDM_MODEM_WAKE_UP_DELAY (8) /* delay in half slots of modem wake up procedure, including re-enable PHY/RF */
+#endif
+
+#define BTDM_MODEM_SLEEP_MODE_NONE 0
+
+#define ESP_BT_CONTROLLER_CONFIG_MAGIC_VAL 0x20200622
+
+extern void btdm_controller_set_sleep_mode(uint8_t mode);
+
+#ifdef CONFIG_ESP32_WIFI_BT_COEXIST
+extern void coex_pti_v2(void);
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Number of fractional bits in values returned by rtc_clk_cal */
+
+#define RTC_CLK_CAL_FRACT 19
+
+/* BLE message queue private data */
+
+struct mq_adpt_s
+{
+ struct file mq; /* Message queue handle */
+ uint32_t msgsize; /* Message size */
+ char name[MSG_QUEUE_NAME_SIZE]; /* Message queue name */
+};
+
+/* BLE interrupt adapter private data */
+
+struct irq_adpt_s
+{
+ void (*func)(void *arg); /* Interrupt callback function */
+ void *arg; /* Interrupt private data */
+};
+
+/* BLE low power control struct */
+
+typedef struct btdm_lpcntl_s
+{
+ bool enable; /* whether low power mode is required */
+ bool lpclk_sel; /* low power clock source */
+ bool mac_bb_pd; /* whether hardware(MAC, BB) force-power-down is required during sleep */
+ bool wakeup_timer_required; /* whether system timer is needed */
+ bool no_light_sleep; /* do not allow system to enter light sleep after bluetooth is enabled */
+} btdm_lpcntl_t;
+
+/* low power control status */
+
+typedef struct btdm_lpstat_s
+{
+ bool pm_lock_released; /* whether power management lock is released */
+ bool mac_bb_pd; /* whether hardware(MAC, BB) is powered down */
+ bool phy_enabled; /* whether phy is switched on */
+ bool wakeup_timer_started; /* whether wakeup timer is started */
+} btdm_lpstat_t;
+
+/* vendor dependent signals to be posted to controller task */
+
+typedef enum
+{
+ BTDM_VND_OL_SIG_WAKEUP_TMR,
+ BTDM_VND_OL_SIG_NUM,
+} btdm_vnd_ol_sig_t;
+
+#ifdef CONFIG_PM
+/* wakeup request sources */
+
+typedef enum
+{
+ BTDM_ASYNC_WAKEUP_SRC_VHCI,
+ BTDM_ASYNC_WAKEUP_SRC_DISA,
+ BTDM_ASYNC_WAKEUP_SRC_TMR,
+ BTDM_ASYNC_WAKEUP_SRC_MAX,
+} btdm_wakeup_src_t;
+#endif
+
+typedef enum
+{
+ PERIPH_LEDC_MODULE = 0,
+ PERIPH_UART0_MODULE,
+ PERIPH_UART1_MODULE,
+ PERIPH_UART2_MODULE,
+ PERIPH_I2C0_MODULE,
+ PERIPH_I2C1_MODULE,
+ PERIPH_I2S0_MODULE,
+ PERIPH_I2S1_MODULE,
+ PERIPH_TIMG0_MODULE,
+ PERIPH_TIMG1_MODULE,
+ PERIPH_PWM0_MODULE,
+ PERIPH_PWM1_MODULE,
+ PERIPH_PWM2_MODULE,
+ PERIPH_PWM3_MODULE,
+ PERIPH_UHCI0_MODULE,
+ PERIPH_UHCI1_MODULE,
+ PERIPH_RMT_MODULE,
+ PERIPH_PCNT_MODULE,
+ PERIPH_SPI_MODULE,
+ PERIPH_HSPI_MODULE,
+ PERIPH_VSPI_MODULE,
+ PERIPH_SPI_DMA_MODULE,
+ PERIPH_SDMMC_MODULE,
+ PERIPH_SDIO_SLAVE_MODULE,
+ PERIPH_CAN_MODULE,
+ PERIPH_EMAC_MODULE,
+ PERIPH_RNG_MODULE,
+ PERIPH_WIFI_MODULE,
+ PERIPH_BT_MODULE,
+ PERIPH_WIFI_BT_COMMON_MODULE,
+ PERIPH_BT_BASEBAND_MODULE,
+ PERIPH_BT_LC_MODULE,
+ PERIPH_AES_MODULE,
+ PERIPH_SHA_MODULE,
+ PERIPH_RSA_MODULE,
+} periph_module_e;
+
+/* prototype of function to handle vendor dependent signals */
+
+typedef void (*btdm_vnd_ol_task_func_t)(void *param);
+
+/* VHCI function interface */
+
+typedef struct vhci_host_callback_s
+{
+ void (*notify_host_send_available)(void); /* callback used to notify that the host can send packet to controller */
+ int (*notify_host_recv)(uint8_t *data, uint16_t len); /* callback used to notify that the controller has a packet to send to the host */
+} vhci_host_callback_t;
+
+/* DRAM region */
+
+typedef struct btdm_dram_available_region_s
+{
+ esp_bt_mode_t mode;
+ intptr_t start;
+ intptr_t end;
+} btdm_dram_available_region_t;
+
+typedef void (*osi_intr_handler)(void);
+
+/* BLE OS function */
+
+struct osi_funcs_s
+{
+ uint32_t _version;
+ xt_handler (*_set_isr)(int n, xt_handler f, void *arg);
+ void (*_ints_on)(unsigned int mask);
+ void (*_interrupt_disable)(void);
+ void (*_interrupt_restore)(void);
+ void (*_task_yield)(void);
+ void (*_task_yield_from_isr)(void);
+ void *(*_semphr_create)(uint32_t max, uint32_t init);
+ void (*_semphr_delete)(void *semphr);
+ int32_t (*_semphr_take_from_isr)(void *semphr, void *hptw);
+ int32_t (*_semphr_give_from_isr)(void *semphr, void *hptw);
+ int32_t (*_semphr_take)(void *semphr, uint32_t block_time_ms);
+ int32_t (*_semphr_give)(void *semphr);
+ void *(*_mutex_create)(void);
+ void (*_mutex_delete)(void *mutex);
+ int32_t (*_mutex_lock)(void *mutex);
+ int32_t (*_mutex_unlock)(void *mutex);
+ void *(* _queue_create)(uint32_t queue_len, uint32_t item_size);
+ void (* _queue_delete)(void *queue);
+ int32_t (* _queue_send)(void *queue, void *item, uint32_t block_time_ms);
+ int32_t (* _queue_send_from_isr)(void *queue, void *item, void *hptw);
+ int32_t (* _queue_recv)(void *queue, void *item, uint32_t block_time_ms);
+ int32_t (* _queue_recv_from_isr)(void *queue, void *item, void *hptw);
+ int32_t (* _task_create)(void *task_func,
+ const char *name,
+ uint32_t stack_depth,
+ void *param,
+ uint32_t prio,
+ void *task_handle,
+ uint32_t core_id);
+ void (* _task_delete)(void *task_handle);
+ bool (* _is_in_isr)(void);
+ int (* _cause_sw_intr_to_core)(int core_id, int intr_no);
+ void *(* _malloc)(uint32_t size);
+ void *(* _malloc_internal)(uint32_t size);
+ void (* _free)(void *p);
+ int32_t (* _read_efuse_mac)(uint8_t mac[6]);
+ void (* _srand)(unsigned int seed);
+ int (* _rand)(void);
+ uint32_t (* _btdm_lpcycles_2_us)(uint32_t cycles);
+ uint32_t (* _btdm_us_2_lpcycles)(uint32_t us);
+ bool (* _btdm_sleep_check_duration)(uint32_t *slot_cnt);
+ void (* _btdm_sleep_enter_phase1)(uint32_t lpcycles); /* called when interrupt is disabled */
+ void (* _btdm_sleep_enter_phase2)(void);
+ void (* _btdm_sleep_exit_phase1)(void); /* called from ISR */
+ void (* _btdm_sleep_exit_phase2)(void); /* called from ISR */
+ void (* _btdm_sleep_exit_phase3)(void); /* called from task */
+ bool (* _coex_bt_wakeup_request)(void);
+ void (* _coex_bt_wakeup_request_end)(void);
+ int (* _coex_bt_request)(uint32_t event,
+ uint32_t latency,
+ uint32_t duration);
+ int (* _coex_bt_release)(uint32_t event);
+ int (* _coex_register_bt_cb)(coex_func_cb_t cb);
+ uint32_t (* _coex_bb_reset_lock)(void);
+ void (* _coex_bb_reset_unlock)(uint32_t restore);
+ int (* _coex_schm_register_btdm_callback)(void *callback);
+ void (* _coex_schm_status_bit_clear)(uint32_t type, uint32_t status);
+ void (* _coex_schm_status_bit_set)(uint32_t type, uint32_t status);
+ uint32_t (* _coex_schm_interval_get)(void);
+ uint8_t (* _coex_schm_curr_period_get)(void);
+ void *(* _coex_schm_curr_phase_get)(void);
+ int (* _coex_wifi_channel_get)(uint8_t *primary, uint8_t *secondary);
+ int (* _coex_register_wifi_channel_change_callback)(void *cb);
+ uint32_t _magic;
+};
+
+/****************************************************************************
+ * Private Function
+ ****************************************************************************/
+
+static xt_handler esp_ble_set_isr(int n, xt_handler f, void *arg);
+static void IRAM_ATTR interrupt_disable(void);
+static void IRAM_ATTR interrupt_restore(void);
+static void IRAM_ATTR task_yield_from_isr(void);
+static void *semphr_create_wrapper(uint32_t max, uint32_t init);
+static void semphr_delete_wrapper(void *semphr);
+static int IRAM_ATTR semphr_take_from_isr_wrapper(void *semphr, void *hptw);
+static int IRAM_ATTR semphr_give_from_isr_wrapper(void *semphr, void *hptw);
+static int semphr_take_wrapper(void *semphr, uint32_t block_time_ms);
+static int semphr_give_wrapper(void *semphr);
+static void *mutex_create_wrapper(void);
+static void mutex_delete_wrapper(void *mutex);
+static int mutex_lock_wrapper(void *mutex);
+static int mutex_unlock_wrapper(void *mutex);
+static int IRAM_ATTR queue_send_from_isr_wrapper(void *queue, void *item,
+ void *hptw);
+static int IRAM_ATTR queue_recv_from_isr_wrapper(void *queue, void *item,
+ void *hptw);
+static int task_create_wrapper(void *task_func, const char *name,
+ uint32_t stack_depth, void *param,
+ uint32_t prio, void *task_handle,
+ uint32_t core_id);
+static void task_delete_wrapper(void *task_handle);
+static bool IRAM_ATTR is_in_isr_wrapper(void);
+static void *malloc_wrapper(size_t size);
+static void IRAM_ATTR cause_sw_intr(void *arg);
+static int IRAM_ATTR cause_sw_intr_to_core_wrapper(int core_id, int intr_no);
+static void *malloc_internal_wrapper(size_t size);
+static int IRAM_ATTR read_mac_wrapper(uint8_t mac[6]);
+static void IRAM_ATTR srand_wrapper(unsigned int seed);
+static int IRAM_ATTR rand_wrapper(void);
+static uint32_t IRAM_ATTR btdm_lpcycles_2_us(uint32_t cycles);
+static uint32_t IRAM_ATTR btdm_us_2_lpcycles(uint32_t us);
+static void *queue_create_wrapper(uint32_t queue_len, uint32_t item_size);
+static int queue_send_wrapper(void *queue, void *item,
+ uint32_t block_time_ms);
+static int queue_recv_wrapper(void *queue, void *item,
+ uint32_t block_time_ms);
+static void queue_delete_wrapper(void *queue);
+static void esp32_ints_on(uint32_t mask);
+static int adapter_coex_register_bt_cb_wrapper(coex_func_cb_t cb);
+static int adapter_coex_schm_register_btdm_callback(void *callback);
+static int adapter_coex_register_wifi_channel_change_callback(void *cb);
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+ uint8_t *secondary);
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+ uint32_t status);
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status);
+static uint32_t adapter_coex_schm_interval_get(void);
+static uint8_t adapter_coex_schm_curr_period_get(void);
+static void *adapter_coex_schm_curr_phase_get(void);
+
+#ifdef CONFIG_PM
+static bool IRAM_ATTR btdm_sleep_check_duration(int32_t *half_slot_cnt);
+static void btdm_sleep_enter_phase1_wrapper(uint32_t lpcycles);
+static void btdm_sleep_enter_phase2_wrapper(void);
+static void btdm_sleep_exit_phase3_wrapper(void);
+#endif
+
+static bool coex_bt_wakeup_request(void);
+static void coex_bt_wakeup_request_end(void);
+static int esp_int_adpt_cb(int irq, void *context, void *arg);
+
+/****************************************************************************
+ * Extern Functions declaration and value
+ ****************************************************************************/
+
+extern int btdm_osi_funcs_register(void *osi_funcs);
+extern void btdm_controller_rom_data_init(void);
+extern void coex_bt_high_prio(void);
+
+/* Initialise and De-initialise */
+
+extern int btdm_controller_init(uint32_t config_mask,
+ esp_bt_controller_config_t *config_opts);
+extern void btdm_controller_deinit(void);
+extern int btdm_controller_enable(esp_bt_mode_t mode);
+extern void btdm_controller_disable(void);
+extern uint8_t btdm_controller_get_mode(void);
+extern const char *btdm_controller_get_compile_version(void);
+extern void btdm_rf_bb_init_phase2(void); /* shall be called after PHY/RF is enabled */
+
+/* Sleep */
+
+extern void btdm_controller_enable_sleep(bool enable);
+extern void btdm_controller_set_sleep_mode(uint8_t mode);
+extern uint8_t btdm_controller_get_sleep_mode(void);
+extern bool btdm_power_state_active(void);
+extern void btdm_wakeup_request(bool request_lock);
+extern void btdm_wakeup_request_end(void);
+
+/* Low Power Clock */
+
+extern bool btdm_lpclk_select_src(uint32_t sel);
+extern bool btdm_lpclk_set_div(uint32_t div);
+extern int btdm_hci_tl_io_event_post(int event);
+
+/* VHCI */
+
+extern bool api_vhci_host_check_send_available(void); /* Functions in bt lib */
+extern void api_vhci_host_send_packet(uint8_t * data, uint16_t len);
+extern int api_vhci_host_register_callback(const vhci_host_callback_t
+ *callback);
+
+/* TX power */
+
+extern int ble_txpwr_set(int power_type, int power_level);
+extern int ble_txpwr_get(int power_type);
+extern int bredr_txpwr_set(int min_power_level, int max_power_level);
+extern int bredr_txpwr_get(int *min_power_level, int *max_power_level);
+extern void bredr_sco_datapath_set(uint8_t data_path);
+extern void btdm_controller_scan_duplicate_list_clear(void);
+
+/* Coexistence */
+
+int coex_bt_request_wrapper(uint32_t event,
+ uint32_t latency,
+ uint32_t duration);
+int coex_bt_release_wrapper(uint32_t event);
+uint32_t coex_bb_reset_lock_wrapper(void);
+void coex_bb_reset_unlock_wrapper(uint32_t restore);
+extern void coex_ble_adv_priority_high_set(bool high);
+
+extern char _bss_start_btdm;
+extern char _bss_end_btdm;
+extern char _data_start_btdm;
+extern char _data_end_btdm;
+extern uint32_t _data_start_btdm_rom;
+extern uint32_t _data_end_btdm_rom;
+
+extern uint32_t _bt_bss_start;
+extern uint32_t _bt_bss_end;
+extern uint32_t _btdm_bss_start;
+extern uint32_t _btdm_bss_end;
+extern uint32_t _bt_data_start;
+extern uint32_t _bt_data_end;
+extern uint32_t _btdm_data_start;
+extern uint32_t _btdm_data_end;
+
+extern char _bt_tmp_bss_start;
+extern char _bt_tmp_bss_end;
+
+void intr_matrix_set(int cpu_no, uint32_t model_num, uint32_t intr_num);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Controller status */
+
+static DRAM_ATTR esp_bt_controller_status_t btdm_controller_status =
+ ESP_BT_CONTROLLER_STATUS_IDLE;
+
+/* low power control struct */
+
+static DRAM_ATTR btdm_lpcntl_t g_lp_cntl;
+
+/* low power status struct */
+
+static DRAM_ATTR btdm_lpstat_t g_lp_stat;
+
+/* measured average low power clock period in micro seconds */
+
+static DRAM_ATTR uint32_t g_btdm_lpcycle_us = 0;
+
+/* number of fractional bit for g_btdm_lpcycle_us */
+
+static DRAM_ATTR uint8_t g_btdm_lpcycle_us_frac = 0;
+
+#ifdef CONFIG_PM
+/* semaphore used for blocking VHCI API to wait for controller to wake up */
+
+static DRAM_ATTR void * g_wakeup_req_sem = NULL;
+
+/* wakeup timer */
+
+static DRAM_ATTR esp_timer_handle_t g_btdm_slp_tmr;
+#endif
+
+/* BT interrupt private data */
+
+static irqstate_t g_inter_flags;
+static uint32_t g_phy_clk_en_cnt;
+static int64_t g_phy_rf_en_ts;
+static uint8_t g_phy_access_ref;
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/* BLE OS adapter data */
+
+static struct osi_funcs_s g_osi_funcs =
+{
+ ._magic = OSI_MAGIC_VALUE,
+ ._version = OSI_VERSION,
+ ._set_isr = esp_ble_set_isr,
+ ._ints_on = esp32_ints_on,
+ ._interrupt_disable = interrupt_disable,
+ ._interrupt_restore = interrupt_restore,
+ ._task_yield = task_yield_from_isr,
+ ._task_yield_from_isr = task_yield_from_isr,
+ ._semphr_create = semphr_create_wrapper,
+ ._semphr_delete = semphr_delete_wrapper,
+ ._semphr_take_from_isr = semphr_take_from_isr_wrapper,
+ ._semphr_give_from_isr = semphr_give_from_isr_wrapper,
+ ._semphr_take = semphr_take_wrapper,
+ ._semphr_give = semphr_give_wrapper,
+ ._mutex_create = 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 = queue_delete_wrapper,
+ ._queue_send = queue_send_wrapper,
+ ._queue_send_from_isr = queue_send_from_isr_wrapper,
+ ._queue_recv = queue_recv_wrapper,
+ ._queue_recv_from_isr = queue_recv_from_isr_wrapper,
+ ._task_create = task_create_wrapper,
+ ._task_delete = task_delete_wrapper,
+ ._is_in_isr = is_in_isr_wrapper,
+ ._cause_sw_intr_to_core = cause_sw_intr_to_core_wrapper,
+ ._malloc = malloc_wrapper,
+ ._malloc_internal = malloc_internal_wrapper,
+ ._free = free,
+ ._read_efuse_mac = read_mac_wrapper,
+ ._srand = srand_wrapper,
+ ._rand = rand_wrapper,
+ ._btdm_lpcycles_2_us = btdm_lpcycles_2_us,
+ ._btdm_us_2_lpcycles = btdm_us_2_lpcycles,
+#ifdef CONFIG_PM
+ ._btdm_sleep_check_duration = btdm_sleep_check_duration,
+ ._btdm_sleep_enter_phase1 = btdm_sleep_enter_phase1_wrapper,
+ ._btdm_sleep_enter_phase2 = btdm_sleep_enter_phase2_wrapper,
+ ._btdm_sleep_exit_phase3 = btdm_sleep_exit_phase3_wrapper,
+#endif
+ ._coex_bt_wakeup_request = coex_bt_wakeup_request,
+ ._coex_bt_wakeup_request_end = coex_bt_wakeup_request_end,
+ ._coex_bt_request = coex_bt_request_wrapper,
+ ._coex_bt_release = coex_bt_release_wrapper,
+ ._coex_register_bt_cb = adapter_coex_register_bt_cb_wrapper,
+ ._coex_register_wifi_channel_change_callback =
+ adapter_coex_register_wifi_channel_change_callback,
+ ._coex_wifi_channel_get = adapter_coex_wifi_channel_get,
+ ._coex_schm_status_bit_clear = adapter_coex_schm_status_bit_clear,
+ ._coex_schm_status_bit_set = adapter_coex_schm_status_bit_set,
+ ._coex_schm_interval_get = adapter_coex_schm_interval_get,
+ ._coex_schm_curr_period_get = adapter_coex_schm_curr_period_get,
+ ._coex_schm_curr_phase_get = adapter_coex_schm_curr_phase_get,
+ ._coex_schm_register_btdm_callback =
+ adapter_coex_schm_register_btdm_callback,
+ ._coex_bb_reset_lock = coex_bb_reset_lock_wrapper,
+ ._coex_bb_reset_unlock = coex_bb_reset_unlock_wrapper,
+};
+
+/* The mode column will be modified by release function to indicate the
+ * available region
+ */
+
+static btdm_dram_available_region_t btdm_dram_available_region[] =
+{
+ /* following is .data */
+
+ {
+ ESP_BT_MODE_BTDM,
+ SOC_MEM_BT_DATA_START,
+ SOC_MEM_BT_DATA_END
+ },
+
+ /* following is memory which HW will use */
+
+ {
+ ESP_BT_MODE_BTDM,
+ SOC_MEM_BT_EM_BTDM0_START,
+ SOC_MEM_BT_EM_BTDM0_END
+ },
+ {
+ ESP_BT_MODE_BLE,
+ SOC_MEM_BT_EM_BLE_START,
+ SOC_MEM_BT_EM_BLE_END
+ },
+ {
+ ESP_BT_MODE_BTDM,
+ SOC_MEM_BT_EM_BTDM1_START,
+ SOC_MEM_BT_EM_BTDM1_END
+ },
+ {
+ ESP_BT_MODE_CLASSIC_BT,
+ SOC_MEM_BT_EM_BREDR_START,
+ SOC_MEM_BT_EM_BREDR_REAL_END
+ },
+
+ /* following is .bss */
+
+ {
+ ESP_BT_MODE_BTDM,
+ SOC_MEM_BT_BSS_START,
+ SOC_MEM_BT_BSS_END
+ },
+ {
+ ESP_BT_MODE_BTDM,
+ SOC_MEM_BT_MISC_START,
+ SOC_MEM_BT_MISC_END
+ },
+};
+
+/****************************************************************************
+ * Private Functions and Public Functions only used by libraries
+ ****************************************************************************/
+
+static int adapter_coex_register_bt_cb_wrapper(coex_func_cb_t cb)
+{
+ return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+ return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+ return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+ uint8_t *secondary)
+{
+ return -ERROR;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+ uint32_t status)
+{
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+ return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+ return OK;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: esp_errno_trans
+ *
+ * Description:
+ * Transform from nuttx error code to Wi-Fi adapter error code
+ *
+ * Input Parameters:
+ * ret - NuttX error code
+ *
+ * Returned Value:
+ * Wi-Fi adapter error code
+ *
+ ****************************************************************************/
+
+static inline int32_t esp_errno_trans(int ret)
+{
+ if (!ret)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+/****************************************************************************
+ * Name: esp_task_create_pinned_to_core
+ *
+ * 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 esp_task_create_pinned_to_core(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
+
+ DEBUGASSERT(task_handle != NULL);
+
+ pid = kthread_create(name, prio, stack_depth, entry,
+ (char * const *)param);
+ if (pid > 0)
+ {
+ if (task_handle)
+ {
+ *((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, error %d\n", pid);
+ }
+
+ return pid > 0 ? true : false;
+}
+
+/****************************************************************************
+ * Name: esp_set_isr
+ *
+ * Description:
+ * Register interrupt function
+ *
+ * Input Parameters:
+ * n - Interrupt ID
+ * f - Interrupt function
+ * arg - Function private data
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static xt_handler esp_ble_set_isr(int n, xt_handler f, void *arg)
+{
+ int ret;
+ uint32_t tmp;
+ struct irq_adpt_s *adapter;
+ int irq = n + XTENSA_IRQ_FIRSTPERIPH;
+
+ wlinfo("n=%d f=%p arg=%p irq=%d\n", n, f, arg, irq);
+
+ if (g_irqvector[irq].handler &&
+ g_irqvector[irq].handler != irq_unexpected_isr)
+ {
+ wlinfo("irq=%d has been set handler=%p\n", irq,
+ g_irqvector[irq].handler);
+ return NULL;
+ }
+
+ tmp = sizeof(struct irq_adpt_s);
+ adapter = kmm_malloc(tmp);
+ if (!adapter)
+ {
+ wlerr("Failed to alloc %d memory\n", tmp);
+ assert(0);
+ return NULL;
+ }
+
+ adapter->func = f;
+ adapter->arg = arg;
+
+ ret = irq_attach(irq, esp_int_adpt_cb, adapter);
+ if (ret)
+ {
+ wlerr("Failed to attach IRQ %d\n", irq);
+ assert(0);
+ return NULL;
+ }
+
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: esp32_ints_on
+ *
+ * Description:
+ * Enable BLE interrupt
+ *
+ * Input Parameters:
+ * mask - Mask used to indicate the bits to enable interrupt.
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void esp32_ints_on(uint32_t mask)
+{
+ uint32_t bit;
+
+ for (int i = 0; i < 32; i++)
+ {
+ bit = 1 << i;
+ if (bit & mask)
+ {
+ wlinfo("Enabled bit %d\n", i);
+ up_enable_irq(i);
+ }
+ }
+}
+
+/****************************************************************************
+ * Name: is_wifi_clk_peripheral
+ *
+ * Description:
+ * Checks if the peripheral module needs WiFi Clock.
+ *
+ * Input Parameters:
+ * periph - The peripheral module
+ *
+ * Returned Value:
+ * true if it depends on WiFi clock or false otherwise.
+ *
+ ****************************************************************************/
+
+static bool is_wifi_clk_peripheral(periph_module_e periph)
+{
+ /* A small subset of peripherals use WIFI_CLK_EN_REG and
+ * CORE_RST_EN_REG for their clock & reset registers
+ */
+
+ switch (periph)
+ {
+ case PERIPH_SDMMC_MODULE:
+ case PERIPH_SDIO_SLAVE_MODULE:
+ case PERIPH_EMAC_MODULE:
+ case PERIPH_RNG_MODULE:
+ case PERIPH_WIFI_MODULE:
+ case PERIPH_BT_MODULE:
+ case PERIPH_WIFI_BT_COMMON_MODULE:
+ case PERIPH_BT_BASEBAND_MODULE:
+ case PERIPH_BT_LC_MODULE:
+ return true;
+ default:
+ return false;
+ }
+}
+
+/****************************************************************************
+ * Name: get_clk_en_mask
+ *
+ * Description:
+ * Returns the WIFI_BT clock mask case it is BLE peripheral.
+ *
+ * Input Parameters:
+ * periph - The peripheral module
+ *
+ * Returned Value:
+ * The clock peripheral mask.
+ *
+ ****************************************************************************/
+
+static uint32_t get_clk_en_mask(periph_module_e periph)
+{
+ switch (periph)
+ {
+ case PERIPH_BT_MODULE:
+ return DPORT_WIFI_CLK_BT_EN_M;
+ default:
+ return 0;
+ }
+}
+
+/****************************************************************************
+ * Name: get_rst_en_mask
+ *
+ * Description:
+ * Returns the WIFI_BT reset mask
+ *
+ * Input Parameters:
+ * periph - The peripheral module
+ * enable - Enable/Disable
+ *
+ * Returned Value:
+ * The reset peripheral mask.
+ *
+ ****************************************************************************/
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+ return 0;
+}
+
+/****************************************************************************
+ * Name: get_clk_en_reg
+ *
+ * Description:
+ * Returns the WIFI_BT clock register
+ *
+ * Input Parameters:
+ * periph - The peripheral module
+ *
+ * Returned Value:
+ * The clock peripheral register.
+ *
+ ****************************************************************************/
+
+static uint32_t get_clk_en_reg(periph_module_e periph)
+{
+ return is_wifi_clk_peripheral(periph) ? DPORT_WIFI_CLK_EN_REG :
+ DPORT_PERIP_CLK_EN_REG;
+}
+
+/****************************************************************************
+ * Name: get_rst_en_reg
+ *
+ * Description:
+ * Returns the WIFI_BT reset register
+ *
+ * Input Parameters:
+ * periph - The peripheral module
+ *
+ * Returned Value:
+ * The reset peripheral register.
+ *
+ ****************************************************************************/
+
+static uint32_t get_rst_en_reg(periph_module_e periph)
+{
+ return is_wifi_clk_peripheral(periph) ? DPORT_CORE_RST_EN_REG :
+ DPORT_PERIP_RST_EN_REG;
+}
+
+/****************************************************************************
+ * Name: bt_periph_module_enable
+ *
+ * Description:
+ * Enable the bluetooth module
+ *
+ * Input Parameters:
+ * periph - The peripheral module
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+ modifyreg32(get_clk_en_reg(periph), 0, get_clk_en_mask(periph));
+ modifyreg32(get_rst_en_reg(periph), get_rst_en_mask(periph, true), 0);
+}
+
+/****************************************************************************
+ * Name: esp_int_adpt_cb
+ *
+ * Description:
+ * BT interrupt adapter callback function
+ *
+ * Input Parameters:
+ * arg - interrupt adapter private data
+ *
+ * Returned Value:
+ * NuttX error code
+ *
+ ****************************************************************************/
+
+static int esp_int_adpt_cb(int irq, void *context, void *arg)
+{
+ struct irq_adpt_s *adapter = (struct irq_adpt_s *)arg;
+
+ adapter->func(adapter->arg);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: interrupt_disable
+ *
+ * Description:
+ * Enter critical section by disabling interrupts and taking the spin lock
+ * if in SMP mode.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None.
+ *
+ ****************************************************************************/
+
+static void IRAM_ATTR interrupt_disable(void)
+{
+ g_inter_flags = enter_critical_section();
+}
+
+/****************************************************************************
+ * Name: interrupt_restore
+ *
+ * Description:
+ * Exit from critical section by enabling interrupts and releasing the spin
+ * lock if in SMP mode.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void IRAM_ATTR interrupt_restore(void)
+{
+ leave_critical_section(g_inter_flags);
+}
+
+/****************************************************************************
+ * Name: task_yield_from_isr
+ *
+ * Description:
+ * Do nothing in NuttX
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void IRAM_ATTR task_yield_from_isr(void)
+{
+}
+
+/****************************************************************************
+ * Name: semphr_create_wrapper
+ *
+ * Description:
+ * Create and initialize semaphore
+ *
+ * Input Parameters:
+ * max - Unused
+ * init - semaphore initialization value
+ *
+ * Returned Value:
+ * Semaphore data pointer
+ *
+ ****************************************************************************/
+
+static void *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("ERROR: Failed to alloc %d memory\n", tmp);
+ return NULL;
+ }
+
+ ret = sem_init(sem, 0, init);
+ if (ret)
+ {
+ wlerr("ERROR: Failed to initialize sem error=%d\n", ret);
+ kmm_free(sem);
+ return NULL;
+ }
+
+ return sem;
+}
+
+/****************************************************************************
+ * Name: semphr_delete_wrapper
+ *
+ * Description:
+ * Delete semaphore
+ *
+ * Input Parameters:
+ * semphr - Semaphore data pointer
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void semphr_delete_wrapper(void *semphr)
+{
+ sem_t *sem = (sem_t *)semphr;
+ sem_destroy(sem);
+ kmm_free(sem);
+}
+
+/****************************************************************************
+ * Name: 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 int IRAM_ATTR semphr_take_from_isr_wrapper(void *semphr, void *hptw)
+{
+ return esp_errno_trans(sem_trywait(semphr));
+}
+
+/****************************************************************************
+ * Name: semphr_give_from_isr_wrapper
+ *
+ * Description:
+ * Post semaphore
+ *
+ * Input Parameters:
+ * semphr - Semaphore data pointer
+ *
+ * Returned Value:
+ * True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int IRAM_ATTR semphr_give_from_isr_wrapper(void *semphr, void *hptw)
+{
+ return semphr_give_wrapper(semphr);
+}
+
+/****************************************************************************
+ * Name: esp_update_time
+ *
+ * Description:
+ * Transform ticks to time and add this time to timespec value
+ *
+ * Input Parameters:
+ * ticks - System ticks
+ *
+ * Output Parameters:
+ * timespec - Input timespec data pointer
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void esp_update_time(struct timespec *timespec, uint32_t ticks)
+{
+ uint32_t tmp;
+
+ tmp = TICK2SEC(ticks);
+ timespec->tv_sec += tmp;
+
+ ticks -= SEC2TICK(tmp);
+ tmp = TICK2NSEC(ticks);
+
+ timespec->tv_nsec += tmp;
+}
+
+/****************************************************************************
+ * Name: semphr_take_wrapper
+ *
+ * Description:
+ * Wait semaphore within a certain period of time
+ *
+ * Input Parameters:
+ * semphr - Semaphore data pointer
+ * block_time_ms - Wait time
+ *
+ * Returned Value:
+ * True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int semphr_take_wrapper(void *semphr, uint32_t block_time_ms)
+{
+ int ret;
+ struct timespec timeout;
+ sem_t *sem = (sem_t *)semphr;
+
+ if (block_time_ms == OSI_FUNCS_TIME_BLOCKING)
+ {
+ ret = sem_wait(sem);
+ if (ret)
+ {
+ wlerr("Failed to wait sem %d\n", ret);
+ }
+ }
+ else
+ {
+ ret = clock_gettime(CLOCK_REALTIME, &timeout);
+ if (ret < 0)
+ {
+ wlerr("Failed to get time\n");
+ return esp_errno_trans(ret);
+ }
+
+ if (block_time_ms)
+ {
+ esp_update_time(&timeout, MSEC2TICK(block_time_ms));
+ }
+
+ ret = sem_timedwait(sem, &timeout);
+ }
+
+ return esp_errno_trans(ret);
+}
+
+/****************************************************************************
+ * Name: semphr_give_wrapper
+ *
+ * Description:
+ * Post semaphore
+ *
+ * Input Parameters:
+ * semphr - Semaphore data pointer
+ *
+ * Returned Value:
+ * True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int semphr_give_wrapper(void *semphr)
+{
+ int ret;
+ sem_t *sem = (sem_t *)semphr;
+
+ ret = sem_post(sem);
+ if (ret)
+ {
+ wlerr("Failed to post sem error=%d\n", ret);
+ }
+
+ return esp_errno_trans(ret);
+}
+
+/****************************************************************************
+ * 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);
+ DEBUGASSERT(mutex);
+
+ 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:
+ * None
+ *
+ * Returned Value:
+ * Mutex data pointer
+ *
+ ****************************************************************************/
+
+static void mutex_delete_wrapper(void *mutex)
+{
+ pthread_mutex_destroy(mutex);
+ kmm_free(mutex);
+}
+
+/****************************************************************************
+ * Name: mutex_lock_wrapper
+ *
+ * Description:
+ * Lock mutex
+ *
+ * Input Parameters:
+ * mutex_data - mutex data pointer
+ *
+ * Returned Value:
+ * True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int mutex_lock_wrapper(void *mutex)
+{
+ int ret;
+
+ ret = pthread_mutex_lock(mutex);
+ if (ret)
+ {
+ wlerr("Failed to lock mutex error=%d\n", ret);
+ }
+
+ return esp_errno_trans(ret);
+}
+
+/****************************************************************************
+ * Name: mutex_unlock_wrapper
+ *
+ * Description:
+ * Unlock mutex
+ *
+ * Input Parameters:
+ * mutex_data - mutex data pointer
+ *
+ * Returned Value:
+ * True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int mutex_unlock_wrapper(void *mutex)
+{
+ int ret;
+
+ ret = pthread_mutex_unlock(mutex);
+ if (ret)
+ {
+ wlerr("Failed to unlock mutex error=%d\n", ret);
+ }
+
+ return esp_errno_trans(ret);
+}
+
+/****************************************************************************
+ * Name: esp_queue_send_generic
+ *
+ * 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 esp_queue_send_generic(void *queue, void *item,
+ uint32_t ticks, int prio)
+{
+ int ret;
+ struct timespec timeout;
+ struct mq_adpt_s *mq_adpt = (struct mq_adpt_s *)queue;
+
+ if (ticks == OSI_FUNCS_TIME_BLOCKING || ticks == 0)
+ {
+ /**
+ * BLE 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 %d\n", ret);
+ return esp_errno_trans(ret);
+ }
+
+ 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 esp_errno_trans(ret);
+}
+
+/****************************************************************************
+ * 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 int IRAM_ATTR queue_send_from_isr_wrapper(void *queue,
+ void *item,
+ void *hptw)
+{
+ *((int *)hptw) = false;
+ return esp_queue_send_generic(queue, item, 0, 0);
+}
+
+/****************************************************************************
+ * Name: queue_recv_from_isr_wrapper
+ *
+ * Description:
+ * Receive message from queue 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 int IRAM_ATTR queue_recv_from_isr_wrapper(void *queue,
+ void *item,
+ void *hptw)
+{
+ return 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 int task_create_wrapper(void *task_func, const char *name,
+ uint32_t stack_depth, void *param,
+ uint32_t prio, void *task_handle,
+ uint32_t core_id)
+{
+ return esp_task_create_pinned_to_core(task_func, name,
+ stack_depth, param,
+ prio, task_handle, UINT32_MAX);
+}
+
+/****************************************************************************
+ * 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: is_in_isr_wrapper
+ *
+ * Description:
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static bool IRAM_ATTR is_in_isr_wrapper(void)
+{
+ return false;
+}
+
+/****************************************************************************
+ * Name: malloc_wrapper
+ *
+ * Description:
+ * Malloc buffer
+ *
+ * Input Parameters:
+ * size - buffer size
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+ void * p = NULL;
+
+ p = kmm_malloc(size);
+ DEBUGASSERT(p);
+
+ return p;
+}
+
+/****************************************************************************
+ * Name: cause_sw_intr
+ *
+ * Description:
+ * Set a software interrupt bit
+ *
+ * Input Parameters:
+ * arg - number of the bit as void pointer
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void IRAM_ATTR cause_sw_intr(void *arg)
+{
+ /* just convert void * to int, because the width is the same */
+
+ uint32_t intr_no = (uint32_t)arg;
+ XTHAL_SET_INTSET((1 << intr_no));
+}
+
+/****************************************************************************
+ * Name: cause_sw_intr_to_core_wrapper
+ *
+ * Description:
+ * Just a wrapper to cause_sw_intr
+ *
+ * Input Parameters:
+ * core_id - ID of the CPU core, not used.
+ * intr_no - Number of the software interrupt
+ *
+ * Returned Value:
+ * Always return OK.
+ *
+ ****************************************************************************/
+
+static int IRAM_ATTR cause_sw_intr_to_core_wrapper(int core_id, int intr_no)
+{
+ cause_sw_intr((void *)intr_no);
+ return ESP_OK;
+}
+
+/****************************************************************************
+ * Name: malloc_internal_wrapper
+ *
+ * Description:
+ * Malloc buffer in DRAM
+ *
+ * Input Parameters:
+ * szie - buffer size
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void *malloc_internal_wrapper(size_t size)
+{
+ void * p = NULL;
+
+ p = kmm_malloc(size);
+ DEBUGASSERT(p);
+
+ return p;
+}
+
+/****************************************************************************
+ * Name: read_mac_wrapper
+ *
+ * Description:
+ * Get Mac Address
+ *
+ * Input Parameters:
+ * mac - mac address
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static int IRAM_ATTR read_mac_wrapper(uint8_t mac[6])
+{
+ return esp_read_mac(mac, ESP_MAC_BT);
+}
+
+/****************************************************************************
+ * Name: srand_wrapper
+ *
+ * Description:
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void IRAM_ATTR srand_wrapper(unsigned int seed)
+{
+ /* empty function */
+}
+
+/****************************************************************************
+ * Name: rand_wrapper
+ *
+ * Description:
+ * Get random value.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * Random value
+ *
+ ****************************************************************************/
+
+static int IRAM_ATTR rand_wrapper(void)
+{
+ return random();
+}
+
+/****************************************************************************
+ * Name: btdm_lpcycles_2_us
+ *
+ * Description:
+ * Converts a number of low power clock cycles into a duration in us
+ *
+ * Input Parameters:
+ * cycles - number of CPU cycles
+ *
+ * Returned Value:
+ * us - value equivalent to the CPU cycles
+ *
+ ****************************************************************************/
+
+static uint32_t IRAM_ATTR btdm_lpcycles_2_us(uint32_t cycles)
+{
+ uint64_t us = (uint64_t)g_btdm_lpcycle_us * cycles;
+ us = (us + (1 << (g_btdm_lpcycle_us_frac - 1))) >> g_btdm_lpcycle_us_frac;
+ return (uint32_t)us;
+}
+
+/****************************************************************************
+ * Name: btdm_us_2_lpcycles
+ *
+ * Description:
+ * Converts a duration in half us into a number of low power clock cycles.
+ *
+ * Input Parameters:
+ * us
+ *
+ * Returned Value:
+ * cycles
+ *
+ ****************************************************************************/
+
+static uint32_t IRAM_ATTR btdm_us_2_lpcycles(uint32_t us)
+{
+ uint64_t cycles;
+ cycles = ((uint64_t)(us) << g_btdm_lpcycle_us_frac) / g_btdm_lpcycle_us;
+ return (uint32_t)cycles;
+}
+
+#ifdef CONFIG_PM
+/****************************************************************************
+ * Name: btdm_sleep_exit_phase0
+ *
+ * Description:
+ * Acquire PM lock and stop esp timer.
+ *
+ * Input Parameters:
+ * param - wakeup event
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void IRAM_ATTR btdm_sleep_exit_phase0(void *param)
+{
+ int event = (int) param;
+
+ DEBUGASSERT(g_lp_cntl.enable == true);
+
+ if (g_lp_stat.pm_lock_released)
+ {
+ esp32_pm_lockacquire();
+ g_lp_stat.pm_lock_released = false;
+ }
+
+ if (event == BTDM_ASYNC_WAKEUP_SRC_VHCI ||
+ event == BTDM_ASYNC_WAKEUP_SRC_DISA)
+ {
+ btdm_wakeup_request();
+ }
+
+ if (g_lp_cntl.wakeup_timer_required && g_lp_stat.wakeup_timer_started)
+ {
+ esp_timer_stop(g_btdm_slp_tmr);
+ g_lp_stat.wakeup_timer_started = false;
+ }
+
+ if (event == BTDM_ASYNC_WAKEUP_SRC_VHCI ||
+ event == BTDM_ASYNC_WAKEUP_SRC_DISA)
+ {
+ semphr_give_wrapper(g_wakeup_req_sem);
+ }
+}
+
+/****************************************************************************
+ * Name: btdm_slp_tmr_callback
+ *
+ * Description:
+ * ESP BLE sleep callback function.
+ *
+ * Input Parameters:
+ * arg - Unused
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void IRAM_ATTR btdm_slp_tmr_callback(void *arg)
+{
+ btdm_vnd_offload_post(BTDM_VND_OL_SIG_WAKEUP_TMR,
+ (void *)BTDM_ASYNC_WAKEUP_SRC_TMR);
+}
+
+/****************************************************************************
+ * Name: btdm_sleep_check_duration
+ *
+ * Description:
+ * Wake up in advance considering the delay in enabling PHY/RF.
+ *
+ * Input Parameters:
+ * half_slot_cnt - half slots to allow to fall into modem sleep
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static bool IRAM_ATTR btdm_sleep_check_duration(int32_t *half_slot_cnt)
+{
+ if (*half_slot_cnt < BTDM_MIN_SLEEP_DURATION)
+ {
+ return false;
+ }
+
+ *half_slot_cnt -= BTDM_MODEM_WAKE_UP_DELAY;
+ return true;
+}
+
+/****************************************************************************
+ * Name: btdm_sleep_enter_phase1_wrapper
+ *
+ * Description:
+ * ESP32 BLE lightsleep callback function.
+ *
+ * Input Parameters:
+ * lpcycles - light sleep cycles
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void btdm_sleep_enter_phase1_wrapper(uint32_t lpcycles)
+{
+ uint32_t us_to_sleep;
+ uint32_t uncertainty;
+
+ if (g_lp_cntl.wakeup_timer_required == false)
+ {
+ return;
+ }
+
+ /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+ us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+ DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+ uncertainty = (us_to_sleep >> 11);
+
+ if (uncertainty < BTDM_MIN_TIMER_UNCERTAINTY_US)
+ {
+ uncertainty = BTDM_MIN_TIMER_UNCERTAINTY_US;
+ }
+
+ DEBUGASSERT(g_lp_stat.wakeup_timer_started == false);
+
+ if (esp_timer_start_once(g_btdm_slp_tmr,
+ us_to_sleep - uncertainty) == ESP_OK)
+ {
+ g_lp_stat.wakeup_timer_started = true;
+ }
+ else
+ {
+ wlerr("timer start failed");
+ DEBUGASSERT(0);
+ }
+}
+
+/****************************************************************************
+ * Name: btdm_sleep_enter_phase2_wrapper
+ *
+ * Description:
+ * ESP32 BLE lightsleep callback function.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void btdm_sleep_enter_phase2_wrapper(void)
+{
+ if (btdm_controller_get_sleep_mode() == ESP_BT_SLEEP_MODE_1)
+ {
+ if (g_lp_stat.phy_enabled)
+ {
+ bt_phy_disable();
+ g_lp_stat.phy_enabled = false;
+ }
+ else
+ {
+ DEBUGASSERT(0);
+ }
+
+ if (g_lp_stat.pm_lock_released == false)
+ {
+ esp32_pm_lockrelease();
+ g_lp_stat.pm_lock_released = true;
+ }
+ }
+}
+
+/****************************************************************************
+ * Name: btdm_sleep_exit_phase3_wrapper
+ *
+ * Description:
+ * ESP32 BLE lightsleep callback function..
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void btdm_sleep_exit_phase3_wrapper(void)
+{
+ if (g_lp_stat.pm_lock_released)
+ {
+ esp32_pm_lockacquire();
+ g_lp_stat.pm_lock_released = false;
+ }
+
+ if (btdm_sleep_clock_sync())
+ {
+ wlerr("sleep eco state err\n");
+ DEBUGASSERT(0);
+ }
+
+ if (btdm_controller_get_sleep_mode() == ESP_BT_SLEEP_MODE_1)
+ {
+ if (g_lp_stat.phy_enabled == false)
+ {
+ bt_phy_enable();
+ g_lp_stat.phy_enabled = true;
+ }
+ }
+
+ if (g_lp_cntl.wakeup_timer_required && g_lp_stat.wakeup_timer_started)
+ {
+ esp_timer_stop(g_btdm_slp_tmr);
+ g_lp_stat.wakeup_timer_started = false;
+ }
+}
+#endif
+
+/****************************************************************************
+ * Name: btdm_controller_mem_init
+ *
+ * Description:
+ * Initialize BT controller to allocate task and other resource.
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void btdm_controller_mem_init(void)
+{
+ int btdm_dram_regions;
+
+ /* initialise .data section */
+
+ memcpy(&_data_start_btdm, (void *)_data_start_btdm_rom,
+ &_data_end_btdm - &_data_start_btdm);
+
+ wlinfo(".data initialise [0x%08x] <== [0x%08x]\n",
+ (uint32_t)&_data_start_btdm, _data_start_btdm_rom);
+
+ /* initial em, .bss section */
+
+ btdm_dram_regions = sizeof(btdm_dram_available_region)
+ / sizeof(btdm_dram_available_region_t);
+
+ for (int i = 1; i < btdm_dram_regions; i++)
+ {
+ if (btdm_dram_available_region[i].mode != ESP_BT_MODE_IDLE)
+ {
+ memset((void *)btdm_dram_available_region[i].start, 0x0,
+ btdm_dram_available_region[i].end - \
+ btdm_dram_available_region[i].start);
+ wlinfo(".bss initialise [0x%08x] - [0x%08x]\n",
+ btdm_dram_available_region[i].start,
+ btdm_dram_available_region[i].end);
+ }
+ }
+}
+
+/****************************************************************************
+ * Name: phy_printf_ble
+ *
+ * Description:
+ * Output format string and its arguments
+ *
+ * Input Parameters:
+ * format - format string
+ *
+ * Returned Value:
+ * 0
+ *
+ ****************************************************************************/
+
+int phy_printf_ble(const char *format, ...)
+{
+#ifdef CONFIG_DEBUG_WIRELESS_INFO
+ va_list arg;
+
+ va_start(arg, format);
+ vsyslog(LOG_INFO, format, arg);
+ va_end(arg);
+#endif
+
+ return 0;
+}
+
+int coexist_printf(const char *format, ...)
+{
+#ifdef CONFIG_DEBUG_WIRELESS_INFO
+ va_list arg;
+
+ va_start(arg, format);
+ vsyslog(LOG_INFO, format, arg);
+ va_end(arg);
+#endif
+
+ return 0;
+}
+
+/****************************************************************************
+ * Name: bt_phy_enable_clock
+ *
+ * Description:
+ * Enable BT clock.
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void bt_phy_enable_clock(void)
+{
+ irqstate_t flags;
+
+ flags = enter_critical_section();
+
+ if (g_phy_clk_en_cnt == 0)
+ {
+ modifyreg32(DPORT_WIFI_CLK_EN_REG, 0,
+ DPORT_WIFI_CLK_WIFI_BT_COMMON_M);
+ }
+
+ g_phy_clk_en_cnt++;
+
+ leave_critical_section(flags);
+}
+
+/****************************************************************************
+ * Name: bt_phy_disable_clock
+ *
+ * Description:
+ * Disable BT clock.
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void bt_phy_disable_clock(void)
+{
+ irqstate_t flags;
+
+ flags = enter_critical_section();
+
+ if (g_phy_clk_en_cnt)
+ {
+ g_phy_clk_en_cnt--;
+ if (!g_phy_clk_en_cnt)
+ {
+ modifyreg32(DPORT_WIFI_CLK_EN_REG,
+ DPORT_WIFI_CLK_WIFI_BT_COMMON_M,
+ 0);
+ }
+ }
+
+ leave_critical_section(flags);
+}
+
+/****************************************************************************
+ * Name: bt_phy_disable
+ *
+ * Description:
+ * Disable BT phy.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void bt_phy_disable(void)
+{
+ irqstate_t flags;
+ flags = enter_critical_section();
+
+ g_phy_access_ref--;
+
+ if (g_phy_access_ref == 0)
+ {
+ /* Disable PHY and RF. */
+
+ phy_close_rf();
+
+ /* Disable Wi-Fi/BT common peripheral clock.
+ * Do not disable clock for hardware RNG.
+ */
+
+ bt_phy_disable_clock();
+ }
+
+ leave_critical_section(flags);
+}
+
+/****************************************************************************
+ * Name: bt_phy_enable
+ *
+ * Description:
+ * Enable BT phy.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void bt_phy_enable(void)
+{
+ irqstate_t flags;
+ esp_phy_calibration_data_t *cal_data;
+
+ cal_data = kmm_zalloc(sizeof(esp_phy_calibration_data_t));
+ if (cal_data == NULL)
+ {
+ wlerr("Failed to kmm_zalloc");
+ DEBUGASSERT(0);
+ }
+
+ flags = enter_critical_section();
+
+ if (g_phy_access_ref == 0)
+ {
+ /* Update time stamp */
+
+ g_phy_rf_en_ts = (int64_t)rt_timer_time_us();
+
+ bt_phy_enable_clock();
+ phy_set_wifi_mode_only(0);
+ register_chipv7_phy(&phy_init_data, cal_data, PHY_RF_CAL_NONE);
+#ifdef CONFIG_ESP32_WIFI_BT_COEXIST
+ coex_pti_v2();
+#endif
+ }
+
+ g_phy_access_ref++;
+ leave_critical_section(flags);
+ kmm_free(cal_data);
+}
+
+/****************************************************************************
+ * Name: queue_create_wrapper
+ *
+ * Description:
+ * Create message queue
+ *
+ * Input Parameters:
+ * queue_len - queue message number
+ * item_size - message size
+ *
+ * Returned Value:
+ * Message queue data pointer
+ *
+ ****************************************************************************/
+
+static void *queue_create_wrapper(uint32_t queue_len, uint32_t item_size)
+{
+ struct mq_attr attr;
+ struct mq_adpt_s *mq_adpt;
+ int ret;
+
+ mq_adpt = kmm_malloc(sizeof(struct mq_adpt_s));
+ DEBUGASSERT(mq_adpt);
+
+ 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 %d \n", ret);
+ kmm_free(mq_adpt);
+ return NULL;
+ }
+
+ mq_adpt->msgsize = item_size;
+ return (void *)mq_adpt;
+}
+
+/****************************************************************************
+ * Name: queue_send_wrapper
+ *
+ * Description:
+ * Generic send message to queue within a certain period of time
+ *
+ * Input Parameters:
+ * queue - Message queue data pointer
+ * item - Item to be sent.
+ * block_time_ms - Wait time
+ *
+ * Returned Value:uint32_t
+ * True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int queue_send_wrapper(void *queue, void *item,
+ uint32_t block_time_ms)
+{
+ return esp_queue_send_generic(queue, item, block_time_ms, 0);
+}
+
+/****************************************************************************
+ * 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
+ * block_time_ms - Wait time
+ *
+ * Returned Value:
+ * True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int queue_recv_wrapper(void *queue, void *item,
+ uint32_t block_time_ms)
+{
+ ssize_t ret;
+ struct timespec timeout;
+ unsigned int prio;
+ struct mq_adpt_s *mq_adpt = (struct mq_adpt_s *)queue;
+
+ if (block_time_ms == 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 %d\n", ret);
+ return false;
+ }
+
+ if (block_time_ms)
+ {
+ esp_update_time(&timeout, MSEC2TICK(block_time_ms));
+ }
+
+ 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: queue_delete_wrapper
+ *
+ * Description:
+ * Delete message queue
+ *
+ * Input Parameters:
+ * queue - Message queue data pointer
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void queue_delete_wrapper(void *queue)
+{
+ struct mq_adpt_s *mq_adpt = (struct mq_adpt_s *)queue;
+
+ file_mq_close(&mq_adpt->mq);
+ file_mq_unlink(mq_adpt->name);
+ kmm_free(mq_adpt);
+}
+
+/****************************************************************************
+ * Name: btdm_config_mask_load
+ *
+ * Description:
+ * Create a mask with all ESP32 BLE supported features
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * The uint32_t mask
+ *
+ ****************************************************************************/
+
+static uint32_t btdm_config_mask_load(void)
+{
+ uint32_t mask = 0x0;
+
+#ifdef CONFIG_UART_BTH4
+ mask |= BTDM_CFG_HCI_UART;
+#endif
+
+#ifdef CONFIG_ESP32_BLE_RUN_APP_CPU
+ mask |= BTDM_CFG_CONTROLLER_RUN_APP_CPU;
+#endif
+
+#ifdef CONFIG_ESP32_BLE_FULL_SCAN
+ mask |= BTDM_CFG_BLE_FULL_SCAN_SUPPORTED;
+#endif
+
+ mask |= BTDM_CFG_SCAN_DUPLICATE_OPTIONS;
+
+ mask |= BTDM_CFG_SEND_ADV_RESERVED_SIZE;
+
+ return mask;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_bt_controller_init
+ *
+ * Description:
+ * Init BT controller.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+int esp32_bt_controller_init(void)
+{
+ esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
+ esp_bt_controller_config_t *cfg = &bt_cfg;
+ int err;
+ uint32_t btdm_cfg_mask = 0;
+
+ if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE)
+ {
+ wlerr("Invalid controller status");
+ return -ERROR;
+ }
+
+ if (btdm_osi_funcs_register(&g_osi_funcs) != 0)
+ {
+ wlinfo("Error, probably invalid OSI Functions\n");
+ return -EINVAL;
+ }
+
+ wlinfo("BT controller compile version [%s]\n",
+ btdm_controller_get_compile_version());
+
+ /* If all the bt available memory was already released,
+ * cannot initialize bluetooth controller
+ */
+
+ if (btdm_dram_available_region[0].mode == ESP_BT_MODE_IDLE)
+ {
+ wlerr("Error, bt available memory was released\n");
+ return ESP_ERR_INVALID_STATE;
+ }
+
+ if (cfg == NULL)
+ {
+ wlerr("%s %d\n", __func__, __LINE__);
+ return -EINVAL;
+ }
+
+ cfg->controller_task_stack_size = CONFIG_ESP32_BLE_TASK_STACK_SIZE;
+ cfg->controller_task_prio = CONFIG_ESP32_BLE_TASK_PRIORITY;
+
+ cfg->bt_max_sync_conn = CONFIG_ESP32_BLE_MAX_CONN;
+ cfg->magic = ESP_BT_CONTROLLER_CONFIG_MAGIC_VAL;
+
+ if (((cfg->mode & ESP_BT_MODE_BLE) && (cfg->ble_max_conn <= 0 ||
+ cfg->ble_max_conn > BTDM_CONTROLLER_BLE_MAX_CONN_LIMIT)) ||
+ ((cfg->mode & ESP_BT_MODE_CLASSIC_BT) && (cfg->bt_max_acl_conn <= 0 ||
+ cfg->bt_max_acl_conn > BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_LIMIT)) ||
+ ((cfg->mode & ESP_BT_MODE_CLASSIC_BT) &&
+ (cfg->bt_max_sync_conn > BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_LIMIT)))
+ {
+ wlerr("%s %d\n", __func__, __LINE__);
+ return -EINVAL;
+ }
+
+ wlinfo("BT controller compile version [%s]",
+ btdm_controller_get_compile_version());
+
+ btdm_controller_mem_init();
+
+ wlinfo("Memory initialized!\n");
+
+ bt_periph_module_enable(PERIPH_BT_MODULE);
+
+ /* set default sleep clock cycle and its fractional bits */
+
+ g_btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
+ g_btdm_lpcycle_us = 2 << (g_btdm_lpcycle_us_frac);
+
+ btdm_controller_set_sleep_mode(BTDM_MODEM_SLEEP_MODE_NONE);
+
+ btdm_cfg_mask = btdm_config_mask_load();
+
+ wlinfo("Going to call btdm_controller_init\n");
+
+ if (btdm_controller_init(btdm_cfg_mask, cfg) != 0)
+ {
+ wlerr("Failed to initialize the BLE Controller\n");
+ err = -ENOMEM;
+ goto error;
+ }
+
+ wlinfo("The btdm_controller_init was initialized\n");
+
+#ifdef CONFIG_BTDM_COEX_BLE_ADV_HIGH_PRIORITY
+ coex_ble_adv_priority_high_set(true);
+#else
+ coex_ble_adv_priority_high_set(false);
+#endif
+
+ btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
+
+ return OK;
+
+error:
+ return err;
+}
+
+/****************************************************************************
+ * Name: esp32_bt_controller_deinit
+ *
+ * Description:
+ * Deinit BT controller.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+int esp32_bt_controller_deinit(void)
+{
+ if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_INITED)
+ {
+ return -ERROR;
+ }
+
+ btdm_controller_deinit();
+
+ if (g_lp_stat.phy_enabled)
+ {
+ bt_phy_disable();
+ g_lp_stat.phy_enabled = false;
+ }
+ else
+ {
+ DEBUGASSERT(0);
+ }
+
+#ifdef CONFIG_PM
+ /* deinit low power control resources */
+
+ g_lp_stat.pm_lock_released = false;
+
+ if (g_lp_cntl.wakeup_timer_required)
+ {
+ if (g_lp_stat.wakeup_timer_started)
+ {
+ esp_timer_stop(g_btdm_slp_tmr);
+ }
+
+ g_lp_stat.wakeup_timer_started = false;
+ esp_timer_delete(g_btdm_slp_tmr);
+ g_btdm_slp_tmr = NULL;
+ }
+
+ if (g_lp_cntl.enable)
+ {
+ btdm_vnd_offload_task_deregister(BTDM_VND_OL_SIG_WAKEUP_TMR);
+ semphr_delete_wrapper(g_wakeup_req_sem);
+ g_wakeup_req_sem = NULL;
+ }
+#endif
+
+ btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE;
+ g_btdm_lpcycle_us = 0;
+ return 0;
+}
+
+/****************************************************************************
+ * Name: esp32_bt_controller_disable
+ *
+ * Description:
+ * Disable BT controller.
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+int esp32_bt_controller_disable(void)
+{
+ if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED)
+ {
+ return -ERROR;
+ }
+
+ while (!btdm_power_state_active())
+ {
+ usleep(1000); /* wait */
+ }
+
+ btdm_controller_disable();
+
+#ifdef CONFIG_ESP32_WIFI_BT_COEXIST
+ coex_disable();
+#endif
+
+ btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
+
+#ifdef CONFIG_PM
+ /* disable low power mode */
+
+ if (g_lp_stat.pm_lock_released == false)
+ {
+ esp32_pm_lockrelease();
+ g_lp_stat.pm_lock_released = true;
+ }
+ else
+ {
+ DEBUGASSERT(0);
+ }
+#endif
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_bt_controller_enable
+ *
+ * Description:
+ * Enable BT controller.
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+int esp32_bt_controller_enable(esp_bt_mode_t mode)
+{
+ int ret = 0;
+
+ if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_INITED)
+ {
+ return -ERROR;
+ }
+
+ if (mode != btdm_controller_get_mode())
+ {
+ wlerr("invalid mode %d, controller support mode is %d",
+ mode, btdm_controller_get_mode());
+ return -1;
+ }
+
+ bt_phy_enable();
+
+ btdm_rf_bb_init_phase2();
+
+ coex_bt_high_prio();
+
+#ifdef CONFIG_ESP32_WIFI_BT_COEXIST
+ coex_enable();
+#endif
+
+#ifdef CONFIG_PM
+ /* enable low power mode */
+
+ esp32_pm_lockacquire();
+ g_lp_stat.pm_lock_released = false;
+
+ if (g_lp_cntl.enable)
+ {
+ btdm_controller_enable_sleep(true);
+ }
+#endif
+
+ if (g_lp_cntl.enable)
+ {
+ btdm_controller_enable_sleep(true);
+ }
+
+ if (btdm_controller_enable(mode) != 0)
+ {
+ ret = -1;
+ goto error;
+ }
+
+ btdm_controller_status = ESP_BT_CONTROLLER_STATUS_ENABLED;
+
+ return ret;
+
+error:
+
+ /* disable low power mode */
+
+ btdm_controller_enable_sleep(false);
+
+#ifdef CONFIG_PM
+ if (g_lp_stat.pm_lock_released == false)
+ {
+ esp32_pm_lockrelease();
+ g_lp_stat.pm_lock_released = true;
+ }
+#endif
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: esp32_bt_controller_get_status
+ *
+ * Description:
+ * Returns the status of the BT Controller
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * The current status (type esp_bt_controller_status_t)
+ *
+ ****************************************************************************/
+
+esp_bt_controller_status_t esp32_bt_controller_get_status(void)
+{
+ return btdm_controller_status;
+}
+
+/****************************************************************************
+ * Name: async_wakeup_request
+ *
+ * Description:
+ * Request the BLE Controller to wakeup
+ *
+ * Input Parameters:
+ * event - the event that triggered the wakeup
+ *
+ * Returned Value:
+ * true if request lock is needed, false otherwise
+ *
+ ****************************************************************************/
+
+static bool async_wakeup_request(int event)
+{
+ bool request_lock = false;
+ bool do_wakeup_request = false;
+
+ switch (event)
+ {
+ case BTDM_ASYNC_WAKEUP_REQ_HCI:
+ request_lock = true;
+ break;
+ case BTDM_ASYNC_WAKEUP_REQ_COEX:
+ request_lock = false;
+ break;
+ default:
+ return false;
+ }
+
+ if (!btdm_power_state_active())
+ {
+ do_wakeup_request = true;
+ btdm_wakeup_request(request_lock);
+ }
+
+ return do_wakeup_request;
+}
+
+/****************************************************************************
+ * Name: async_wakeup_request_end
+ *
+ * Description:
+ * Finish a wakeup request
+ *
+ * Input Parameters:
+ * event - the event that triggered the wakeup
+ *
+ * Returned Value:
+ * true if request lock is needed, false otherwise
+ *
+ ****************************************************************************/
+
+static void async_wakeup_request_end(int event)
+{
+ bool request_lock = false;
+
+ switch (event)
+ {
+ case BTDM_ASYNC_WAKEUP_REQ_HCI:
+ request_lock = true;
+ break;
+ case BTDM_ASYNC_WAKEUP_REQ_COEX:
+ request_lock = false;
+ break;
+ default:
+ return;
+ }
+
+ if (request_lock)
+ {
+ btdm_wakeup_request_end();
+ }
+
+ return;
+}
+
+/****************************************************************************
+ * Name: coex_bt_wakeup_request
+ *
+ * Description:
+ * Request a WiFi/BLE Coex wakeup request
+ *
+ * Input Parameters:
+ * none
+ *
+ * Returned Value:
+ * true if request lock is needed, false otherwise
+ *
+ ****************************************************************************/
+
+static bool coex_bt_wakeup_request(void)
+{
+ return async_wakeup_request(BTDM_ASYNC_WAKEUP_REQ_COEX);
+}
+
+/****************************************************************************
+ * Name: coex_bt_wakeup_request_end
+ *
+ * Description:
+ * Finish WiFi/BLE Coex wakeup request
+ *
+ * Input Parameters:
+ * none
+ *
+ * Returned Value:
+ * none
+ *
+ ****************************************************************************/
+
+static void coex_bt_wakeup_request_end(void)
+{
+ async_wakeup_request_end(BTDM_ASYNC_WAKEUP_REQ_COEX);
+ return;
+}
+
+/****************************************************************************
+ * Name: esp32_vhci_host_check_send_available
+ *
+ * Description:
+ * Check if the host can send packet to controller or not.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * bool - true or false
+ *
+ ****************************************************************************/
+
+bool esp32_vhci_host_check_send_available(void)
+{
+ if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED)
+ {
+ return false;
+ }
+
+ return api_vhci_host_check_send_available();
+}
+
+/****************************************************************************
+ * Name: esp32_vhci_host_send_packet
+ *
+ * Description:
+ * Host send packet to controller.
+ * Input Parameters:
+ * data - the packet pointer
+ * len - the packet length
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void esp32_vhci_host_send_packet(uint8_t *data, uint16_t len)
+{
+ wlinfo("len: %d\n", len);
+ for (uint16_t i = 0; i < len; i++)
+ {
+ wlinfo("%02x\n", data[i]);
+ }
+
+ if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED)
+ {
+ return;
+ }
+
+ api_vhci_host_send_packet(data, len);
+}
+
+/****************************************************************************
+ * Name: esp32_vhci_register_callback
+ *
+ * Description:
+ * Register the vhci reference callback.
+ *
+ * Input Parameters:
+ * callback - struct defined by vhci_host_callback structure.
+ *
+ * Returned Value:
+ * status - success or fail
+ *
+ ****************************************************************************/
+
+int esp32_vhci_register_callback(const esp_vhci_host_callback_t *callback)
+{
+ int ret = -ERROR;
+ if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED)
+ {
+ return ret;
+ }
+
+ ret = api_vhci_host_register_callback(
+ (const vhci_host_callback_t *)callback) == 0 ? 0 : -1;
+ return ret;
+}
+
+int coex_bt_request_wrapper(uint32_t event,
+ uint32_t latency,
+ uint32_t duration)
+{
+ return 0;
+}
+
+int coex_bt_release_wrapper(uint32_t event)
+{
+ return 0;
+}
+
+uint32_t coex_bb_reset_lock_wrapper(void)
+{
+ return 0;
+}
+
+void coex_bb_reset_unlock_wrapper(uint32_t restore)
+{
+ return;
+}
+
diff --git a/arch/xtensa/src/esp32/esp32_ble_adapter.h b/arch/xtensa/src/esp32/esp32_ble_adapter.h
new file mode 100644
index 0000000..447b111
--- /dev/null
+++ b/arch/xtensa/src/esp32/esp32_ble_adapter.h
@@ -0,0 +1,200 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_ble_adapter.h
+ *
+ * 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_XTENSA_SRC_ESP32_ESP32_BLE_ADAPTER_H
+#define __ARCH_XTENSA_SRC_ESP32_ESP32_BLE_ADAPTER_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "esp_bt.h"
+
+/* Bluetooth system and controller config */
+
+#define BTDM_CFG_BT_DATA_RELEASE (1 << 0)
+#define BTDM_CFG_HCI_UART (1 << 1)
+#define BTDM_CFG_CONTROLLER_RUN_APP_CPU (1 << 2)
+#define BTDM_CFG_SCAN_DUPLICATE_OPTIONS (1 << 3)
+#define BTDM_CFG_SEND_ADV_RESERVED_SIZE (1 << 4)
+#define BTDM_CFG_BLE_FULL_SCAN_SUPPORTED (1 << 5)
+
+/* Bluetooth memory regions */
+
+#define SOC_MEM_BT_DATA_START 0x3ffae6e0
+#define SOC_MEM_BT_DATA_END 0x3ffaff10
+#define SOC_MEM_BT_EM_START 0x3ffb0000
+#define SOC_MEM_BT_EM_END 0x3ffb7cd8
+#define SOC_MEM_BT_EM_BTDM0_START 0x3ffb0000
+#define SOC_MEM_BT_EM_BTDM0_END 0x3ffb09a8
+#define SOC_MEM_BT_EM_BLE_START 0x3ffb09a8
+#define SOC_MEM_BT_EM_BLE_END 0x3ffb1ddc
+#define SOC_MEM_BT_EM_BTDM1_START 0x3ffb1ddc
+#define SOC_MEM_BT_EM_BTDM1_END 0x3ffb2730
+#define SOC_MEM_BT_EM_BREDR_START 0x3ffb2730
+#define SOC_MEM_BT_EM_BREDR_NO_SYNC_END 0x3ffb6388 /* Not calculate with synchronize connection support */
+#define SOC_MEM_BT_EM_BREDR_END 0x3ffb7cd8 /* Calculate with synchronize connection support */
+#define SOC_MEM_BT_EM_SYNC0_START 0x3ffb6388
+#define SOC_MEM_BT_EM_SYNC0_END 0x3ffb6bf8
+#define SOC_MEM_BT_EM_SYNC1_START 0x3ffb6bf8
+#define SOC_MEM_BT_EM_SYNC1_END 0x3ffb7468
+#define SOC_MEM_BT_EM_SYNC2_START 0x3ffb7468
+#define SOC_MEM_BT_EM_SYNC2_END 0x3ffb7cd8
+#define SOC_MEM_BT_BSS_START 0x3ffb8000
+#define SOC_MEM_BT_BSS_END 0x3ffb9a20
+#define SOC_MEM_BT_MISC_START 0x3ffbdb28
+#define SOC_MEM_BT_MISC_END 0x3ffbdb5c
+
+#define SOC_MEM_BT_EM_PER_SYNC_SIZE 0x870
+
+#define SOC_MEM_BT_EM_BREDR_REAL_END (SOC_MEM_BT_EM_BREDR_NO_SYNC_END + CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF * SOC_MEM_BT_EM_PER_SYNC_SIZE)
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32_bt_controller_init
+ *
+ * Description:
+ * Init BT controller.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+int esp32_bt_controller_init(void);
+
+/****************************************************************************
+ * Name: esp32_bt_controller_deinit
+ *
+ * Description:
+ * Deinit BT controller.
+ * Input Parameters:
+ * cfg - Initial configuration of BT controller.
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+int esp32_bt_controller_deinit(void);
+
+/****************************************************************************
+ * Name: esp32_bt_controller_enable
+ *
+ * Description:
+ * disable BT controller.
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+int esp32_bt_controller_enable(esp_bt_mode_t mode);
+
+/****************************************************************************
+ * Name: esp32_bt_controller_disable
+ *
+ * Description:
+ * disable BT controller.
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+int esp32_bt_controller_disable(void);
+
+/****************************************************************************
+ * Name: esp32_bt_controller_enable
+ *
+ * Description:
+ * Enable BT controller.
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+esp_bt_controller_status_t esp32_bt_controller_get_status(void);
+
+/****************************************************************************
+ * Name: esp32_vhci_host_check_send_available
+ *
+ * Description:
+ * used for check actively if the host can send packet to controller or not.
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * bool - true or false
+ *
+ ****************************************************************************/
+
+bool esp32_vhci_host_check_send_available(void);
+
+/****************************************************************************
+ * Name: esp32_vhci_host_send_packet
+ *
+ * Description:
+ * host send packet to controller.
+ * Input Parameters:
+ * data - the packet point
+ * len - the packet length
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void esp32_vhci_host_send_packet(uint8_t *data, uint16_t len);
+
+/****************************************************************************
+ * Name: esp32_vhci_register_callback
+ *
+ * Description:
+ * register the vhci reference callback.
+ * Input Parameters:
+ * callback - struct defined by vhci_host_callback structure.
+ *
+ * Returned Value:
+ * status - success or fail
+ *
+ ****************************************************************************/
+
+int esp32_vhci_register_callback(
+ const esp_vhci_host_callback_t *callback);
+
+#endif /* __ARCH_XTENSA_SRC_ESP32_ESP32_BLE_ADAPTER_H */
diff --git a/arch/xtensa/src/esp32/esp32_irq.c b/arch/xtensa/src/esp32/esp32_irq.c
index bb3f137..1b36d1f 100644
--- a/arch/xtensa/src/esp32/esp32_irq.c
+++ b/arch/xtensa/src/esp32/esp32_irq.c
@@ -102,6 +102,14 @@
# define ESP32_WIRELESS_RESERVE_INT 0
#endif
+#ifdef CONFIG_ESP32_BLE
+# define ESP32_BLE_RESERVE_INT ((1 << ESP32_PERIPH_BT_BB_NMI) | \
+ (1 << ESP32_PERIPH_RWBLE_IRQ) | \
+ (1 << ESP32_PERIPH_RWBT_NMI))
+#else
+# define ESP32_BLE_RESERVE_INT 0
+#endif
+
/****************************************************************************
* Public Data
****************************************************************************/
@@ -171,10 +179,12 @@ static uint32_t g_intenable[1];
*/
static uint32_t g_cpu0_freeints = ESP32_CPUINT_PERIPHSET &
- (~ESP32_WIRELESS_RESERVE_INT);
+ (~ESP32_WIRELESS_RESERVE_INT &
+ ~ESP32_BLE_RESERVE_INT);
#ifdef CONFIG_SMP
static uint32_t g_cpu1_freeints = ESP32_CPUINT_PERIPHSET &
- (~ESP32_WIRELESS_RESERVE_INT);
+ (~ESP32_WIRELESS_RESERVE_INT &
+ ~ESP32_BLE_RESERVE_INT);
#endif
/* Bitsets for each interrupt priority 1-5 */
@@ -464,6 +474,12 @@ void up_irqinitialize(void)
g_irqmap[ESP32_IRQ_MAC] = IRQ_MKMAP(0, ESP32_CPUINT_MAC);
#endif
+#ifdef CONFIG_ESP32_BLE
+ g_irqmap[ESP32_IRQ_BT_BB_NMI] = IRQ_MKMAP(0, ESP32_PERIPH_BT_BB_NMI);
+ g_irqmap[ESP32_IRQ_RWBT_NMI] = IRQ_MKMAP(0, ESP32_PERIPH_RWBT_NMI);
+ g_irqmap[ESP32_IRQ_RWBLE_IRQ] = IRQ_MKMAP(0, ESP32_PERIPH_RWBLE_IRQ);
+#endif
+
/* Initialize CPU interrupts */
esp32_cpuint_initialize();
@@ -743,6 +759,15 @@ int esp32_cpuint_initialize(void)
xtensa_enable_cpuint(&g_intenable[0], 1 << ESP32_CPUINT_MAC);
#endif
+#ifdef CONFIG_ESP32_BLE
+ intmap[ESP32_PERIPH_BT_BB_NMI] = CPUINT_ASSIGN(ESP32_IRQ_BT_BB_NMI);
+ intmap[ESP32_PERIPH_RWBT_NMI] = CPUINT_ASSIGN(ESP32_IRQ_RWBT_NMI);
+ intmap[ESP32_PERIPH_RWBLE_IRQ] = CPUINT_ASSIGN(ESP32_IRQ_RWBLE_IRQ);
+ xtensa_enable_cpuint(&g_intenable[0], 1 << ESP32_PERIPH_BT_BB_NMI);
+ xtensa_enable_cpuint(&g_intenable[0], 1 << ESP32_PERIPH_RWBT_NMI);
+ xtensa_enable_cpuint(&g_intenable[0], 1 << ESP32_PERIPH_RWBLE_IRQ);
+#endif
+
return OK;
}
diff --git a/arch/xtensa/src/esp32/esp32_wifi_adapter.c b/arch/xtensa/src/esp32/esp32_wifi_adapter.c
index f49ac7b..07c124d 100644
--- a/arch/xtensa/src/esp32/esp32_wifi_adapter.c
+++ b/arch/xtensa/src/esp32/esp32_wifi_adapter.c
@@ -349,6 +349,8 @@ static void *wifi_coex_get_schm_curr_phase(void);
static int wifi_coex_set_schm_curr_phase_idx(int idx);
static int wifi_coex_get_schm_curr_phase_idx(void);
+extern void coex_bt_high_prio(void);
+
/****************************************************************************
* Public Functions declaration
****************************************************************************/
@@ -2495,6 +2497,7 @@ static void wifi_phy_enable(void)
esp_phy_enable_clock();
phy_set_wifi_mode_only(0);
register_chipv7_phy(&phy_init_data, cal_data, PHY_RF_CAL_NONE);
+ coex_bt_high_prio();
}
g_phy_access_ref++;
@@ -2603,7 +2606,7 @@ int32_t esp_read_mac(uint8_t *mac, esp_mac_type_t type)
uint8_t crc;
int i;
- if (type > ESP_MAC_WIFI_SOFTAP)
+ if (type > ESP_MAC_BT)
{
wlerr("Input type is error=%d\n", type);
return -1;
@@ -2645,6 +2648,22 @@ int32_t esp_read_mac(uint8_t *mac, esp_mac_type_t type)
}
}
+ if (type == ESP_MAC_BT)
+ {
+ tmp = mac[0];
+ for (i = 0; i < 64; i++)
+ {
+ mac[0] = tmp | 0x02;
+ mac[0] ^= i << 2;
+
+ if (mac[0] != tmp)
+ {
+ break;
+ }
+ }
+ mac[5] += 1;
+ }
+
return 0;
}
diff --git a/arch/xtensa/src/esp32/esp32_wifi_adapter.h b/arch/xtensa/src/esp32/esp32_wifi_adapter.h
index dbe595b..ce039e9 100644
--- a/arch/xtensa/src/esp32/esp32_wifi_adapter.h
+++ b/arch/xtensa/src/esp32/esp32_wifi_adapter.h
@@ -26,6 +26,7 @@
****************************************************************************/
#include <nuttx/config.h>
+#include <nuttx/wireless/wireless.h>
#include <sys/types.h>
diff --git a/arch/xtensa/src/esp32/hardware/esp32_dport.h b/arch/xtensa/src/esp32/hardware/esp32_dport.h
index 6aa829d..a545535 100644
--- a/arch/xtensa/src/esp32/hardware/esp32_dport.h
+++ b/arch/xtensa/src/esp32/hardware/esp32_dport.h
@@ -1184,7 +1184,8 @@
#define DPORT_SLAVE_SPI_MASK_PRO_V 0x1
#define DPORT_SLAVE_SPI_MASK_PRO_S 0
-#define DPORT_WIFI_CLK_EN_REG (DR_REG_DPORT_BASE + 0x0CC)
+#define DPORT_WIFI_CLK_EN_REG (DR_REG_DPORT_BASE + 0x0cc)
+#define DPORT_CORE_RST_EN_REG (DR_REG_DPORT_BASE + 0x0d0)
#define DPORT_EMAC_CLK_EN (BIT(14))
diff --git a/boards/xtensa/esp32/common/scripts/esp32.ld b/boards/xtensa/esp32/common/scripts/esp32.ld
index cce43ee..f047908 100644
--- a/boards/xtensa/esp32/common/scripts/esp32.ld
+++ b/boards/xtensa/esp32/common/scripts/esp32.ld
@@ -93,6 +93,17 @@ SECTIONS
. = ALIGN (8);
_sbss = ABSOLUTE(.);
+ _bss_start = ABSOLUTE(.);
+ *(.ext_ram.bss*)
+ _bt_bss_start = ABSOLUTE(.);
+ *libbt.a:(.bss .bss.* COMMON)
+ . = ALIGN (4);
+ _bt_bss_end = ABSOLUTE(.);
+ _btdm_bss_start = ABSOLUTE(.);
+ *libbtdm_app.a:(.bss .bss.* COMMON)
+ . = ALIGN (4);
+ _btdm_bss_end = ABSOLUTE(.);
+ . = ALIGN (8);
*(.dynsbss)
*(.sbss)
*(.sbss.*)
@@ -109,6 +120,7 @@ SECTIONS
*(COMMON)
*libarch.a:esp32_spiflash.*(.bss .bss.* COMMON)
. = ALIGN(8);
+ _bss_end = ABSOLUTE(.);
_ebss = ABSOLUTE(.);
} >dram0_0_seg
@@ -126,6 +138,14 @@ SECTIONS
/* .data initialized on power-up in ROMed configurations. */
_sdata = ABSOLUTE(.);
+ _bt_data_start = ABSOLUTE(.);
+ *libbt.a:(.data .data.*)
+ . = ALIGN (4);
+ _bt_data_end = ABSOLUTE(.);
+ _btdm_data_start = ABSOLUTE(.);
+ *libbtdm_app.a:(.data .data.*)
+ . = ALIGN (4);
+ _btdm_data_end = ABSOLUTE(.);
KEEP (*(.data))
KEEP (*(.data.*))
KEEP (*(.gnu.linkonce.d.*))
diff --git a/boards/xtensa/esp32/common/scripts/esp32.template.ld b/boards/xtensa/esp32/common/scripts/esp32.template.ld
index 7632e2a..36aa1ed 100644
--- a/boards/xtensa/esp32/common/scripts/esp32.template.ld
+++ b/boards/xtensa/esp32/common/scripts/esp32.template.ld
@@ -34,6 +34,7 @@
****************************************************************************/
#include <nuttx/config.h>
+#include "esp32_aliases.ld"
#ifdef CONFIG_ESP32_FLASH_2M
# define FLASH_SIZE 0x200000
diff --git a/boards/xtensa/esp32/common/scripts/esp32_aliases.ld b/boards/xtensa/esp32/common/scripts/esp32_aliases.ld
new file mode 100644
index 0000000..6ffa84d
--- /dev/null
+++ b/boards/xtensa/esp32/common/scripts/esp32_aliases.ld
@@ -0,0 +1,31 @@
+/****************************************************************************
+ * boards/xtensa/esp32/common/scripts/esp32_aliases.ld
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+/* Lower-case aliases for symbols not compliant to nxstyle */
+
+/* Bluetooth needs symbol alias, to be removed after IDF rename it */
+
+#ifdef CONFIG_ESP32_BLE
+ api_vhci_host_check_send_available = API_vhci_host_check_send_available;
+ api_vhci_host_send_packet = API_vhci_host_send_packet;
+ api_vhci_host_register_callback = API_vhci_host_register_callback;
+#endif
diff --git a/boards/xtensa/esp32/common/scripts/esp32_rom.ld b/boards/xtensa/esp32/common/scripts/esp32_rom.ld
index a6755fa..c56f28d 100644
--- a/boards/xtensa/esp32/common/scripts/esp32_rom.ld
+++ b/boards/xtensa/esp32/common/scripts/esp32_rom.ld
@@ -181,11 +181,11 @@ PROVIDE ( _sbss_btdm = 0x3ffb8000);
PROVIDE ( _ebss_btdm = 0x3ffbff70);
PROVIDE ( _daylight = 0x3ffae0a4 );
PROVIDE ( dbg_default_handler = 0x3ff97218 );
+PROVIDE ( dbg_default_state = 0x3ff97220 );
PROVIDE ( dbg_state = 0x3ffb8d5d );
PROVIDE ( DebugE256PublicKey_x = 0x3ff97428 );
PROVIDE ( DebugE256PublicKey_y = 0x3ff97408 );
PROVIDE ( DebugE256SecretKey = 0x3ff973e8 );
-PROVIDE ( _DebugExceptionVector = 0x40000280 );
PROVIDE ( debug_timer = 0x3ffe042c );
PROVIDE ( debug_timerfn = 0x3ffe0430 );
PROVIDE ( dh_group14_generator = 0x3ff9ac60 );
@@ -373,6 +373,7 @@ PROVIDE ( hci_cmd_desc_tab_testing = 0x3ff97a98 );
PROVIDE ( hci_cmd_desc_tab_vs = 0x3ff97714 );
PROVIDE ( hci_command_handler = 0x4004c928 );
PROVIDE ( hci_env = 0x3ffb9350 );
+PROVIDE ( rwip_env = 0x3ffb8bcc );
PROVIDE ( hci_evt_dbg_desc_tab = 0x3ff9750c );
PROVIDE ( hci_evt_desc_tab = 0x3ff9751c );
PROVIDE ( hci_evt_le_desc_tab = 0x3ff974b4 );
@@ -406,6 +407,8 @@ PROVIDE ( __itoa = 0x40056678 );
PROVIDE ( jd_decomp = 0x400613e8 );
PROVIDE ( jd_prepare = 0x40060fa8 );
PROVIDE ( ke_env = 0x3ffb93cc );
+PROVIDE ( ke_handler_search = 0x4001a430 );
+PROVIDE ( ke_task_env = 0x3ffb81d4 );
PROVIDE ( _KernelExceptionVector = 0x40000300 );
PROVIDE ( _kill_r = 0x4000bd10 );
PROVIDE ( labs = 0x40056370 );
@@ -449,9 +452,18 @@ PROVIDE ( llc_state = 0x3ffb96f8 );
PROVIDE ( lldesc_build_chain = 0x4000a850 );
PROVIDE ( lldesc_num2link = 0x4000a948 );
PROVIDE ( lldesc_set_owner = 0x4000a974 );
+PROVIDE ( lld_evt_deferred_elt_push = 0x400466b4 );
+PROVIDE ( lld_evt_deferred_elt_pop = 0x400466dc );
+PROVIDE ( lld_evt_winsize_change = 0x40046730 );
+PROVIDE ( lld_evt_rxwin_compute = 0x400467c8 );
+PROVIDE ( lld_evt_slave_time_compute = 0x40046818 );
PROVIDE ( lld_evt_env = 0x3ffb9704 );
+PROVIDE ( lld_evt_elt_wait_get = 0x400468e4 );
+PROVIDE ( lld_evt_get_next_free_slot = 0x4004692c );
PROVIDE ( lld_pdu_adv_pk_desc_tab = 0x3ff98c70 );
PROVIDE ( lld_pdu_llcp_pk_desc_tab = 0x3ff98b68 );
+PROVIDE ( lld_pdu_tx_flush_list = 0x4004a760 );
+PROVIDE ( lld_pdu_pack = 0x4004ab14 );
PROVIDE ( LLM_AA_CT1 = 0x3ff98d8a );
PROVIDE ( LLM_AA_CT2 = 0x3ff98d88 );
PROVIDE ( llm_default_handler = 0x3ff98d80 );
@@ -581,6 +593,9 @@ PROVIDE ( r_E1 = 0x400108e8 );
PROVIDE ( r_E21 = 0x40010968 );
PROVIDE ( r_E22 = 0x400109b4 );
PROVIDE ( r_E3 = 0x40010a58 );
+PROVIDE ( lm_n192_mod_mul = 0x40011dc0 );
+PROVIDE ( lm_n192_mod_add = 0x40011e9c );
+PROVIDE ( lm_n192_mod_sub = 0x40011eec );
PROVIDE ( r_ea_alarm_clear = 0x40015ab4 );
PROVIDE ( r_ea_alarm_set = 0x40015a10 );
PROVIDE ( read = 0x400017dc );
@@ -598,6 +613,8 @@ PROVIDE ( r_ea_interval_insert = 0x4001557c );
PROVIDE ( r_ea_interval_remove = 0x40015590 );
PROVIDE ( realloc = 0x4000becc );
PROVIDE ( _realloc_r = 0x4000bbe0 );
+PROVIDE ( ea_conflict_check = 0x40014e9c );
+PROVIDE ( ea_prog_timer = 0x40014f88 );
PROVIDE ( r_ea_offset_req = 0x40015748 );
PROVIDE ( r_ea_sleep_check = 0x40015928 );
PROVIDE ( r_ea_sw_isr = 0x40015724 );
@@ -609,6 +626,7 @@ PROVIDE ( r_ecc_gen_new_public_key = 0x400170c0 );
PROVIDE ( r_ecc_gen_new_secret_key = 0x400170e4 );
PROVIDE ( r_ecc_get_debug_Keys = 0x40017224 );
PROVIDE ( r_ecc_init = 0x40016dbc );
+PROVIDE ( ecc_point_multiplication_uint8_256 = 0x40016804 );
PROVIDE ( RecvBuff = 0x3ffe009c );
PROVIDE ( recv_packet = 0x40009424 );
PROVIDE ( r_em_buf_init = 0x4001729c );
@@ -910,6 +928,118 @@ PROVIDE ( r_lc_util_get_offset_clke = 0x4002f538 );
PROVIDE ( r_lc_util_get_offset_clkn = 0x4002f51c );
PROVIDE ( r_lc_util_set_loc_trans_coll = 0x4002f500 );
PROVIDE ( r_lc_version = 0x40020a30 );
+PROVIDE ( lc_set_encap_pdu_data_p192 = 0x4002e4c8 );
+PROVIDE ( lc_set_encap_pdu_data_p256 = 0x4002e454 );
+PROVIDE ( lm_get_auth_method = 0x40023420 );
+PROVIDE ( lmp_accepted_ext_handler = 0x40027290 );
+PROVIDE ( lmp_not_accepted_ext_handler = 0x40029c54 );
+PROVIDE ( lmp_clk_adj_handler = 0x40027468 );
+PROVIDE ( lmp_clk_adj_ack_handler = 0x400274f4 );
+PROVIDE ( lm_get_auth_method = 0x40023420 );
+PROVIDE ( lmp_accepted_ext_handler = 0x40027290 );
+PROVIDE ( lmp_not_accepted_ext_handler = 0x40029c54 );
+PROVIDE ( lmp_clk_adj_handler = 0x40027468 );
+PROVIDE ( lmp_clk_adj_ack_handler = 0x400274f4 );
+PROVIDE ( lmp_clk_adj_req_handler = 0x4002751c );
+PROVIDE ( lmp_feats_res_ext_handler = 0x4002cac4 );
+PROVIDE ( lmp_feats_req_ext_handler = 0x4002ccb0 );
+PROVIDE ( lmp_pkt_type_tbl_req_handler = 0x40027574 );
+PROVIDE ( lmp_esco_link_req_handler = 0x40027610 );
+PROVIDE ( lmp_rmv_esco_link_req_handler = 0x400276e8 );
+PROVIDE ( lmp_ch_class_req_handler = 0x40027730 );
+PROVIDE ( lmp_ch_class_handler = 0x4002ca18 );
+PROVIDE ( lmp_ssr_req_handler = 0x4002780c );
+PROVIDE ( lmp_ssr_res_handler = 0x40027900 );
+PROVIDE ( lmp_pause_enc_aes_req_handler = 0x400279a4 );
+PROVIDE ( lmp_pause_enc_req_handler = 0x4002df90 );
+PROVIDE ( lmp_resume_enc_req_handler = 0x4002e084 );
+PROVIDE ( lmp_num_comparison_fail_handler = 0x40027a74 );
+PROVIDE ( lmp_passkey_fail_handler = 0x40027aec );
+PROVIDE ( lmp_keypress_notif_handler = 0x4002c5c8 );
+PROVIDE ( lmp_pwr_ctrl_req_handler = 0x400263bc );
+PROVIDE ( lmp_pwr_ctrl_res_handler = 0x40026480 );
+PROVIDE ( lmp_auto_rate_handler = 0x40026548 );
+PROVIDE ( lmp_pref_rate_handler = 0x4002657c );
+PROVIDE ( lmp_name_req_handler = 0x40025050 );
+PROVIDE ( lmp_name_res_handler = 0x400250bc );
+PROVIDE ( lmp_not_accepted_handler = 0x400251d0 );
+PROVIDE ( lmp_accepted_handler = 0x4002e894 );
+PROVIDE ( lmp_clk_off_req_handler = 0x40025a44 );
+PROVIDE ( lmp_clk_off_res_handler = 0x40025ab8 );
+PROVIDE ( lmp_detach_handler = 0x40025b74 );
+PROVIDE ( lmp_tempkey_handler = 0x4002b6b0 );
+PROVIDE ( lmp_temprand_handler = 0x4002b74c );
+PROVIDE ( lmp_sres_handler = 0x4002b840 );
+PROVIDE ( lmp_aurand_handler = 0x4002bda0 );
+PROVIDE ( lmp_unitkey_handler = 0x4002c13c );
+PROVIDE ( lmp_combkey_handler = 0x4002c234 );
+PROVIDE ( lmp_inrand_handler = 0x4002c414 );
+PROVIDE ( lmp_oob_fail_handler = 0x40027b84 );
+PROVIDE ( lmp_ping_req_handler = 0x40027c08 );
+PROVIDE ( lmp_ping_res_handler = 0x40027c5c );
+PROVIDE ( lmp_enc_mode_req_handler = 0x40025c60 );
+PROVIDE ( lmp_enc_key_size_req_handler = 0x40025e54 );
+PROVIDE ( lmp_switch_req_handler = 0x40025f84 );
+PROVIDE ( lmp_start_enc_req_handler = 0x4002e124 );
+PROVIDE ( lmp_stop_enc_req_handler = 0x4002de30 );
+PROVIDE ( lmp_sniff_req_handler = 0x400260c8 );
+PROVIDE ( lmp_unsniff_req_handler = 0x400261e0 );
+PROVIDE ( lmp_incr_pwr_req_handler = 0x4002629c );
+PROVIDE ( lmp_decr_pwr_req_handler = 0x400262f8 );
+PROVIDE ( lmp_max_pwr_handler = 0x40026354 );
+PROVIDE ( lmp_min_pwr_handler = 0x40026388 );
+PROVIDE ( lmp_ver_req_handler = 0x400265f0 );
+PROVIDE ( lmp_ver_res_handler = 0x40026670 );
+PROVIDE ( lmp_qos_handler = 0x40026790 );
+PROVIDE ( lmp_qos_req_handler = 0x40026844 );
+PROVIDE ( lmp_sco_link_req_handler = 0x40026930 );
+PROVIDE ( lmp_rmv_sco_link_req_handler = 0x40026a10 );
+PROVIDE ( lmp_max_slot_handler = 0x40026a54 );
+PROVIDE ( lmp_max_slot_req_handler = 0x40026aac );
+PROVIDE ( lmp_timing_accu_req_handler = 0x40026b54 );
+PROVIDE ( lmp_timing_accu_res_handler = 0x40026bcc );
+PROVIDE ( lmp_setup_cmp_handler = 0x40026c84 );
+PROVIDE ( lmp_feats_res_handler = 0x4002b548 );
+PROVIDE ( lmp_feats_req_handler = 0x4002b620 );
+PROVIDE ( lmp_host_con_req_handler = 0x4002b3d8 );
+PROVIDE ( lmp_use_semi_perm_key_handler = 0x4002b4c4 );
+PROVIDE ( lmp_slot_off_handler = 0x40026cc8 );
+PROVIDE ( lmp_page_mode_req_handler = 0x40026d0c );
+PROVIDE ( lmp_page_scan_mode_req_handler = 0x40026d4c );
+PROVIDE ( lmp_supv_to_handler = 0x40026d94 );
+PROVIDE ( lmp_test_activate_handler = 0x40026e7c );
+PROVIDE ( lmp_test_ctrl_handler = 0x40026ee4 );
+PROVIDE ( lmp_enc_key_size_mask_req_handler = 0x40027038 );
+PROVIDE ( lmp_enc_key_size_mask_res_handler = 0x400270a4 );
+PROVIDE ( lmp_set_afh_handler = 0x4002b2e4 );
+PROVIDE ( lmp_encaps_hdr_handler = 0x40027120 );
+PROVIDE ( lmp_encaps_payl_handler = 0x4002e590 );
+PROVIDE ( lmp_sp_nb_handler = 0x4002acf0 );
+PROVIDE ( lmp_sp_cfm_handler = 0x4002b170 );
+PROVIDE ( lmp_dhkey_chk_handler = 0x4002ab48 );
+PROVIDE ( lmp_pause_enc_aes_req_handler = 0x400279a4 );
+PROVIDE ( lmp_io_cap_res_handler = 0x4002c670 );
+PROVIDE ( lmp_io_cap_req_handler = 0x4002c7a4 );
+PROVIDE ( lc_cmd_cmp_bd_addr_send = 0x4002cec4 );
+PROVIDE ( ld_acl_tx_packet_type_select = 0x4002fb40 );
+PROVIDE ( ld_acl_sched = 0x40033268 );
+PROVIDE ( ld_acl_sniff_sched = 0x4003340c );
+PROVIDE ( ld_acl_rx = 0x4003274c );
+PROVIDE ( ld_acl_tx = 0x4002ffdc );
+PROVIDE ( ld_acl_rx_sync = 0x4002fbec );
+PROVIDE ( ld_acl_rx_sync2 = 0x4002fd8c );
+PROVIDE ( ld_acl_rx_no_sync = 0x4002fe78 );
+PROVIDE ( ld_acl_clk_isr = 0x40030cf8 );
+PROVIDE ( ld_acl_rsw_frm_cbk = 0x40033bb0 );
+PROVIDE ( ld_sco_modify = 0x40031778 );
+PROVIDE ( lm_cmd_cmp_send = 0x40051838 );
+PROVIDE ( ld_sco_frm_cbk = 0x400349dc );
+PROVIDE ( ld_acl_sco_rsvd_check = 0x4002fa94 );
+PROVIDE ( ld_acl_sniff_frm_cbk = 0x4003482c );
+PROVIDE ( ld_inq_end = 0x4003ab48 );
+PROVIDE ( ld_inq_sched = 0x4003aba4 );
+PROVIDE ( ld_inq_frm_cbk = 0x4003ae4c );
+PROVIDE ( ld_pscan_frm_cbk = 0x4003ebe4 );
PROVIDE ( r_ld_acl_active_hop_types_get = 0x40036e10 );
PROVIDE ( r_ld_acl_afh_confirm = 0x40036d40 );
PROVIDE ( r_ld_acl_afh_prepare = 0x40036c84 );
@@ -954,6 +1084,11 @@ PROVIDE ( r_ld_acl_timing_accuracy_set = 0x4003673c );
PROVIDE ( r_ld_acl_t_poll_get = 0x40036024 );
PROVIDE ( r_ld_acl_t_poll_set = 0x40036068 );
PROVIDE ( r_ld_acl_tx_enc = 0x400362f8 );
+PROVIDE ( ld_acl_frm_cbk = 0x40034414 );
+PROVIDE ( ld_acl_rsw_end = 0x40032bc0 );
+PROVIDE ( ld_acl_end = 0x40033140 );
+PROVIDE ( ld_acl_resched = 0x40033814 );
+PROVIDE ( ld_acl_test_mode_update = 0x40032050 );
PROVIDE ( r_ld_acl_unsniff = 0x400361e0 );
PROVIDE ( r_ld_active_check = 0x4003cac4 );
PROVIDE ( r_ld_afh_ch_assess_data_get = 0x4003caec );
@@ -1333,6 +1468,13 @@ PROVIDE ( r_lm_num_clk_adj_ack_pending_set = 0x4004f500 );
PROVIDE ( r_lm_oob_f1 = 0x40012e54 );
PROVIDE ( r_lm_pca_sscan_link_get = 0x4004f560 );
PROVIDE ( r_lm_pca_sscan_link_set = 0x4004f550 );
+PROVIDE ( nvds_null_read = 0x400542a0 );
+PROVIDE ( nvds_null_write = 0x400542a8 );
+PROVIDE ( nvds_null_erase = 0x400542b0 );
+PROVIDE ( nvds_read = 0x400542c4 );
+PROVIDE ( nvds_write = 0x400542fc );
+PROVIDE ( nvds_erase = 0x40054334 );
+PROVIDE ( nvds_init_memory = 0x40054358 );
PROVIDE ( r_lmp_pack = 0x4001135c );
PROVIDE ( r_lmp_unpack = 0x4001149c );
PROVIDE ( r_lm_read_features = 0x4004f0d8 );
@@ -1823,7 +1965,23 @@ PROVIDE ( Xthal_intlevel = 0x3ff9c2b4 );
PROVIDE ( xthal_memcpy = 0x4000c0bc );
PROVIDE ( xthal_set_ccompare = 0x4000c058 );
PROVIDE ( xthal_set_intclear = 0x4000c1ec );
+PROVIDE ( _xtos_set_intlevel = 0x4000bfdc );
+PROVIDE ( g_ticks_per_us_pro = 0x3ffe01e0 );
+PROVIDE ( g_ticks_per_us_app = 0x3ffe40f0 );
+PROVIDE ( esp_rom_spiflash_config_param = 0x40063238 );
+PROVIDE ( esp_rom_spiflash_read_user_cmd = 0x400621b0 );
+PROVIDE ( esp_rom_spiflash_write_encrypted_disable = 0x40062e60 );
+PROVIDE ( esp_rom_spiflash_write_encrypted_enable = 0x40062df4 );
+PROVIDE ( esp_rom_spiflash_prepare_encrypted_data = 0x40062e1c );
+PROVIDE ( esp_rom_spiflash_select_qio_pins = 0x40061ddc );
+PROVIDE ( esp_rom_spiflash_attach = 0x40062a6c );
PROVIDE ( esp_rom_spiflash_config_clk = 0x40062bc8 );
+PROVIDE ( g_rom_spiflash_chip = 0x3ffae270 );
+PROVIDE ( hci_le_rd_rem_used_feats_cmd_handler = 0x400417b4 );
+PROVIDE ( llcp_length_req_handler = 0x40043808 );
+PROVIDE ( llcp_unknown_rsp_handler = 0x40043ba8 );
+PROVIDE ( llcp_channel_map_req_handler = 0x4004291c );
+PROVIDE ( llcp_con_up_req_handler = 0x400426f0 );
PROVIDE ( _xtos_alloca_handler = 0x40000010 );
PROVIDE ( _xtos_cause3_handler = 0x40000dd8 );
PROVIDE ( _xtos_c_handler_table = 0x3ffe0548 );
@@ -1858,3 +2016,35 @@ PROVIDE ( esp_rom_spiflash_prepare_encrypted_data = 0x40062e1c );
PROVIDE ( esp_rom_printf = ets_printf );
PROVIDE ( esp_rom_delay_us = ets_delay_us );
+
+/* Following are static data, but can be used, not generated by script <<<<< btdm data */
+
+PROVIDE ( hci_tl_env = 0x3ffb8154 );
+PROVIDE ( ld_acl_env = 0x3ffb8258 );
+PROVIDE ( ea_env = 0x3ffb80ec );
+PROVIDE ( lc_sco_data_path_config = 0x3ffb81f8 );
+PROVIDE ( lc_sco_env = 0x3ffb81fc );
+PROVIDE ( ld_active_ch_map = 0x3ffb8334 );
+PROVIDE ( ld_bcst_acl_env = 0x3ffb8274 );
+PROVIDE ( ld_csb_rx_env = 0x3ffb8278 );
+PROVIDE ( ld_csb_tx_env = 0x3ffb827c );
+PROVIDE ( ld_env = 0x3ffb9510 );
+PROVIDE ( ld_fm_env = 0x3ffb8284 );
+PROVIDE ( ld_inq_env = 0x3ffb82e4 );
+PROVIDE ( ld_iscan_env = 0x3ffb82e8 );
+PROVIDE ( ld_page_env = 0x3ffb82f0 );
+PROVIDE ( ld_pca_env = 0x3ffb82f4 );
+PROVIDE ( ld_pscan_env = 0x3ffb8308 );
+PROVIDE ( ld_sched_env = 0x3ffb830c );
+PROVIDE ( ld_sched_params = 0x3ffb96c0 );
+PROVIDE ( ld_sco_env = 0x3ffb824c );
+PROVIDE ( ld_sscan_env = 0x3ffb832c );
+PROVIDE ( ld_strain_env = 0x3ffb8330 );
+PROVIDE ( LM_Sniff = 0x3ffb8230 );
+PROVIDE ( LM_SniffSubRate = 0x3ffb8214 );
+PROVIDE ( prbs_64bytes = 0x3ff98992 );
+PROVIDE ( nvds_env = 0x3ffb8364 );
+PROVIDE ( nvds_magic_number = 0x3ff9912a );
+PROVIDE ( TASK_DESC_LLD = 0x3ff98b58 );
+/* Above are static data, but can be used, not generated by script >>>>> btdm data */
+
diff --git a/boards/xtensa/esp32/esp32-devkitc/configs/ble/defconfig b/boards/xtensa/esp32/esp32-devkitc/configs/ble/defconfig
new file mode 100644
index 0000000..0783b32
--- /dev/null
+++ b/boards/xtensa/esp32/esp32-devkitc/configs/ble/defconfig
@@ -0,0 +1,60 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed .config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that includes your
+# modifications.
+#
+# CONFIG_ARCH_LEDS is not set
+# CONFIG_NSH_ARGCAT is not set
+# CONFIG_NSH_CMDOPT_HEXDUMP is not set
+# CONFIG_NSH_CMDPARMS is not set
+CONFIG_ALLOW_BSD_COMPONENTS=y
+CONFIG_ARCH="xtensa"
+CONFIG_ARCH_BOARD="esp32-devkitc"
+CONFIG_ARCH_BOARD_ESP32_DEVKITC=y
+CONFIG_ARCH_CHIP="esp32"
+CONFIG_ARCH_CHIP_ESP32=y
+CONFIG_ARCH_CHIP_ESP32WROVER=y
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_ARCH_XTENSA=y
+CONFIG_BOARD_LOOPSPERMSEC=16717
+CONFIG_BTSAK=y
+CONFIG_BUILTIN=y
+CONFIG_DRIVERS_BLUETOOTH=y
+CONFIG_DRIVERS_IEEE80211=y
+CONFIG_DRIVERS_WIRELESS=y
+CONFIG_ESP32_BLE=y
+CONFIG_ESP32_UART0=y
+CONFIG_FS_PROCFS=y
+CONFIG_HAVE_CXX=y
+CONFIG_HAVE_CXXINITIALIZE=y
+CONFIG_IDLETHREAD_STACKSIZE=3072
+CONFIG_INTELHEX_BINARY=y
+CONFIG_MM_REGIONS=3
+CONFIG_NETDEV_LATEINIT=y
+CONFIG_NET_BLUETOOTH=y
+CONFIG_NET_SOCKOPTS=y
+CONFIG_NET_TCP=y
+CONFIG_NSH_ARCHINIT=y
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_LINELEN=64
+CONFIG_NSH_READLINE=y
+CONFIG_PREALLOC_MQ_MSGS=32
+CONFIG_PREALLOC_TIMERS=4
+CONFIG_PTHREAD_MUTEX_TYPES=y
+CONFIG_RAM_SIZE=114688
+CONFIG_RAM_START=0x20000000
+CONFIG_RAW_BINARY=y
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_WAITPID=y
+CONFIG_SPINLOCK=y
+CONFIG_START_DAY=6
+CONFIG_START_MONTH=12
+CONFIG_START_YEAR=2011
+CONFIG_SYSTEM_NSH=y
+CONFIG_UART0_SERIAL_CONSOLE=y
+CONFIG_USER_ENTRYPOINT="nsh_main"
+CONFIG_WIRELESS=y
+CONFIG_WIRELESS_BLUETOOTH=y
diff --git a/boards/xtensa/esp32/esp32-devkitc/src/Make.defs b/boards/xtensa/esp32/esp32-devkitc/src/Make.defs
index a3ef9b5..658aa43 100644
--- a/boards/xtensa/esp32/esp32-devkitc/src/Make.defs
+++ b/boards/xtensa/esp32/esp32-devkitc/src/Make.defs
@@ -56,7 +56,7 @@ SCRIPTOUT = $(BOARD_DIR)$(DELIM)scripts$(DELIM)esp32_out.ld
.PHONY = context distclean
$(SCRIPTOUT): $(LDSCRIPT_TEMPLATE) $(CONFIGFILE)
- $(Q) $(CC) -isystem $(TOPDIR)/include -C -P -x c -E $(LDSCRIPT_TEMPLATE) -o $@
+ $(Q) $(CC) -isystem $(TOPDIR)/include -I $(BOARD_COMMON_DIR)$(DELIM)scripts -C -P -x c -E $(LDSCRIPT_TEMPLATE) -o $@
context:: $(SCRIPTOUT)
diff --git a/boards/xtensa/esp32/esp32-devkitc/src/esp32_bringup.c b/boards/xtensa/esp32/esp32-devkitc/src/esp32_bringup.c
index 77db8c5..106df62 100644
--- a/boards/xtensa/esp32/esp32-devkitc/src/esp32_bringup.c
+++ b/boards/xtensa/esp32/esp32-devkitc/src/esp32_bringup.c
@@ -62,6 +62,10 @@
# include "esp32_board_wdt.h"
#endif
+#ifdef CONFIG_ESP32_BLE
+# include "esp32_ble.h"
+#endif
+
#ifdef CONFIG_ESP32_WIRELESS
# include "esp32_board_wlan.h"
#endif
@@ -221,6 +225,14 @@ int esp32_bringup(void)
}
#endif
+#ifdef CONFIG_ESP32_BLE
+ ret = esp32_ble_initialize();
+ if (ret)
+ {
+ syslog(LOG_ERR, "ERROR: Failed to initialize BLE: %d \n", ret);
+ }
+#endif
+
#ifdef CONFIG_ESP32_WIRELESS
ret = board_wlan_init();
if (ret < 0)
diff --git a/boards/xtensa/esp32/esp32-ethernet-kit/src/esp32_bringup.c b/boards/xtensa/esp32/esp32-ethernet-kit/src/esp32_bringup.c
index 7285d87..f09919f 100644
--- a/boards/xtensa/esp32/esp32-ethernet-kit/src/esp32_bringup.c
+++ b/boards/xtensa/esp32/esp32-ethernet-kit/src/esp32_bringup.c
@@ -62,6 +62,10 @@
# include "esp32_rt_timer.h"
#endif
+#ifdef CONFIG_ESP32_BLE
+# include "esp32_ble.h"
+#endif
+
#ifdef CONFIG_ESP32_WIRELESS
# include "esp32_board_wlan.h"
#endif
@@ -166,6 +170,14 @@ int esp32_bringup(void)
}
#endif
+#ifdef CONFIG_ESP32_BLE
+ ret = esp32_ble_initialize();
+ if (ret)
+ {
+ syslog(LOG_ERR, "ERROR: Failed to initialize BLE: %d \n", ret);
+ }
+#endif
+
#ifdef CONFIG_ESP32_WIRELESS
ret = board_wlan_init();
if (ret < 0)
diff --git a/boards/xtensa/esp32/esp32-wrover-kit/src/esp32_bringup.c b/boards/xtensa/esp32/esp32-wrover-kit/src/esp32_bringup.c
index 52a3991..af7871d 100644
--- a/boards/xtensa/esp32/esp32-wrover-kit/src/esp32_bringup.c
+++ b/boards/xtensa/esp32/esp32-wrover-kit/src/esp32_bringup.c
@@ -61,6 +61,10 @@
# include "esp32_board_wdt.h"
#endif
+#ifdef CONFIG_ESP32_BLE
+# include "esp32_ble.h"
+#endif
+
#ifdef CONFIG_ESP32_WIRELESS
# include "esp32_board_wlan.h"
#endif
@@ -200,6 +204,14 @@ int esp32_bringup(void)
}
#endif
+#ifdef CONFIG_ESP32_BLE
+ ret = esp32_ble_initialize();
+ if (ret)
+ {
+ syslog(LOG_ERR, "ERROR: Failed to initialize BLE: %d \n", ret);
+ }
+#endif
+
#ifdef CONFIG_ESP32_WIRELESS
ret = board_wlan_init();
if (ret < 0)
diff --git a/boards/xtensa/esp32/ttgo_lora_esp32/src/esp32_bringup.c b/boards/xtensa/esp32/ttgo_lora_esp32/src/esp32_bringup.c
index 3d307cf..701f611 100644
--- a/boards/xtensa/esp32/ttgo_lora_esp32/src/esp32_bringup.c
+++ b/boards/xtensa/esp32/ttgo_lora_esp32/src/esp32_bringup.c
@@ -62,6 +62,10 @@
# include "esp32_board_wdt.h"
#endif
+#ifdef CONFIG_ESP32_BLE
+# include "esp32_ble.h"
+#endif
+
#ifdef CONFIG_ESP32_WIRELESS
# include "esp32_board_wlan.h"
#endif
@@ -192,6 +196,14 @@ int esp32_bringup(void)
}
#endif
+#ifdef CONFIG_ESP32_BLE
+ ret = esp32_ble_initialize();
+ if (ret)
+ {
+ syslog(LOG_ERR, "ERROR: Failed to initialize BLE: %d \n", ret);
+ }
+#endif
+
#ifdef CONFIG_ESP32_WIRELESS
ret = board_wlan_init();
if (ret < 0)