You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/06/29 04:14:41 UTC
[incubator-nuttx] 01/03: riscv/esp32c3: Add esp32c3 BLE driver
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit 8b96edc3a5b62e76b8c1ff22063321a08de1361e
Author: xiewenxiang <xi...@espressif.com>
AuthorDate: Fri Apr 2 16:05:30 2021 +0800
riscv/esp32c3: Add esp32c3 BLE driver
---
arch/risc-v/include/esp32c3/irq.h | 2 +
arch/risc-v/src/esp32c3/Kconfig | 48 +-
arch/risc-v/src/esp32c3/Make.defs | 15 +-
arch/risc-v/src/esp32c3/esp32c3_ble.c | 337 ++++
.../src/esp32c3/{esp32c3_wlan.h => esp32c3_ble.h} | 58 +-
arch/risc-v/src/esp32c3/esp32c3_ble_adapter.c | 2007 ++++++++++++++++++++
arch/risc-v/src/esp32c3/esp32c3_ble_adapter.h | 161 ++
arch/risc-v/src/esp32c3/esp32c3_irq.c | 9 +
arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.c | 11 +
arch/risc-v/src/esp32c3/esp32c3_wlan.c | 4 +-
arch/risc-v/src/esp32c3/esp32c3_wlan.h | 4 +-
.../esp32c3-devkit/configs/autopm/defconfig | 2 +-
.../esp32c3-devkit/configs/{wapi => ble}/defconfig | 30 +-
.../esp32c3-devkit/configs/sta_softap/defconfig | 2 +-
.../esp32c3/esp32c3-devkit/configs/wapi/defconfig | 2 +-
.../esp32c3/esp32c3-devkit/src/esp32c3_bringup.c | 16 +-
16 files changed, 2622 insertions(+), 86 deletions(-)
diff --git a/arch/risc-v/include/esp32c3/irq.h b/arch/risc-v/include/esp32c3/irq.h
index 89334e2..1b44758 100644
--- a/arch/risc-v/include/esp32c3/irq.h
+++ b/arch/risc-v/include/esp32c3/irq.h
@@ -133,6 +133,8 @@
/* Reserved CPU interrupt for specific drivers */
#define ESP32C3_CPUINT_WMAC 1 /* Wi-Fi MAC */
+#define ESP32C3_CPUINT_BT_BB 5 /* BT BB */
+#define ESP32C3_CPUINT_RWBLE 8 /* RW BLE */
/* IRQ numbers. */
diff --git a/arch/risc-v/src/esp32c3/Kconfig b/arch/risc-v/src/esp32c3/Kconfig
index 45c9713..791b087 100644
--- a/arch/risc-v/src/esp32c3/Kconfig
+++ b/arch/risc-v/src/esp32c3/Kconfig
@@ -162,6 +162,12 @@ config ESP32C3_RTC_HEAP
select ARCH_HAVE_EXTRA_HEAPS
default n
+config ESP32C3_WIRELESS
+ bool
+ default n
+ select ESP32C3_RT_TIMER
+ select ESP32C3_TIMER0
+
menu "ESP32-C3 Peripheral Support"
config ESP32C3_ADC
@@ -328,6 +334,22 @@ config ESP32C3_RSA_ACCELERATOR
---help---
Enable ESP32-C3 RSA accelerator support.
+config ESP32C3_WIFI
+ bool "Wi-Fi"
+ default n
+ select NET
+ select ARCH_PHY_INTERRUPT
+ select ESP32C3_WIRELESS
+ ---help---
+ Enable Wi-Fi support
+
+config ESP32C3_BLE
+ bool "BLE"
+ default n
+ select ESP32C3_WIRELESS
+ ---help---
+ Enable BLE support
+
endmenu # ESP32-C3 Peripheral Support
menu "I2C Configuration"
@@ -641,7 +663,7 @@ endif # ESP32C3_ADC1
endmenu # ADC Configuration
menu "Wi-Fi configuration"
- depends on ESP32C3_WIRELESS
+ depends on ESP32C3_WIFI
choice
prompt "ESP32-C3 Wi-Fi mode"
@@ -763,7 +785,29 @@ config ESP32C3_WIFI_RECONNECT
---help---
Select this option to enable Wi-Fi to reconnect for station when disconnected.
-endmenu # ESP32C3_WIRELESS
+endmenu # Wi-Fi configuration
+
+menu "BLE Configuration"
+ depends on ESP32C3_BLE
+
+config ESP32C3_BLE_PKTBUF_NUM
+ int "BLE netcard packet buffer number per netcard"
+ default 16
+
+config ESP32C3_BLE_TTY_NAME
+ string "BLE TTY device name"
+ default "/dev/ttyHCI0"
+ depends on UART_BTH4
+
+config ESP32C3_BLE_TASK_STACK_SIZE
+ int "Controller task stack size"
+ default 4096
+
+config ESP32C3_BLE_TASK_PRIORITY
+ int "Controller task priority"
+ default 110
+
+endmenu # BLE Configuration
menu "SPI Flash configuration"
depends on ESP32C3_SPIFLASH
diff --git a/arch/risc-v/src/esp32c3/Make.defs b/arch/risc-v/src/esp32c3/Make.defs
index bd62279..df1b047 100644
--- a/arch/risc-v/src/esp32c3/Make.defs
+++ b/arch/risc-v/src/esp32c3/Make.defs
@@ -178,7 +178,7 @@ endif
ifeq ($(CONFIG_ESP32C3_WIRELESS),y)
WIRELESS_DRV_UNPACK = esp-wireless-drivers-3rdparty
-WIRELESS_DRV_ID = 2b53111
+WIRELESS_DRV_ID = df1f8c1
WIRELESS_DRV_ZIP = $(WIRELESS_DRV_ID).zip
WIRELESS_DRV_URL = https://github.com/espressif/esp-wireless-drivers-3rdparty/archive
@@ -200,13 +200,22 @@ clean_context::
INCLUDES += $(shell $(INCDIR) "$(CC)" $(ARCH_SRCDIR)$(DELIM)chip$(DELIM)esp-wireless-drivers-3rdparty$(DELIM)include)
INCLUDES += $(shell $(INCDIR) "$(CC)" $(ARCH_SRCDIR)$(DELIM)chip$(DELIM)esp-wireless-drivers-3rdparty$(DELIM)include$(DELIM)esp32c3)
-CHIP_CSRCS += esp32c3_wlan.c esp32c3_wifi_utils.c esp32c3_wifi_adapter.c
EXTRA_LIBPATHS += -L $(ARCH_SRCDIR)$(DELIM)chip$(DELIM)esp-wireless-drivers-3rdparty$(DELIM)libs$(DELIM)esp32c3
-EXTRA_LIBS += -lcore -lnet80211 -lpp -lsmartconfig -lcoexist -lespnow -lphy -lwpa_supplicant -lwapi
+EXTRA_LIBS += -lphy
# Due to some Wi-Fi related libraries, the option is need to avoid linking too much
# unused functions.
LDFLAGS += --gc-sections
endif
+
+ifeq ($(CONFIG_ESP32C3_WIFI),y)
+CHIP_CSRCS += esp32c3_wlan.c esp32c3_wifi_utils.c esp32c3_wifi_adapter.c
+EXTRA_LIBS += -lcore -lnet80211 -lpp -lsmartconfig -lcoexist -lespnow -lwpa_supplicant -lwapi
+endif
+
+ifeq ($(CONFIG_ESP32C3_BLE),y)
+CHIP_CSRCS += esp32c3_ble_adapter.c esp32c3_ble.c
+EXTRA_LIBS += -lbtbb -lbtdm_app
+endif
diff --git a/arch/risc-v/src/esp32c3/esp32c3_ble.c b/arch/risc-v/src/esp32c3/esp32c3_ble.c
new file mode 100644
index 0000000..b655b73
--- /dev/null
+++ b/arch/risc-v/src/esp32c3/esp32c3_ble.c
@@ -0,0 +1,337 @@
+/****************************************************************************
+ * arch/risc-v/src/esp32c3/esp32c3_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 "esp32c3_ble_adapter.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* BLE packet buffer max number */
+
+#define BLE_BUF_NUM CONFIG_ESP32C3_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 esp32c3_ble_priv_s
+{
+ struct bt_driver_s drv; /* NuttX BT/BLE driver data */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int esp32c3_ble_open(struct bt_driver_s *drv);
+static int esp32c3_ble_send(struct bt_driver_s *drv,
+ enum bt_buf_type_e type,
+ void *data, size_t len);
+static void esp32c3_ble_close(struct bt_driver_s *drv);
+
+static void esp32c3_ble_send_ready(void);
+static int esp32c3_ble_recv_cb(uint8_t *data, uint16_t len);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct esp32c3_ble_priv_s g_ble_priv =
+{
+ .drv =
+ {
+ .head_reserve = H4_HEADER_SIZE,
+ .open = esp32c3_ble_open,
+ .send = esp32c3_ble_send,
+ .close = esp32c3_ble_close
+ }
+};
+
+static esp_vhci_host_callback_t vhci_host_cb =
+{
+ .notify_host_send_available = esp32c3_ble_send_ready,
+ .notify_host_recv = esp32c3_ble_recv_cb
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32c3_ble_send_ready
+ *
+ * Description:
+ * If the controller could send HCI comand will callback this function.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void esp32c3_ble_send_ready(void)
+{
+}
+
+/****************************************************************************
+ * Name: esp32c3_ble_recv_cb
+ *
+ * Description:
+ * BLE receive callback function when BLE hardware receive packet
+ *
+ * Input Parameters:
+ * data - BLE packet data pointer
+ * len - BLE packet length
+ *
+ * Returned Value:
+ * 0 on success or a negated value on failure.
+ *
+ ****************************************************************************/
+
+static int esp32c3_ble_recv_cb(uint8_t *data, uint16_t len)
+{
+ int ret;
+ bool valid;
+ enum bt_buf_type_e type;
+ struct esp32c3_ble_priv_s *priv = &g_ble_priv;
+
+ switch (data[0])
+ {
+ case H4_EVT:
+ type = BT_EVT;
+ valid = true;
+ break;
+ case H4_ACL:
+ type = BT_ACL_IN;
+ valid = true;
+ break;
+ case H4_ISO:
+ type = BT_ISO_IN;
+ valid = true;
+ break;
+ default:
+ valid = false;
+ break;
+ }
+
+ if (!valid)
+ {
+ ret = ERROR;
+ }
+ else
+ {
+ /* send packet to host */
+
+ ret = bt_netdev_receive(&priv->drv, type,
+ &data[H4_HEADER_SIZE],
+ len - H4_HEADER_SIZE);
+ if (ret < 0)
+ {
+ wlerr("Failed to receive ret=%d\n", ret);
+ }
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: esp32c3_ble_send
+ *
+ * Description:
+ * ESP32-C3 BLE send callback function for BT driver.
+ *
+ * Input Parameters:
+ * drv - BT driver pointer
+ * type - BT packet type
+ * data - BT packte data buffer pointer
+ * len - BT packte length
+ *
+ * Returned Value:
+ * Sent bytes on success or a negated value on failure.
+ *
+ ****************************************************************************/
+
+static int esp32c3_ble_send(struct bt_driver_s *drv,
+ enum bt_buf_type_e type,
+ void *data, size_t len)
+{
+ uint8_t *hdr = (uint8_t *)data - drv->head_reserve;
+
+ if ((len + H4_HEADER_SIZE) > BLE_BUF_SIZE)
+ {
+ return -EINVAL;
+ }
+
+ if (type == BT_CMD)
+ {
+ *hdr = H4_CMD;
+ }
+ else if (type == BT_ACL_OUT)
+ {
+ *hdr = H4_ACL;
+ }
+ else if (type == BT_ISO_OUT)
+ {
+ *hdr = H4_ISO;
+ }
+ else
+ {
+ return -EINVAL;
+ }
+
+ if (esp32c3_vhci_host_check_send_available())
+ {
+ esp32c3_vhci_host_send_packet(hdr, len + drv->head_reserve);
+ }
+
+ return len;
+}
+
+/****************************************************************************
+ * Name: esp32c3_ble_close
+ *
+ * Description:
+ * ESP32-C3 BLE close callback function for BT driver.
+ *
+ * Input Parameters:
+ * drv - BT driver pointer
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void esp32c3_ble_close(struct bt_driver_s *drv)
+{
+}
+
+/****************************************************************************
+ * Name: esp32c3_ble_open
+ *
+ * Description:
+ * ESP32-C3 BLE open callback function for BT driver.
+ *
+ * Input Parameters:
+ * drv - BT driver pointer
+ *
+ * Returned Value:
+ * OK on success or a negated value on failure.
+ *
+ ****************************************************************************/
+
+static int esp32c3_ble_open(struct bt_driver_s *drv)
+{
+ return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32c3_ble_initialize
+ *
+ * Description:
+ * Init BT controller
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * success or fail
+ *
+ ****************************************************************************/
+
+int esp32c3_ble_initialize(void)
+{
+ int ret;
+
+ ret = esp32c3_bt_controller_init();
+ if (ret)
+ {
+ wlerr("Failed to initialize BLE ret=%d\n", ret);
+ return ERROR;
+ }
+
+ ret = esp32c3_bt_controller_enable(ESP_BT_MODE_BLE);
+ if (ret)
+ {
+ wlerr("Failed to Enable BLE ret=%d\n", ret);
+ return ERROR;
+ }
+
+ ret = esp32c3_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 error: %d\n", ret);
+ return ret;
+ }
+
+ return OK;
+}
diff --git a/arch/risc-v/src/esp32c3/esp32c3_wlan.h b/arch/risc-v/src/esp32c3/esp32c3_ble.h
similarity index 57%
copy from arch/risc-v/src/esp32c3/esp32c3_wlan.h
copy to arch/risc-v/src/esp32c3/esp32c3_ble.h
index 54cdf9a..d1cd2c9 100644
--- a/arch/risc-v/src/esp32c3/esp32c3_wlan.h
+++ b/arch/risc-v/src/esp32c3/esp32c3_ble.h
@@ -1,5 +1,5 @@
/****************************************************************************
- * arch/risc-v/src/esp32c3/esp32c3_wlan.h
+ * arch/risc-v/src/esp32c3/esp32c3_ble.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
@@ -18,8 +18,8 @@
*
****************************************************************************/
-#ifndef __ARCH_RISCV_SRC_ESP32C3_ESP32C3_WLAN_H
-#define __ARCH_RISCV_SRC_ESP32C3_ESP32C3_WLAN_H
+#ifndef __ARCH_RISCV_SRC_ESP32C3_ESP32C3_BLE_H
+#define __ARCH_RISCV_SRC_ESP32C3_ESP32C3_BLE_H
/****************************************************************************
* Included Files
@@ -27,66 +27,24 @@
#include <nuttx/config.h>
-#include "esp32c3_wifi_adapter.h"
-
-#ifndef __ASSEMBLY__
-
-#undef EXTERN
-#if defined(__cplusplus)
-#define EXTERN extern "C"
-extern "C"
-{
-#else
-#define EXTERN extern
-#endif
-
-#ifdef CONFIG_ESP32C3_WIRELESS
-
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
- * Name: esp32c3_wlan_sta_initialize
+ * Name: esp32c3_ble_initialize
*
* Description:
- * Initialize the ESP32-C3 WLAN station netcard driver
+ * Init BT controller
*
* Input Parameters:
* None
*
* Returned Value:
- * OK on success; Negated errno on failure.
+ * success or fail
*
****************************************************************************/
-#ifdef ESP32C3_WLAN_HAS_STA
-int esp32c3_wlan_sta_initialize(void);
-#endif
-
-/****************************************************************************
- * Name: esp32c3_wlan_softap_initialize
- *
- * Description:
- * Initialize the ESP32-C3 WLAN softAP netcard driver
- *
- * Input Parameters:
- * None
- *
- * Returned Value:
- * OK on success; Negated errno on failure.
- *
- ****************************************************************************/
-
-#ifdef ESP32C3_WLAN_HAS_SOFTAP
-int esp32c3_wlan_softap_initialize(void);
-#endif
-
-#endif /* CONFIG_ESP32C3_WIRELESS */
-#ifdef __cplusplus
-}
-#endif
-#undef EXTERN
+int esp32c3_ble_initialize(void);
-#endif /* __ASSEMBLY__ */
-#endif /* __ARCH_RISCV_SRC_ESP32C3_ESP32C3_WLAN_H */
+#endif /* __ARCH_RISCV_SRC_ESP32C3_ESP32C3_BLE_H */
diff --git a/arch/risc-v/src/esp32c3/esp32c3_ble_adapter.c b/arch/risc-v/src/esp32c3/esp32c3_ble_adapter.c
new file mode 100644
index 0000000..561cffb
--- /dev/null
+++ b/arch/risc-v/src/esp32c3/esp32c3_ble_adapter.c
@@ -0,0 +1,2007 @@
+/****************************************************************************
+ * arch/risc-v/src/esp32c3/esp32c3_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 "hardware/esp32c3_syscon.h"
+#include "espidf_wifi.h"
+#include "esp32c3.h"
+#include "esp32c3_attr.h"
+#include "esp32c3_irq.h"
+#include "esp32c3_rt_timer.h"
+#include "esp32c3_ble_adapter.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define OSI_FUNCS_TIME_BLOCKING 0xffffffff
+#define OSI_VERSION 0x00010006
+#define OSI_MAGIC_VALUE 0xfadebead
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* BLE message queue private data */
+
+struct mq_adpt_s
+{
+ struct file mq; /* Message queue handle */
+ uint32_t msgsize; /* Message size */
+ char name[16]; /* 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
+{
+ uint32_t enable; /* whether low power mode is required */
+ uint32_t lpclk_sel; /* low power clock source */
+ uint32_t mac_bb_pd; /* whether hardware(MAC, BB) force-power-down is required during sleep */
+ uint32_t wakeup_timer_required; /* whether system timer is needed */
+ uint32_t 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
+{
+ uint32_t pm_lock_released /* whether power management lock is released */
+ uint32_t mac_bb_pd /* whether hardware(MAC, BB) is powered down */
+ uint32_t phy_enabled /* whether phy is switched on */
+ uint32_t 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;
+
+/* 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 _magic;
+ uint32_t _version;
+ void (*_interrupt_set)(int cpu_no, int intr_source,
+ int interrupt_no, int interrpt_prio);
+ void (*_interrupt_clear)(int interrupt_source, int interrupt_no);
+ void (*_interrupt_handler_set)(int interrupt_no, void * fn, void *arg);
+ 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);
+ int (*_semphr_take_from_isr)(void *semphr, void *hptw);
+ int (*_semphr_give_from_isr)(void *semphr, void *hptw);
+ int (*_semphr_take)(void *semphr, uint32_t block_time_ms);
+ int (*_semphr_give)(void *semphr);
+ void *(*_mutex_create)(void);
+ void (*_mutex_delete)(void *mutex);
+ int (*_mutex_lock)(void *mutex);
+ int (*_mutex_unlock)(void *mutex);
+ void *(* _queue_create)(uint32_t queue_len, uint32_t item_size);
+ void (* _queue_delete)(void *queue);
+ int (* _queue_send)(void *queue, void *item, uint32_t block_time_ms);
+ int (* _queue_send_from_isr)(void *queue, void *item, void *hptw);
+ int (* _queue_recv)(void *queue, void *item, uint32_t block_time_ms);
+ int (* _queue_recv_from_isr)(void *queue, void *item, void *hptw);
+ int (* _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)(size_t size);
+ void *(* _malloc_internal)(size_t size);
+ void (* _free)(void *p);
+ int (* _read_efuse_mac)(uint8_t mac[6]);
+ void (* _srand)(unsigned int seed);
+ int (* _rand)(void);
+ uint32_t (* _btdm_lpcycles_2_hus)(uint32_t cycles, uint32_t *error_corr);
+ uint32_t (* _btdm_hus_2_lpcycles)(uint32_t us);
+ bool (* _btdm_sleep_check_duration)(int32_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 */
+ void (* _coex_wifi_sleep_set)(bool sleep);
+ int (* _coex_core_ble_conn_dyn_prio_get)(bool *low, bool *high);
+ void (* _coex_schm_status_bit_set)(uint32_t type, uint32_t status);
+ void (* _coex_schm_status_bit_clear)(uint32_t type, uint32_t status);
+ void (* _interrupt_on)(int intr_num);
+ void (* _interrupt_off)(int intr_num);
+ void (* _esp_hw_power_down)(void);
+ void (* _esp_hw_power_up)(void);
+ void (* _ets_backup_dma_copy)(uint32_t reg,
+ uint32_t mem_addr, uint32_t num,
+ bool to_rem);
+};
+
+/****************************************************************************
+ * Private Function
+ ****************************************************************************/
+
+static void interrupt_set_wrapper(int cpu_no, int intr_source,
+ int intr_num, int intr_prio);
+static void interrupt_clear_wrapper(int intr_source, int intr_num);
+static void interrupt_handler_set_wrapper(int n, void *fn, 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 *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_hus(uint32_t cycles,
+ uint32_t *error_corr);
+static uint32_t IRAM_ATTR btdm_hus_2_lpcycles(uint32_t us);
+static void coex_wifi_sleep_set_hook(bool sleep);
+static void coex_schm_status_bit_set_wrapper(uint32_t type, uint32_t status);
+static void coex_schm_status_bit_clear_wrapper(uint32_t type,
+ uint32_t status);
+static void interrupt_on_wrapper(int intr_num);
+static void interrupt_off_wrapper(int intr_num);
+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);
+
+/****************************************************************************
+ * Extern Functions declaration and value
+ ****************************************************************************/
+
+extern int btdm_osi_funcs_register(void *osi_funcs);
+extern void btdm_controller_rom_data_init(void);
+
+/* Initialise and De-initialise */
+
+extern int btdm_controller_init(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 uint8_t btdm_controller_get_sleep_mode(void);
+extern bool btdm_power_state_active(void);
+extern void btdm_wakeup_request(void);
+extern void btdm_in_wakeup_requesting_set(bool in_wakeup_requesting);
+
+/* vendor dependent tasks to be posted and handled by controller task */
+
+extern int btdm_vnd_offload_task_register(btdm_vnd_ol_sig_t sig,
+ btdm_vnd_ol_task_func_t func);
+extern int btdm_vnd_offload_task_deregister(btdm_vnd_ol_sig_t sig);
+extern int btdm_vnd_offload_post_from_isr(btdm_vnd_ol_sig_t sig,
+ void *param, bool need_yield);
+extern int btdm_vnd_offload_post(btdm_vnd_ol_sig_t sig, void *param);
+
+/* 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 uint16_t l2c_ble_link_get_tx_buf_num(void);
+extern int coex_core_ble_conn_dyn_prio_get(bool *low, bool *high);
+
+extern bool btdm_deep_sleep_mem_init(void);
+extern void btdm_deep_sleep_mem_deinit(void);
+extern void btdm_ble_power_down_dma_copy(bool copy);
+extern uint8_t btdm_sleep_clock_sync(void);
+
+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;
+
+/****************************************************************************
+ * 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;
+
+/* BT interrupt private data */
+
+static bool g_ble_irq_bind;
+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,
+ ._interrupt_set = interrupt_set_wrapper,
+ ._interrupt_clear = interrupt_clear_wrapper,
+ ._interrupt_handler_set = interrupt_handler_set_wrapper,
+ ._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,
+ ._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_hus = btdm_lpcycles_2_hus,
+ ._btdm_hus_2_lpcycles = btdm_hus_2_lpcycles,
+ ._coex_wifi_sleep_set = coex_wifi_sleep_set_hook,
+ ._coex_core_ble_conn_dyn_prio_get = coex_core_ble_conn_dyn_prio_get,
+ ._coex_schm_status_bit_set = coex_schm_status_bit_set_wrapper,
+ ._coex_schm_status_bit_clear = coex_schm_status_bit_clear_wrapper,
+ ._interrupt_on = interrupt_on_wrapper,
+ ._interrupt_off = interrupt_off_wrapper,
+};
+
+/****************************************************************************
+ * Private Functions and Public Functions only used by libraries
+ ****************************************************************************/
+
+/****************************************************************************
+ * 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
+
+ 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\n");
+ }
+
+ return pid > 0 ? true : false;
+}
+
+/****************************************************************************
+ * Name: interrupt_set_wrapper
+ *
+ * Description:
+ * Bind IRQ and resource with given parameters.
+ *
+ * Input Parameters:
+ * cpu_no - The CPU which the interrupt number belongs.
+ * intr_source - The interrupt hardware source number.
+ * intr_num - The interrupt number CPU.
+ * intr_prio - The interrupt priority.
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void interrupt_set_wrapper(int cpu_no,
+ int intr_source,
+ int intr_num,
+ int intr_prio)
+{
+ wlinfo("cpu_no=%d , intr_source=%d , intr_num=%d, intr_prio=%d\n",
+ cpu_no, intr_source, intr_num, intr_prio);
+ esp32c3_bind_irq(intr_num, intr_source, intr_prio, ESP32C3_INT_LEVEL);
+}
+
+/****************************************************************************
+ * Name: interrupt_clear_wrapper
+ *
+ * Description:
+ * Not supported
+ *
+ ****************************************************************************/
+
+static void interrupt_clear_wrapper(int intr_source, int intr_num)
+{
+}
+
+/****************************************************************************
+ * 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, FAR void *arg)
+{
+ struct irq_adpt_s *adapter = (struct irq_adpt_s *)arg;
+
+ adapter->func(adapter->arg);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: interrupt_handler_set_wrapper
+ *
+ * Description:
+ * Register interrupt function
+ *
+ * Input Parameters:
+ * n - Interrupt ID
+ * f - Interrupt function
+ * arg - Function private data
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void interrupt_handler_set_wrapper(int n, void *fn, void *arg)
+{
+ int ret;
+ struct irq_adpt_s *adapter;
+
+ if (g_ble_irq_bind)
+ {
+ return;
+ }
+
+ adapter = kmm_malloc(sizeof(struct irq_adpt_s));
+ DEBUGASSERT(adapter);
+
+ adapter->func = fn;
+ adapter->arg = arg;
+
+ ret = irq_attach(n + ESP32C3_IRQ_FIRSTPERIPH, esp_int_adpt_cb, adapter);
+ DEBUGASSERT(ret == OK);
+
+ g_ble_irq_bind = true;
+}
+
+/****************************************************************************
+ * Name: esp32c3_ints_on
+ *
+ * Description:
+ * Enable Wi-Fi interrupt
+ *
+ * Input Parameters:
+ * intr_num - No mean
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void interrupt_on_wrapper(int intr_num)
+{
+ up_enable_irq(intr_num);
+}
+
+/****************************************************************************
+ * Name: esp32c3_ints_off
+ *
+ * Description:
+ * Disable Wi-Fi interrupt
+ *
+ * Input Parameters:
+ * intr_num - No mean
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void interrupt_off_wrapper(int intr_num)
+{
+ up_disable_irq(intr_num);
+}
+
+/****************************************************************************
+ * 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)
+{
+ 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);
+ DEBUGASSERT(sem);
+
+ ret = sem_init(sem, 0, init);
+ DEBUGASSERT(ret == OK);
+
+ 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
+ *
+ * Returned Value:
+ * True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int IRAM_ATTR semphr_take_from_isr_wrapper(void *semphr, void *hptw)
+{
+ return semphr_take_wrapper(semphr, 0);
+}
+
+/****************************************************************************
+ * 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:
+ * timespec - Input timespec data pointer
+ * ticks - System ticks
+ *
+ * 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\n");
+ }
+ }
+ else
+ {
+ ret = clock_gettime(CLOCK_REALTIME, &timeout);
+ if (ret < 0)
+ {
+ wlerr("Failed to get time\n");
+ return false;
+ }
+
+ 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\n");
+ return false;
+ }
+
+ if (ticks)
+ {
+ esp_update_time(&timeout, ticks);
+ }
+
+ ret = file_mq_timedsend(&mq_adpt->mq, (const char *)item,
+ mq_adpt->msgsize, prio, &timeout);
+ if (ret < 0)
+ {
+ wlerr("Failed to timedsend message to mqueue error=%d\n", ret);
+ }
+ }
+
+ return 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)
+{
+ 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:
+ * szie - buffer size
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+ void * p = NULL;
+
+ p = kmm_malloc(size);
+ DEBUGASSERT(p);
+
+ return p;
+}
+
+/****************************************************************************
+ * 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 0;
+}
+
+/****************************************************************************
+ * 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_hus
+ *
+ * Description:
+ * Converts a number of low power clock cycles into a duration in half us.
+ *
+ * Input Parameters:
+ * cycles
+ * error_corr
+ *
+ * Returned Value:
+ * us
+ *
+ ****************************************************************************/
+
+static uint32_t IRAM_ATTR btdm_lpcycles_2_hus(uint32_t cycles,
+ uint32_t *error_corr)
+{
+ 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_hus_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_hus_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;
+}
+
+/****************************************************************************
+ * Name: coex_schm_status_bit_set_wrapper
+ *
+ * Description:
+ *
+ * Input Parameters:
+ * type
+ * status
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void coex_schm_status_bit_set_wrapper(uint32_t type, uint32_t status)
+{
+ /* empty function */
+}
+
+/****************************************************************************
+ * Name: coex_schm_status_bit_clear_wrapper
+ *
+ * Description:
+ *
+ * Input Parameters:
+ * szie
+ * status
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void coex_schm_status_bit_clear_wrapper(uint32_t type,
+ uint32_t status)
+{
+ /* empty function */
+}
+
+/****************************************************************************
+ * 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)
+{
+ btdm_controller_rom_data_init();
+}
+
+/****************************************************************************
+ * Name: phy_printf
+ *
+ * Description:
+ * Output format string and its arguments
+ *
+ * Input Parameters:
+ * format - format string
+ *
+ * Returned Value:
+ * 0
+ *
+ ****************************************************************************/
+
+int phy_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(SYSTEM_WIFI_CLK_EN_REG, 0,
+ SYSTEM_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(SYSTEM_WIFI_CLK_EN_REG,
+ SYSTEM_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)
+ {
+ 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);
+ extern void coex_pti_v2(void);
+ coex_pti_v2();
+ }
+
+ g_phy_access_ref++;
+ leave_critical_section(flags);
+ kmm_free(cal_data);
+}
+
+static void coex_wifi_sleep_set_hook(bool sleep)
+{
+}
+
+/****************************************************************************
+ * 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\n");
+ 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 - Message data pointerint
+ * 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\n");
+ 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);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32c3_bt_controller_init
+ *
+ * Description:
+ * Init BT controller.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+int esp32c3_bt_controller_init(void)
+{
+ esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
+ esp_bt_controller_config_t *cfg = &bt_cfg;
+
+ if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE)
+ {
+ wlerr("Invalid controller status");
+ return -1;
+ }
+
+ cfg->controller_task_stack_size = CONFIG_ESP32C3_BLE_TASK_STACK_SIZE;
+ cfg->controller_task_prio = CONFIG_ESP32C3_BLE_TASK_PRIORITY;
+
+ cfg->controller_task_run_cpu = 0;
+ cfg->ble_max_act = 10;
+ cfg->sleep_mode = 0;
+ cfg->coex_phy_coded_tx_rx_time_limit = 0;
+ cfg->bluetooth_mode = 1;
+ cfg->sleep_clock = 0;
+ cfg->ble_st_acl_tx_buf_nb = 0;
+ cfg->ble_hw_cca_check = 0;
+ cfg->ble_adv_dup_filt_max = 30;
+ cfg->ce_len_type = 0;
+ cfg->hci_tl_type = 1;
+ cfg->hci_tl_funcs = NULL;
+ cfg->txant_dft = 0;
+ cfg->rxant_dft = 0;
+ cfg->txpwr_dft = 7;
+ cfg->cfg_mask = 1;
+ cfg->scan_duplicate_mode = 0;
+ cfg->scan_duplicate_type = 0;
+ cfg->normal_adv_size = 20;
+ cfg->mesh_adv_size = 0;
+
+ btdm_controller_mem_init();
+
+ if (btdm_osi_funcs_register(&g_osi_funcs) != 0)
+ {
+ return -EINVAL;
+ }
+
+ wlinfo("BT controller compile version [%s]\n",
+ btdm_controller_get_compile_version());
+
+ modifyreg32(SYSTEM_WIFI_CLK_EN_REG, 0, UINT32_MAX);
+
+ bt_phy_enable();
+ g_lp_stat.phy_enabled = 1;
+
+ if (btdm_controller_init(cfg) != 0)
+ {
+ bt_phy_disable();
+ g_lp_stat.phy_enabled = 0;
+ return -EIO;
+ }
+
+ btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
+
+ return 0;
+}
+
+/****************************************************************************
+ * Name: esp32c3_bt_controller_deinit
+ *
+ * Description:
+ * Deinit BT controller.
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+int esp32c3_bt_controller_deinit(void)
+{
+ if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_INITED)
+ {
+ return -1;
+ }
+
+ btdm_controller_deinit();
+
+ if (g_lp_stat.phy_enabled)
+ {
+ bt_phy_disable();
+ g_lp_stat.phy_enabled = 0;
+ }
+ else
+ {
+ assert(0);
+ }
+
+ btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE;
+ g_btdm_lpcycle_us = 0;
+ return 0;
+}
+
+/****************************************************************************
+ * Name: esp32c3_bt_controller_disable
+ *
+ * Description:
+ * disable BT controller.
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+int esp32c3_bt_controller_disable(void)
+{
+ if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED)
+ {
+ return -1;
+ }
+
+ while (!btdm_power_state_active())
+ {
+ usleep(1000); /* wait */
+ }
+
+ btdm_controller_disable();
+
+ btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
+
+ return 0;
+}
+
+/****************************************************************************
+ * Name: esp32c3_bt_controller_enable
+ *
+ * Description:
+ * Enable BT controller.
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+int esp32c3_bt_controller_enable(esp_bt_mode_t mode)
+{
+ int ret = 0;
+
+ if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_INITED)
+ {
+ return -1;
+ }
+
+ if (mode != btdm_controller_get_mode())
+ {
+ wlerr("invalid mode %d, controller support mode is %d",
+ mode, btdm_controller_get_mode());
+ return -1;
+ }
+
+ /* enable low power mode */
+
+ 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);
+
+ return ret;
+}
+
+esp_bt_controller_status_t esp32c3_bt_controller_get_status(void)
+{
+ return btdm_controller_status;
+}
+
+/****************************************************************************
+ * Name: esp32c3_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 esp32c3_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: esp32c3_vhci_host_send_packet
+ *
+ * Description:
+ * host send packet to controller.
+ * Input Parameters:
+ * data - the packet point
+ * len - the packet length
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void esp32c3_vhci_host_send_packet(uint8_t *data, uint16_t len)
+{
+ if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED)
+ {
+ return;
+ }
+
+ API_vhci_host_send_packet(data, len);
+}
+
+/****************************************************************************
+ * Name: esp32c3_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 esp32c3_vhci_register_callback(const esp_vhci_host_callback_t *callback)
+{
+ int ret = -1;
+ 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;
+}
diff --git a/arch/risc-v/src/esp32c3/esp32c3_ble_adapter.h b/arch/risc-v/src/esp32c3/esp32c3_ble_adapter.h
new file mode 100644
index 0000000..7026035
--- /dev/null
+++ b/arch/risc-v/src/esp32c3/esp32c3_ble_adapter.h
@@ -0,0 +1,161 @@
+/****************************************************************************
+ * arch/risc-v/src/esp32c3/esp32c3_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_RISCV_SRC_ESP32C3_ESP32C3_BLE_ADAPTER_H
+#define __ARCH_RISCV_SRC_ESP32C3_ESP32C3_BLE_ADAPTER_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "esp_bt.h"
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32c3_bt_controller_init
+ *
+ * Description:
+ * Init BT controller.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+int esp32c3_bt_controller_init(void);
+
+/****************************************************************************
+ * Name: esp32c3_bt_controller_deinit
+ *
+ * Description:
+ * Deinit BT controller.
+ * Input Parameters:
+ * cfg - Initial configuration of BT controller.
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+int esp32c3_bt_controller_deinit(void);
+
+/****************************************************************************
+ * Name: esp32c3_bt_controller_enable
+ *
+ * Description:
+ * disable BT controller.
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+int esp32c3_bt_controller_enable(esp_bt_mode_t mode);
+
+/****************************************************************************
+ * Name: esp32c3_bt_controller_disable
+ *
+ * Description:
+ * disable BT controller.
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+int esp32c3_bt_controller_disable(void);
+
+/****************************************************************************
+ * Name: esp32c3_bt_controller_enable
+ *
+ * Description:
+ * Enable BT controller.
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+esp_bt_controller_status_t esp32c3_bt_controller_get_status(void);
+
+/****************************************************************************
+ * Name: esp32c3_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 esp32c3_vhci_host_check_send_available(void);
+
+/****************************************************************************
+ * Name: esp32c3_vhci_host_send_packet
+ *
+ * Description:
+ * host send packet to controller.
+ * Input Parameters:
+ * data - the packet point
+ * len - the packet length
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void esp32c3_vhci_host_send_packet(uint8_t *data, uint16_t len);
+
+/****************************************************************************
+ * Name: esp32c3_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 esp32c3_vhci_register_callback(
+ const esp_vhci_host_callback_t *callback);
+
+#endif /* __ARCH_RISCV_SRC_ESP32C3_ESP32C3_BLE_ADAPTER_H */
diff --git a/arch/risc-v/src/esp32c3/esp32c3_irq.c b/arch/risc-v/src/esp32c3/esp32c3_irq.c
index 734a74e..23e57c7 100644
--- a/arch/risc-v/src/esp32c3/esp32c3_irq.c
+++ b/arch/risc-v/src/esp32c3/esp32c3_irq.c
@@ -88,10 +88,19 @@ void up_irqinitialize(void)
* Object | CPU INT | Peripheral
* | |
* Wi-Fi | 1 | 1
+ * BT BB | 5 | 5
+ * RW BLE | 8 | 8
*/
#ifdef CONFIG_ESP32C3_WIRELESS
+# ifdef CONFIG_ESP32C3_WIFI
g_cpuint_map[ESP32C3_CPUINT_WMAC] = ESP32C3_PERIPH_WIFI_MAC_NMI;
+# endif
+
+# ifdef CONFIG_ESP32C3_BLE
+ g_cpuint_map[ESP32C3_CPUINT_BT_BB] = ESP32C3_PERIPH_BT_BB;
+ g_cpuint_map[ESP32C3_CPUINT_RWBLE] = ESP32C3_PERIPH_RWBLE_IRQ;
+# endif
#endif
/* Clear all peripheral interrupts from "bootloader" */
diff --git a/arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.c b/arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.c
index 9c44b81..8d73dba 100644
--- a/arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.c
+++ b/arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.c
@@ -354,6 +354,14 @@ static int wifi_coex_set_schm_curr_phase_idx(int idx);
static int wifi_coex_get_schm_curr_phase_idx(void);
/****************************************************************************
+ * Extern Functions declaration
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32C3_BLE
+extern void coex_pti_v2(void);
+#endif
+
+/****************************************************************************
* Public Functions declaration
****************************************************************************/
@@ -2456,6 +2464,9 @@ 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);
+#ifdef CONFIG_ESP32C3_BLE
+ coex_pti_v2();
+#endif
}
g_phy_access_ref++;
diff --git a/arch/risc-v/src/esp32c3/esp32c3_wlan.c b/arch/risc-v/src/esp32c3/esp32c3_wlan.c
index bdfb8ff..6cdf9dd 100644
--- a/arch/risc-v/src/esp32c3/esp32c3_wlan.c
+++ b/arch/risc-v/src/esp32c3/esp32c3_wlan.c
@@ -24,7 +24,7 @@
#include <nuttx/config.h>
-#ifdef CONFIG_ESP32C3_WIRELESS
+#ifdef CONFIG_ESP32C3_WIFI
#include <queue.h>
#include <assert.h>
@@ -2026,4 +2026,4 @@ int esp32c3_wlan_softap_initialize(void)
}
#endif
-#endif /* CONFIG_ESP32C3_WIRELESS */
+#endif /* CONFIG_ESP32C3_WIFI */
diff --git a/arch/risc-v/src/esp32c3/esp32c3_wlan.h b/arch/risc-v/src/esp32c3/esp32c3_wlan.h
index 54cdf9a..ce4e06f 100644
--- a/arch/risc-v/src/esp32c3/esp32c3_wlan.h
+++ b/arch/risc-v/src/esp32c3/esp32c3_wlan.h
@@ -40,7 +40,7 @@ extern "C"
#define EXTERN extern
#endif
-#ifdef CONFIG_ESP32C3_WIRELESS
+#ifdef CONFIG_ESP32C3_WIFI
/****************************************************************************
* Public Function Prototypes
@@ -82,7 +82,7 @@ int esp32c3_wlan_sta_initialize(void);
int esp32c3_wlan_softap_initialize(void);
#endif
-#endif /* CONFIG_ESP32C3_WIRELESS */
+#endif /* CONFIG_ESP32C3_WIFI */
#ifdef __cplusplus
}
#endif
diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/configs/autopm/defconfig b/boards/risc-v/esp32c3/esp32c3-devkit/configs/autopm/defconfig
index af32cc2..588fbc6 100644
--- a/boards/risc-v/esp32c3/esp32c3-devkit/configs/autopm/defconfig
+++ b/boards/risc-v/esp32c3/esp32c3-devkit/configs/autopm/defconfig
@@ -22,7 +22,7 @@ CONFIG_BUILTIN=y
CONFIG_DRIVERS_IEEE80211=y
CONFIG_DRIVERS_WIRELESS=y
CONFIG_ESP32C3_AUTO_SLEEP=y
-CONFIG_ESP32C3_WIRELESS=y
+CONFIG_ESP32C3_WIFI=y
CONFIG_EXAMPLE_POWER_SAVE_MIN_MODEM=y
CONFIG_FS_PROCFS=y
CONFIG_HAVE_CXX=y
diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/configs/wapi/defconfig b/boards/risc-v/esp32c3/esp32c3-devkit/configs/ble/defconfig
similarity index 65%
copy from boards/risc-v/esp32c3/esp32c3-devkit/configs/wapi/defconfig
copy to boards/risc-v/esp32c3/esp32c3-devkit/configs/ble/defconfig
index 96f6cbf..fb1bb17 100644
--- a/boards/risc-v/esp32c3/esp32c3-devkit/configs/wapi/defconfig
+++ b/boards/risc-v/esp32c3/esp32c3-devkit/configs/ble/defconfig
@@ -5,9 +5,6 @@
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
-# CONFIG_NSH_ARGCAT is not set
-# CONFIG_NSH_CMDOPT_HEXDUMP is not set
-# CONFIG_NSH_CMDPARMS is not set
CONFIG_ARCH="risc-v"
CONFIG_ARCH_BOARD="esp32c3-devkit"
CONFIG_ARCH_BOARD_ESP32C3_DEVKIT=y
@@ -18,27 +15,21 @@ CONFIG_ARCH_INTERRUPTSTACK=1536
CONFIG_ARCH_RISCV=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BOARD_LOOPSPERMSEC=16717
+CONFIG_BTSAK=y
CONFIG_BUILTIN=y
+CONFIG_DRIVERS_BLUETOOTH=y
CONFIG_DRIVERS_IEEE80211=y
CONFIG_DRIVERS_WIRELESS=y
-CONFIG_ESP32C3_WIRELESS=y
+CONFIG_ESP32C3_BLE=y
CONFIG_FS_PROCFS=y
CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=3072
CONFIG_INTELHEX_BINARY=y
-CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_NAME_MAX=48
-CONFIG_NETDB_DNSCLIENT=y
-CONFIG_NETDEV_LATEINIT=y
-CONFIG_NETDEV_PHY_IOCTL=y
-CONFIG_NETDEV_WIRELESS_IOCTL=y
-CONFIG_NET_BROADCAST=y
-CONFIG_NET_ETH_PKTSIZE=1514
-CONFIG_NET_ICMP=y
-CONFIG_NET_ICMP_SOCKET=y
+CONFIG_NET_BLUETOOTH=y
+CONFIG_NET_SOCKOPTS=y
CONFIG_NET_TCP=y
-CONFIG_NET_UDP=y
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_FILEIOSIZE=512
@@ -48,18 +39,11 @@ CONFIG_PREALLOC_TIMERS=4
CONFIG_PTHREAD_MUTEX_TYPES=y
CONFIG_RAW_BINARY=y
CONFIG_RR_INTERVAL=200
-CONFIG_SCHED_LPWORK=y
CONFIG_SCHED_WAITPID=y
CONFIG_SIG_DEFAULT=y
-CONFIG_START_DAY=6
-CONFIG_START_MONTH=12
-CONFIG_START_YEAR=2011
-CONFIG_SYSTEM_DHCPC_RENEW=y
+CONFIG_SPINLOCK=y
CONFIG_SYSTEM_NSH=y
-CONFIG_SYSTEM_PING=y
CONFIG_UART0_SERIAL_CONSOLE=y
CONFIG_USER_ENTRYPOINT="nsh_main"
CONFIG_WIRELESS=y
-CONFIG_WIRELESS_WAPI=y
-CONFIG_WIRELESS_WAPI_CMDTOOL=y
-CONFIG_WIRELESS_WAPI_STACKSIZE=4096
+CONFIG_WIRELESS_BLUETOOTH=y
diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/configs/sta_softap/defconfig b/boards/risc-v/esp32c3/esp32c3-devkit/configs/sta_softap/defconfig
index 12f0332..aca1681 100644
--- a/boards/risc-v/esp32c3/esp32c3-devkit/configs/sta_softap/defconfig
+++ b/boards/risc-v/esp32c3/esp32c3-devkit/configs/sta_softap/defconfig
@@ -32,7 +32,7 @@ CONFIG_ESP32C3_MTD_SIZE=0xf0000
CONFIG_ESP32C3_SPIFLASH=y
CONFIG_ESP32C3_WIFI_SAVE_PARAM=y
CONFIG_ESP32C3_WIFI_STATION_SOFTAP_COEXISTENCE=y
-CONFIG_ESP32C3_WIRELESS=y
+CONFIG_ESP32C3_WIFI=y
CONFIG_EXAMPLES_DHCPD=y
CONFIG_EXPERIMENTAL=y
CONFIG_FS_PROCFS=y
diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/configs/wapi/defconfig b/boards/risc-v/esp32c3/esp32c3-devkit/configs/wapi/defconfig
index 96f6cbf..acff433 100644
--- a/boards/risc-v/esp32c3/esp32c3-devkit/configs/wapi/defconfig
+++ b/boards/risc-v/esp32c3/esp32c3-devkit/configs/wapi/defconfig
@@ -21,7 +21,7 @@ CONFIG_BOARD_LOOPSPERMSEC=16717
CONFIG_BUILTIN=y
CONFIG_DRIVERS_IEEE80211=y
CONFIG_DRIVERS_WIRELESS=y
-CONFIG_ESP32C3_WIRELESS=y
+CONFIG_ESP32C3_WIFI=y
CONFIG_FS_PROCFS=y
CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_bringup.c b/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_bringup.c
index 550a133..15297a7 100644
--- a/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_bringup.c
+++ b/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_bringup.c
@@ -67,6 +67,10 @@
# include "esp32c3_rtc_lowerhalf.h"
#endif
+#ifdef CONFIG_ESP32C3_BLE
+# include "esp32c3_ble.h"
+#endif
+
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
@@ -303,10 +307,20 @@ int esp32c3_bringup(void)
if (ret < 0)
{
syslog(LOG_ERR, "Failed to initialize RT timer: %d\n", ret);
+ return ret;
+ }
+#endif
+
+#ifdef CONFIG_ESP32C3_BLE
+ ret = esp32c3_ble_initialize();
+ if (ret)
+ {
+ syslog(LOG_ERR, "ERROR: Failed to initialize BLE\n");
+ return ret;
}
#endif
-#ifdef CONFIG_ESP32C3_WIRELESS
+#ifdef CONFIG_ESP32C3_WIFI
#ifdef CONFIG_ESP32C3_WIFI_SAVE_PARAM
ret = esp32c3_init_wifi_storage();