You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by GitBox <gi...@apache.org> on 2021/09/10 13:37:59 UTC

[GitHub] [incubator-nuttx] acassis opened a new pull request #4509: esp32: Add initial support to Bluetooth Low Energy

acassis opened a new pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509


   ## Summary
   Add initial support to Bluetooth Low Energy
   ## Impact
   User will be able to use BLE on ESP32 chips
   ## Testing
   esp32-devkit
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716266398



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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");

Review comment:
       ```suggestion
             wlerr("Failed to wait sem %d\n", ret);
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716262020



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }

Review comment:
       ```suggestion
     return 0;
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716269689



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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

Review comment:
       Update




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715180456



##########
File path: arch/xtensa/src/esp32/esp32_ble.c
##########
@@ -0,0 +1,344 @@
+/****************************************************************************
+ * 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 HCI comand will callback this function.
+ *
+ * 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 receive packet

Review comment:
       ```suggestion
    *   BLE receive callback function when BLE hardware receives a packet.
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715190971



##########
File path: arch/xtensa/src/esp32/esp32_ble.c
##########
@@ -0,0 +1,344 @@
+/****************************************************************************
+ * 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 HCI comand will callback this function.
+ *
+ * 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 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 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)
+    {
+      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-C3 BLE send callback function for BT driver.

Review comment:
       There are other occurrences, please fix.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716269727



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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:
+ *   ESP32C3 BLE lightsleep callback function.

Review comment:
       ```suggestion
    *   ESP32 BLE lightsleep callback function.
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715192255



##########
File path: 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_RISCV_SRC_ESP32_ESP32_BLE_H
+#define __ARCH_RISCV_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_RISCV_SRC_ESP32_ESP32_BLE_H */

Review comment:
       ```suggestion
   #endif /* __ARCH_XTENSA_SRC_ESP32_ESP32_BLE_H */
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716259149



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  return NULL;
+}

Review comment:
       Alan, please add the functions' headers and I believe these debug messages are here by mistake. Are they? 




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716953633



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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

Review comment:
       ```suggestion
    *   item          - Item to be sent. 
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715187316



##########
File path: arch/xtensa/src/esp32/esp32_ble.c
##########
@@ -0,0 +1,344 @@
+/****************************************************************************
+ * 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 HCI comand will callback this function.
+ *
+ * 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 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 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)
+    {
+      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-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 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;

Review comment:
       why are u initializing `hdr` if it's overwritten below?
   And if it's not written at all it throws an error.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716261564



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+static bool is_wifi_clk_peripheral(periph_module_e periph)

Review comment:
       Add header.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] acassis commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
acassis commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r717880425



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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 */

Review comment:
       Agree, it could become boolean!

##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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)

Review comment:
       I cannot convert it to bool because it is returned by many wrapper function that aren't expecting boolean type!




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] gustavonihei commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
gustavonihei commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r718553018



##########
File path: arch/xtensa/src/esp32/Kconfig
##########
@@ -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 simultaneos connections"

Review comment:
       ```suggestion
   	int "Maximum BLE simultaneous connections"
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716268520



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr

Review comment:
       alignment




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716960461



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;

Review comment:
       ```suggestion
         return -ERROR;
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716973366



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      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 -1;
+    }
+
+  btdm_controller_deinit();
+
+  if (g_lp_stat.phy_enabled)
+    {
+      bt_phy_disable();
+      g_lp_stat.phy_enabled = 0;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+
+#ifdef CONFIG_PM
+  /* deinit low power control resources */
+
+  g_lp_stat.pm_lock_released = 0;
+
+  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 = 0;
+      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

Review comment:
       Update

##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      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 -1;
+    }
+
+  btdm_controller_deinit();
+
+  if (g_lp_stat.phy_enabled)
+    {
+      bt_phy_disable();
+      g_lp_stat.phy_enabled = 0;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+
+#ifdef CONFIG_PM
+  /* deinit low power control resources */
+
+  g_lp_stat.pm_lock_released = 0;
+
+  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 = 0;
+      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 -1;
+    }
+
+  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 == 0)
+    {
+      esp32_pm_lockrelease();
+      g_lp_stat.pm_lock_released = 1;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+#endif
+
+  return 0;

Review comment:
       ```suggestion
     return OK;
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716261564



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+static bool is_wifi_clk_peripheral(periph_module_e periph)

Review comment:
       Add header here and in the others missing one.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716974994



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      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 -1;
+    }
+
+  btdm_controller_deinit();
+
+  if (g_lp_stat.phy_enabled)
+    {
+      bt_phy_disable();
+      g_lp_stat.phy_enabled = 0;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+
+#ifdef CONFIG_PM
+  /* deinit low power control resources */
+
+  g_lp_stat.pm_lock_released = 0;
+
+  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 = 0;
+      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 -1;
+    }
+
+  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 == 0)
+    {
+      esp32_pm_lockrelease();
+      g_lp_stat.pm_lock_released = 1;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+#endif
+
+  return 0;
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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 = 0;
+
+  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;

Review comment:
       ```suggestion
         ret = -ERROR;
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716265403



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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;

Review comment:
       ```suggestion
             esp_errno_trans(ret);
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716953892



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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)

Review comment:
       1 line only




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716266332



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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);

Review comment:
       You can take a shortcut by using
   
   ```suggestion
     return esp_errno_trans(sem_trywait(semphr));
   ```
   
   `sem_trywait` will do the same, since the waiting time is 0.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716265230



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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

Review comment:
       Return type and returned value diverges.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715178207



##########
File path: arch/xtensa/src/esp32/esp32_ble.c
##########
@@ -0,0 +1,344 @@
+/****************************************************************************
+ * 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,

Review comment:
       Is it related to `UART_BTH4`?
   Shouldn't it be protected with guards only if `CONFIG_UART_BTH4` is enabled?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715175243



##########
File path: arch/xtensa/src/esp32/Make.defs
##########
@@ -229,7 +229,13 @@ 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 -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 -lrtc -lcoexist #-lbtbb

Review comment:
       ```suggestion
   EXTRA_LIBS += -lbtdm_app  -lcoexist ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] acassis commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
acassis commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r717977589



##########
File path: arch/xtensa/src/esp32/esp32_ble.c
##########
@@ -0,0 +1,344 @@
+/****************************************************************************
+ * 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 HCI comand will callback this function.
+ *
+ * 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 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 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)
+    {
+      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-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 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;

Review comment:
       It is not creating a new variable, it is a pointer to a memory position

##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */

Review comment:
       Ok

##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* BLE message queue private data */
+
+struct mq_adpt_s
+{
+  struct file mq;           /* Message queue handle */

Review comment:
       It is aligned already:
   ```
   struct mq_adpt_s
   {
     struct file mq;           /* Message queue handle */
     uint32_t    msgsize;      /* Message size */
     char        name[16];     /* Message queue name */
   };
   ```

##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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);
+

Review comment:
       Ok!




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715195801



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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);

Review comment:
       ```suggestion
   typedef void (*coex_func_cb_t)(uint32_t event, int sched_cnt);
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715207173



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* BLE message queue private data */
+
+struct mq_adpt_s
+{
+  struct file mq;           /* Message queue handle */

Review comment:
       align this field with others




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716982931



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      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 -1;
+    }
+
+  btdm_controller_deinit();
+
+  if (g_lp_stat.phy_enabled)
+    {
+      bt_phy_disable();
+      g_lp_stat.phy_enabled = 0;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+
+#ifdef CONFIG_PM
+  /* deinit low power control resources */
+
+  g_lp_stat.pm_lock_released = 0;
+
+  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 = 0;
+      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 -1;
+    }
+
+  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 == 0)
+    {
+      esp32_pm_lockrelease();
+      g_lp_stat.pm_lock_released = 1;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+#endif
+
+  return 0;
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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 = 0;
+
+  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 == 0)
+    {
+      esp32_pm_lockrelease();
+      g_lp_stat.pm_lock_released = 1;
+    }
+#endif
+
+  return ret;
+}
+
+esp_bt_controller_status_t esp32_bt_controller_get_status(void)
+{
+  return btdm_controller_status;
+}
+
+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;
+}
+
+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;
+}
+
+static bool coex_bt_wakeup_request(void)
+{
+  return async_wakeup_request(BTDM_ASYNC_WAKEUP_REQ_COEX);
+}
+
+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 point

Review comment:
       ```suggestion
    *  data - the packet pointer
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715181634



##########
File path: arch/xtensa/src/esp32/esp32_ble.c
##########
@@ -0,0 +1,344 @@
+/****************************************************************************
+ * 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 HCI comand will callback this function.
+ *
+ * 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 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 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)

Review comment:
       ```suggestion
     if (valid == false)
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715179493



##########
File path: arch/xtensa/src/esp32/esp32_ble.c
##########
@@ -0,0 +1,344 @@
+/****************************************************************************
+ * 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 HCI comand will callback this function.

Review comment:
       ```suggestion
    *   If the controller could send an HCI command, this function is called.
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716269582



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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.

Review comment:
       ```suggestion
    *   ESP BLE sleep callback function.
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716270112



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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:
+ *   ESP32C3 BLE lightsleep callback function.
+ *
+ * Input Parameters:
+ *   lpcycles - light sleep cycles
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void btdm_sleep_enter_phase1_wrapper(uint32_t lpcycles)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  else
+    {
+      wlerr("timer start failed");
+      DEBUGASSERT(0);
+    }
+}
+
+/****************************************************************************
+ * Name: btdm_sleep_enter_phase2_wrapper
+ *
+ * Description:
+ *   ESP32C3 BLE lightsleep callback function.

Review comment:
       ```suggestion
    *   ESP32 BLE lightsleep callback function.
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716994102



##########
File path: boards/xtensa/esp32/esp32-devkitc/src/esp32_bringup.c
##########
@@ -207,6 +211,15 @@ int esp32_bringup(void)
     }
 #endif
 
+#ifdef CONFIG_ESP32_BLE
+  ret = esp32_ble_initialize();
+  if (ret)
+    {
+      syslog(LOG_ERR, "ERROR: Failed to initialize BLE\n");
+      return ret;

Review comment:
       ```suggestion
   ```
   Rmv it since we decided not to break the initialization if one fails




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716950616



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)

Review comment:
       ```suggestion
     if (cal_data == NULL)
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716984667



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      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 -1;
+    }
+
+  btdm_controller_deinit();
+
+  if (g_lp_stat.phy_enabled)
+    {
+      bt_phy_disable();
+      g_lp_stat.phy_enabled = 0;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+
+#ifdef CONFIG_PM
+  /* deinit low power control resources */
+
+  g_lp_stat.pm_lock_released = 0;
+
+  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 = 0;
+      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 -1;
+    }
+
+  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 == 0)
+    {
+      esp32_pm_lockrelease();
+      g_lp_stat.pm_lock_released = 1;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+#endif
+
+  return 0;
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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 = 0;
+
+  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 == 0)
+    {
+      esp32_pm_lockrelease();
+      g_lp_stat.pm_lock_released = 1;
+    }
+#endif
+
+  return ret;
+}
+
+esp_bt_controller_status_t esp32_bt_controller_get_status(void)
+{
+  return btdm_controller_status;
+}
+
+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;
+}
+
+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;
+}
+
+static bool coex_bt_wakeup_request(void)
+{
+  return async_wakeup_request(BTDM_ASYNC_WAKEUP_REQ_COEX);
+}
+
+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 point
+ *  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.

Review comment:
       ```suggestion
    *    Register the vhci reference callback.
    *
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715188907



##########
File path: arch/xtensa/src/esp32/esp32_ble.c
##########
@@ -0,0 +1,344 @@
+/****************************************************************************
+ * 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 HCI comand will callback this function.
+ *
+ * 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 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 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)
+    {
+      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-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 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 -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 (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 on success or a negated value on failure.

Review comment:
       ```suggestion
    *   OK
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716259712



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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)

Review comment:
       ```suggestion
   static inline bool esp_errno_trans(int ret)
   ```
   Are Wi-Fi error codes simply false and true?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716964657



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      err = -ENOMEM;
+      goto error;
+    }

Review comment:
       Add a message error, use the return of the function to expose the error.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716973640



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      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 -1;
+    }
+
+  btdm_controller_deinit();
+
+  if (g_lp_stat.phy_enabled)
+    {
+      bt_phy_disable();
+      g_lp_stat.phy_enabled = 0;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+
+#ifdef CONFIG_PM
+  /* deinit low power control resources */
+
+  g_lp_stat.pm_lock_released = 0;
+
+  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 = 0;
+      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 -1;
+    }
+
+  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 == 0)
+    {
+      esp32_pm_lockrelease();
+      g_lp_stat.pm_lock_released = 1;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+#endif
+
+  return 0;
+}
+
+/****************************************************************************
+ * 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 -1;

Review comment:
       ```suggestion
         return -ERROr;
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716963956



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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);

Review comment:
       Shouldn't it be done through some clock config API?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716965001



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      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.

Review comment:
       ```suggestion
    *    Deinit  BT controller.
    *
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715201425



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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)

Review comment:
       ```suggestion
   #define XTHAL_SET_INTSET(v) 
   (
     int __interrupt = (int)(v);
     __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
   )
   ```
   I didn't understand why to use `do {} while(0)`




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716263913



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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();
+}

Review comment:
       Alan, please talk to @Ouss4 and see if here it's not the case of using `spin_lock_irqsave`.
   Besides that, what's the real purpose of this function because its name is `interrupt_disable` but the description is to enter critical section. If it's only to disable interrupts you may use `up_irq_save`




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716264492



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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

Review comment:
       Should be in an Output Parameters section.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716269942



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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:
+ *   ESP32C3 BLE lightsleep callback function.
+ *
+ * Input Parameters:
+ *   lpcycles - light sleep cycles
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void btdm_sleep_enter_phase1_wrapper(uint32_t lpcycles)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t uncertainty = (us_to_sleep >> 11);

Review comment:
       Do the declaration of these variables in the beginning of
    the function.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716991309



##########
File path: arch/xtensa/src/esp32/esp32_wifi_adapter.c
##########
@@ -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)
+            {

Review comment:
       Add some reference/explanation here.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716987217



##########
File path: 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_RISCV_SRC_ESP32_ESP32_BLE_ADAPTER_H
+#define __ARCH_RISCV_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_RISCV_SRC_ESP32_ESP32_BLE_ADAPTER_H */

Review comment:
       ```suggestion
   #endif /* __ARCH_XTENSA_SRC_ESP32_ESP32_BLE_ADAPTER_H */
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716269502



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)

Review comment:
       If the lock is not acquired, should it continue and stop the timer?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716949459



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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:
+ *   ESP32C3 BLE lightsleep callback function.
+ *
+ * Input Parameters:
+ *   lpcycles - light sleep cycles
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void btdm_sleep_enter_phase1_wrapper(uint32_t lpcycles)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  else
+    {
+      wlerr("timer start failed");
+      DEBUGASSERT(0);
+    }
+}
+
+/****************************************************************************
+ * Name: btdm_sleep_enter_phase2_wrapper
+ *
+ * Description:
+ *   ESP32C3 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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * Name: btdm_sleep_exit_phase3_wrapper
+ *
+ * Description:
+ *   ESP32C3 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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();

Review comment:
       P.S: There are multiple occurrences I haven't marked.

##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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.

Review comment:
       ```suggestion
    *    Disable BT phy.
    
   ```

##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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.

Review comment:
       ```suggestion
    *    Enable BT phy.
    
   ```

##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)

Review comment:
       ```suggestion
     if (cal_data == NULL)
   ```

##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\n");

Review comment:
       ```suggestion
         wlerr("Failed to create mqueue %d \n", ret);
   ```

##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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

Review comment:
       ```suggestion
    *   item          - Item to be sent. 
   ```

##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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)

Review comment:
       1 line only

##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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");

Review comment:
       ```suggestion
             wlerr("Failed to get time %d\n", ret);
   ```

##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;

Review comment:
       ```suggestion
         return -ERROR;
   ```

##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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);

Review comment:
       Shouldn't it be done through some clock config API?

##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      err = -ENOMEM;
+      goto error;
+    }

Review comment:
       Add a message error, use the return of the function to expose the error.

##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      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.

Review comment:
       ```suggestion
    *    Deinit  BT controller.
    *
   ```

##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      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 -1;

Review comment:
       ```suggestion
         return -ERROR;
   ```

##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      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 -1;
+    }
+
+  btdm_controller_deinit();

Review comment:
       Is it necessary to deinit? The check before is not intended to check if it was previously initialized?

##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      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 -1;
+    }
+
+  btdm_controller_deinit();
+
+  if (g_lp_stat.phy_enabled)
+    {
+      bt_phy_disable();
+      g_lp_stat.phy_enabled = 0;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+
+#ifdef CONFIG_PM
+  /* deinit low power control resources */
+
+  g_lp_stat.pm_lock_released = 0;
+
+  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 = 0;
+      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.

Review comment:
       ```suggestion
    *    Disable  BT controller.
   ```

##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      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 -1;
+    }
+
+  btdm_controller_deinit();
+
+  if (g_lp_stat.phy_enabled)
+    {
+      bt_phy_disable();
+      g_lp_stat.phy_enabled = 0;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+
+#ifdef CONFIG_PM
+  /* deinit low power control resources */
+
+  g_lp_stat.pm_lock_released = 0;
+
+  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 = 0;
+      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 -1;

Review comment:
       ```suggestion
         return -ERROR;
   ```

##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      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 -1;
+    }
+
+  btdm_controller_deinit();
+
+  if (g_lp_stat.phy_enabled)
+    {
+      bt_phy_disable();
+      g_lp_stat.phy_enabled = 0;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+
+#ifdef CONFIG_PM
+  /* deinit low power control resources */
+
+  g_lp_stat.pm_lock_released = 0;
+
+  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 = 0;
+      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

Review comment:
       Update

##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      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 -1;
+    }
+
+  btdm_controller_deinit();
+
+  if (g_lp_stat.phy_enabled)
+    {
+      bt_phy_disable();
+      g_lp_stat.phy_enabled = 0;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+
+#ifdef CONFIG_PM
+  /* deinit low power control resources */
+
+  g_lp_stat.pm_lock_released = 0;
+
+  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 = 0;
+      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 -1;
+    }
+
+  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 == 0)
+    {
+      esp32_pm_lockrelease();
+      g_lp_stat.pm_lock_released = 1;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+#endif
+
+  return 0;

Review comment:
       ```suggestion
     return OK;
   ```

##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      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 -1;
+    }
+
+  btdm_controller_deinit();
+
+  if (g_lp_stat.phy_enabled)
+    {
+      bt_phy_disable();
+      g_lp_stat.phy_enabled = 0;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+
+#ifdef CONFIG_PM
+  /* deinit low power control resources */
+
+  g_lp_stat.pm_lock_released = 0;
+
+  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 = 0;
+      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 -1;
+    }
+
+  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 == 0)
+    {
+      esp32_pm_lockrelease();
+      g_lp_stat.pm_lock_released = 1;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+#endif
+
+  return 0;
+}
+
+/****************************************************************************
+ * 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 -1;

Review comment:
       ```suggestion
         return -ERROr;
   ```

##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      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 -1;
+    }
+
+  btdm_controller_deinit();
+
+  if (g_lp_stat.phy_enabled)
+    {
+      bt_phy_disable();
+      g_lp_stat.phy_enabled = 0;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+
+#ifdef CONFIG_PM
+  /* deinit low power control resources */
+
+  g_lp_stat.pm_lock_released = 0;
+
+  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 = 0;
+      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 -1;
+    }
+
+  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 == 0)
+    {
+      esp32_pm_lockrelease();
+      g_lp_stat.pm_lock_released = 1;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+#endif
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp32_bt_controller_enable
+ *
+ * Description:
+ *    Enable  BT controller.
+ * Input Parameters:
+ *    None
+ *
+ * Returned Value:
+ *    None

Review comment:
       Update

##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      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 -1;
+    }
+
+  btdm_controller_deinit();
+
+  if (g_lp_stat.phy_enabled)
+    {
+      bt_phy_disable();
+      g_lp_stat.phy_enabled = 0;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+
+#ifdef CONFIG_PM
+  /* deinit low power control resources */
+
+  g_lp_stat.pm_lock_released = 0;
+
+  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 = 0;
+      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 -1;
+    }
+
+  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 == 0)
+    {
+      esp32_pm_lockrelease();
+      g_lp_stat.pm_lock_released = 1;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+#endif
+
+  return 0;
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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 = 0;
+
+  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;

Review comment:
       ```suggestion
         ret = -ERROR;
   ```

##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      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 -1;
+    }
+
+  btdm_controller_deinit();
+
+  if (g_lp_stat.phy_enabled)
+    {
+      bt_phy_disable();
+      g_lp_stat.phy_enabled = 0;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+
+#ifdef CONFIG_PM
+  /* deinit low power control resources */
+
+  g_lp_stat.pm_lock_released = 0;
+
+  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 = 0;
+      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 -1;
+    }
+
+  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 == 0)
+    {
+      esp32_pm_lockrelease();
+      g_lp_stat.pm_lock_released = 1;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+#endif
+
+  return 0;
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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 = 0;
+
+  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 == 0)
+    {
+      esp32_pm_lockrelease();
+      g_lp_stat.pm_lock_released = 1;
+    }
+#endif
+
+  return ret;
+}
+
+esp_bt_controller_status_t esp32_bt_controller_get_status(void)

Review comment:
       Header

##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      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 -1;
+    }
+
+  btdm_controller_deinit();
+
+  if (g_lp_stat.phy_enabled)
+    {
+      bt_phy_disable();
+      g_lp_stat.phy_enabled = 0;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+
+#ifdef CONFIG_PM
+  /* deinit low power control resources */
+
+  g_lp_stat.pm_lock_released = 0;
+
+  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 = 0;
+      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 -1;
+    }
+
+  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 == 0)
+    {
+      esp32_pm_lockrelease();
+      g_lp_stat.pm_lock_released = 1;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+#endif
+
+  return 0;
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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 = 0;
+
+  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 == 0)
+    {
+      esp32_pm_lockrelease();
+      g_lp_stat.pm_lock_released = 1;
+    }
+#endif
+
+  return ret;
+}
+
+esp_bt_controller_status_t esp32_bt_controller_get_status(void)
+{
+  return btdm_controller_status;
+}
+
+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;
+}
+
+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;
+}
+
+static bool coex_bt_wakeup_request(void)
+{
+  return async_wakeup_request(BTDM_ASYNC_WAKEUP_REQ_COEX);
+}
+
+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.

Review comment:
       ```suggestion
    *    Host send packet to controller.
   ```

##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      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 -1;
+    }
+
+  btdm_controller_deinit();
+
+  if (g_lp_stat.phy_enabled)
+    {
+      bt_phy_disable();
+      g_lp_stat.phy_enabled = 0;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+
+#ifdef CONFIG_PM
+  /* deinit low power control resources */
+
+  g_lp_stat.pm_lock_released = 0;
+
+  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 = 0;
+      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 -1;
+    }
+
+  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 == 0)
+    {
+      esp32_pm_lockrelease();
+      g_lp_stat.pm_lock_released = 1;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+#endif
+
+  return 0;
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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 = 0;
+
+  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 == 0)
+    {
+      esp32_pm_lockrelease();
+      g_lp_stat.pm_lock_released = 1;
+    }
+#endif
+
+  return ret;
+}
+
+esp_bt_controller_status_t esp32_bt_controller_get_status(void)
+{
+  return btdm_controller_status;
+}
+
+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;
+}
+
+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;
+}
+
+static bool coex_bt_wakeup_request(void)
+{
+  return async_wakeup_request(BTDM_ASYNC_WAKEUP_REQ_COEX);
+}
+
+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 point

Review comment:
       ```suggestion
    *  data - the packet pointer
   ```

##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      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 -1;
+    }
+
+  btdm_controller_deinit();
+
+  if (g_lp_stat.phy_enabled)
+    {
+      bt_phy_disable();
+      g_lp_stat.phy_enabled = 0;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+
+#ifdef CONFIG_PM
+  /* deinit low power control resources */
+
+  g_lp_stat.pm_lock_released = 0;
+
+  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 = 0;
+      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 -1;
+    }
+
+  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 == 0)
+    {
+      esp32_pm_lockrelease();
+      g_lp_stat.pm_lock_released = 1;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+#endif
+
+  return 0;
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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 = 0;
+
+  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 == 0)
+    {
+      esp32_pm_lockrelease();
+      g_lp_stat.pm_lock_released = 1;
+    }
+#endif
+
+  return ret;
+}
+
+esp_bt_controller_status_t esp32_bt_controller_get_status(void)
+{
+  return btdm_controller_status;
+}
+
+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;
+}
+
+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;
+}
+
+static bool coex_bt_wakeup_request(void)
+{
+  return async_wakeup_request(BTDM_ASYNC_WAKEUP_REQ_COEX);
+}
+
+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 point
+ *  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.

Review comment:
       ```suggestion
    *    Register the vhci reference callback.
    *
   ```

##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      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 -1;
+    }
+
+  btdm_controller_deinit();
+
+  if (g_lp_stat.phy_enabled)
+    {
+      bt_phy_disable();
+      g_lp_stat.phy_enabled = 0;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+
+#ifdef CONFIG_PM
+  /* deinit low power control resources */
+
+  g_lp_stat.pm_lock_released = 0;
+
+  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 = 0;
+      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 -1;
+    }
+
+  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 == 0)
+    {
+      esp32_pm_lockrelease();
+      g_lp_stat.pm_lock_released = 1;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+#endif
+
+  return 0;
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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 = 0;
+
+  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 == 0)
+    {
+      esp32_pm_lockrelease();
+      g_lp_stat.pm_lock_released = 1;
+    }
+#endif
+
+  return ret;
+}
+
+esp_bt_controller_status_t esp32_bt_controller_get_status(void)
+{
+  return btdm_controller_status;
+}
+
+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;
+}
+
+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;
+}
+
+static bool coex_bt_wakeup_request(void)
+{
+  return async_wakeup_request(BTDM_ASYNC_WAKEUP_REQ_COEX);
+}
+
+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 point
+ *  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 = -1;

Review comment:
       ```suggestion
     int ret = -ERROR;
   ```

##########
File path: 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_RISCV_SRC_ESP32_ESP32_BLE_ADAPTER_H
+#define __ARCH_RISCV_SRC_ESP32_ESP32_BLE_ADAPTER_H

Review comment:
       ```suggestion
   #ifndef __ARCH_XTENSA_SRC_ESP32_ESP32_BLE_ADAPTER_H
   #define __ARCH_XTENSA_SRC_ESP32_ESP32_BLE_ADAPTER_H
   ```

##########
File path: 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_RISCV_SRC_ESP32_ESP32_BLE_ADAPTER_H
+#define __ARCH_RISCV_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

Review comment:
       Please make sure to apply the changes I suggested on the functions' definition also in the prototypes.  

##########
File path: 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_RISCV_SRC_ESP32_ESP32_BLE_ADAPTER_H
+#define __ARCH_RISCV_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_RISCV_SRC_ESP32_ESP32_BLE_ADAPTER_H */

Review comment:
       ```suggestion
   #endif /* __ARCH_XTENSA_SRC_ESP32_ESP32_BLE_ADAPTER_H */
   ```

##########
File path: arch/xtensa/src/esp32/esp32_wifi_adapter.c
##########
@@ -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)
+            {

Review comment:
       Add some reference/explanation here.

##########
File path: arch/xtensa/src/esp32/hardware/esp32_dport.h
##########
@@ -1185,6 +1185,7 @@
 #define DPORT_SLAVE_SPI_MASK_PRO_S  0
 
 #define DPORT_WIFI_CLK_EN_REG          (DR_REG_DPORT_BASE + 0x0CC)

Review comment:
       ```suggestion
   #define DPORT_WIFI_CLK_EN_REG          (DR_REG_DPORT_BASE + 0x0cc)
   ```

##########
File path: boards/xtensa/esp32/esp32-devkitc/src/esp32_bringup.c
##########
@@ -207,6 +211,15 @@ int esp32_bringup(void)
     }
 #endif
 
+#ifdef CONFIG_ESP32_BLE
+  ret = esp32_ble_initialize();
+  if (ret)
+    {
+      syslog(LOG_ERR, "ERROR: Failed to initialize BLE\n");

Review comment:
       ```suggestion
         syslog(LOG_ERR, "ERROR: Failed to initialize BLE: %d \n", ret);
   ```

##########
File path: boards/xtensa/esp32/esp32-devkitc/src/esp32_bringup.c
##########
@@ -207,6 +211,15 @@ int esp32_bringup(void)
     }
 #endif
 
+#ifdef CONFIG_ESP32_BLE
+  ret = esp32_ble_initialize();
+  if (ret)
+    {
+      syslog(LOG_ERR, "ERROR: Failed to initialize BLE\n");
+      return ret;

Review comment:
       ```suggestion
   ```
   Rmv it since we decided not to break the initialization if one fails




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716949459



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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:
+ *   ESP32C3 BLE lightsleep callback function.
+ *
+ * Input Parameters:
+ *   lpcycles - light sleep cycles
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void btdm_sleep_enter_phase1_wrapper(uint32_t lpcycles)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  else
+    {
+      wlerr("timer start failed");
+      DEBUGASSERT(0);
+    }
+}
+
+/****************************************************************************
+ * Name: btdm_sleep_enter_phase2_wrapper
+ *
+ * Description:
+ *   ESP32C3 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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * Name: btdm_sleep_exit_phase3_wrapper
+ *
+ * Description:
+ *   ESP32C3 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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();

Review comment:
       P.S: There are multiple occurrences I haven't marked.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715211505



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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);
+

Review comment:
       rmv blank lines




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715209125



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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 */

Review comment:
       Why aren't they boolean?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715183163



##########
File path: arch/xtensa/src/esp32/esp32_ble.c
##########
@@ -0,0 +1,344 @@
+/****************************************************************************
+ * 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 HCI comand will callback this function.
+ *
+ * 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 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 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)
+    {
+      ret = ERROR;

Review comment:
       ```suggestion
         wlerr("Invalid H4 header \n");
         ret = ERROR;
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715177050



##########
File path: arch/xtensa/src/esp32/esp32_ble.c
##########
@@ -0,0 +1,344 @@
+/****************************************************************************
+ * 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);

Review comment:
       nit: alignment.
   and you can also place 2nd param in the first line




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716269177



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;

Review comment:
       Place it in the beginning of the function




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715210811



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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);

Review comment:
       Please, remove the extra space after * in the other parts




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716263937



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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);
+}

Review comment:
       The same discussion above.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716266431



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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;

Review comment:
       ```suggestion
             return esp_errno_trans(ret);
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715184105



##########
File path: arch/xtensa/src/esp32/esp32_ble.c
##########
@@ -0,0 +1,344 @@
+/****************************************************************************
+ * 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 HCI comand will callback this function.
+ *
+ * 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 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 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)
+    {
+      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-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 esp32_ble_send(struct bt_driver_s *drv,
+                            enum bt_buf_type_e type,
+                            void *data, size_t len)

Review comment:
       Fix alignment and mv param to 1st line




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716268011



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */

Review comment:
       ?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716268907



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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;

Review comment:
       Add the math formula and add some explanation.
   If it's from a code or TRM, do the reference.
   For example: https://github.com/apache/incubator-nuttx/blob/master/arch/xtensa/src/esp32s2/esp32s2_rt_timer.c#L756-L778
   It will help on future maintenance. 




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715175243



##########
File path: arch/xtensa/src/esp32/Make.defs
##########
@@ -229,7 +229,13 @@ 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 -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 -lrtc -lcoexist #-lbtbb

Review comment:
       ```suggestion
   EXTRA_LIBS += -lbtdm_app -lcoexist
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715204138



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */

Review comment:
       ```suggestion
   #define BTDM_MIN_SLEEP_DURATION          (24) /* Threshold of interval in half slots to allow to fall into sleep mode */
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715207478



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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 */

Review comment:
       Use some macro for 16




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716950316



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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.

Review comment:
       ```suggestion
    *    Enable BT phy.
    
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716270061



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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:
+ *   ESP32C3 BLE lightsleep callback function.
+ *
+ * Input Parameters:
+ *   lpcycles - light sleep cycles
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void btdm_sleep_enter_phase1_wrapper(uint32_t lpcycles)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);

Review comment:
       why not to check `g_lp_stat.wakeup_timer_started` together with the same `if`?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] acassis commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
acassis commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r719470870



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)

Review comment:
       Yes, see btdm_sleep_exit_phase0()




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] acassis commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
acassis commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716709467



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */

Review comment:
       It was a msg to the Alan of the future, hehehe




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] gustavonihei commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
gustavonihei commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r720441314



##########
File path: 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

Review comment:
       I believe the BLE defconfig does not need to enable support for IEEE802.11.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] acassis commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
acassis commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r717977589



##########
File path: arch/xtensa/src/esp32/esp32_ble.c
##########
@@ -0,0 +1,344 @@
+/****************************************************************************
+ * 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 HCI comand will callback this function.
+ *
+ * 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 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 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)
+    {
+      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-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 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;

Review comment:
       It is not creating a new variable, it is a pointer to a memory position




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] acassis commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
acassis commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r717978935



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* BLE message queue private data */
+
+struct mq_adpt_s
+{
+  struct file mq;           /* Message queue handle */

Review comment:
       It is aligned already:
   ```
   struct mq_adpt_s
   {
     struct file mq;           /* Message queue handle */
     uint32_t    msgsize;      /* Message size */
     char        name[16];     /* Message queue name */
   };
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] gustavonihei commented on pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
gustavonihei commented on pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#issuecomment-932214389


   Some nxstyle errors still need fixing:
   ![image](https://user-images.githubusercontent.com/38959758/135625098-43d3aaf0-c919-4457-8a84-b206cd64e841.png)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716987015



##########
File path: 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_RISCV_SRC_ESP32_ESP32_BLE_ADAPTER_H
+#define __ARCH_RISCV_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

Review comment:
       Please make sure to apply the changes I suggested on the functions' definition also in the prototypes.  




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716258974



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;

Review comment:
       ```suggestion
     return -ERROR;
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715189178



##########
File path: arch/xtensa/src/esp32/esp32_ble.c
##########
@@ -0,0 +1,344 @@
+/****************************************************************************
+ * 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 HCI comand will callback this function.
+ *
+ * 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 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 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)
+    {
+      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-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 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 -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 (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 on success or a negated value on failure.
+ *
+ ****************************************************************************/
+
+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:
+ *   success or fail

Review comment:
       ```suggestion
    *   OK on success or a negated value on failure.
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716262744



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),

Review comment:
       Make sure this reset register doesn't need to first be set to 1 and then be set to 0.
   I've been seen many reset procedures like this one in our chips. Must to be different for Wi-Fi regs.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716267271



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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;

Review comment:
       ```suggestion
             wlerr("Failed to get time %d\n", ret);
             return esp_errno_trans(ret);
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] Ouss4 commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
Ouss4 commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716514601



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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();
+}

Review comment:
       > if it's only to disable interrupts you may use up_irq_save
   
   Yes, if we only need to disable interrupts in the current CPU, `up_irq_save` should be used.
   
   For replacing `enter_critical_section` with `spin_lock_irqsave` we have to verify that we are using the critical section to protect data only and not causing any context switching.  The issue here is that these functions go through the wireless library and we don't really know what's going on inside.  You should be able to track the calls between `interrupt_disable` and `interrupt_restore` with a debugger.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716270513



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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:
+ *   ESP32C3 BLE lightsleep callback function.
+ *
+ * Input Parameters:
+ *   lpcycles - light sleep cycles
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void btdm_sleep_enter_phase1_wrapper(uint32_t lpcycles)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  else
+    {
+      wlerr("timer start failed");
+      DEBUGASSERT(0);
+    }
+}
+
+/****************************************************************************
+ * Name: btdm_sleep_enter_phase2_wrapper
+ *
+ * Description:
+ *   ESP32C3 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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * Name: btdm_sleep_exit_phase3_wrapper
+ *
+ * Description:
+ *   ESP32C3 BLE lightsleep callback function..

Review comment:
       ```suggestion
    *   ESP32 BLE lightsleep callback function..
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715186489



##########
File path: arch/xtensa/src/esp32/esp32_ble.c
##########
@@ -0,0 +1,344 @@
+/****************************************************************************
+ * 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 HCI comand will callback this function.
+ *
+ * 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 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 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)
+    {
+      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-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 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 -EINVAL;

Review comment:
       ```suggestion
         return -EOVERFLOW;
   ```
   Add error msg




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716267393



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)

Review comment:
       I think it doesn't need this verification.
   If `ticks` is equal to zero, it will enter in the if before, 




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] gustavonihei merged pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
gustavonihei merged pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509


   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716972319



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      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 -1;
+    }
+
+  btdm_controller_deinit();

Review comment:
       Is it necessary to deinit? The check before is not intended to check if it was previously initialized?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716268326



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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

Review comment:
       ```suggestion
    *    Get random value.
    
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716260221



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+

Review comment:
       ```suggestion
   DEBUGASSERT(task_handle != NULL);
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716259208



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;

Review comment:
       ```suggestion
     return OK;
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716972933



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      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 -1;
+    }
+
+  btdm_controller_deinit();
+
+  if (g_lp_stat.phy_enabled)
+    {
+      bt_phy_disable();
+      g_lp_stat.phy_enabled = 0;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+
+#ifdef CONFIG_PM
+  /* deinit low power control resources */
+
+  g_lp_stat.pm_lock_released = 0;
+
+  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 = 0;
+      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 -1;

Review comment:
       ```suggestion
         return -ERROR;
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715190745



##########
File path: arch/xtensa/src/esp32/esp32_ble.c
##########
@@ -0,0 +1,344 @@
+/****************************************************************************
+ * 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 HCI comand will callback this function.
+ *
+ * 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 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 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)
+    {
+      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-C3 BLE send callback function for BT driver.

Review comment:
       ```suggestion
    *   ESP32 BLE send callback function for BT driver.
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715210569



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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);

Review comment:
       ```suggestion
   typedef void (*osi_intr_handler)(void);
   ```
   add comment to this  function pointer




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715189974



##########
File path: arch/xtensa/src/esp32/esp32_ble.c
##########
@@ -0,0 +1,344 @@
+/****************************************************************************
+ * 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 HCI comand will callback this function.
+ *
+ * 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 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 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)
+    {
+      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-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 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 -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 (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 on success or a negated value on failure.
+ *
+ ****************************************************************************/
+
+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:
+ *   success or fail
+ *
+ ****************************************************************************/
+
+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 error: %d\n", ret);

Review comment:
       ```suggestion
         wlerr("bt_netdev_register or uart_bth4_register error: %d\n", ret);
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715204713



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */

Review comment:
       Put comment above




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] acassis commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
acassis commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r719447279



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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)

Review comment:
       Putting it in a single line will reach position 79




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715187918



##########
File path: arch/xtensa/src/esp32/esp32_ble.c
##########
@@ -0,0 +1,344 @@
+/****************************************************************************
+ * 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 HCI comand will callback this function.
+ *
+ * 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 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 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)
+    {
+      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-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 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 -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;

Review comment:
       add error msg




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715212291



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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);

Review comment:
       Place it on Public Function section




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715209901



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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);

Review comment:
       ```suggestion
   typedef void (*btdm_vnd_ol_task_func_t)(void *param);
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716991577



##########
File path: arch/xtensa/src/esp32/hardware/esp32_dport.h
##########
@@ -1185,6 +1185,7 @@
 #define DPORT_SLAVE_SPI_MASK_PRO_S  0
 
 #define DPORT_WIFI_CLK_EN_REG          (DR_REG_DPORT_BASE + 0x0CC)

Review comment:
       ```suggestion
   #define DPORT_WIFI_CLK_EN_REG          (DR_REG_DPORT_BASE + 0x0cc)
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716275905



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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:
+ *   ESP32C3 BLE lightsleep callback function.
+ *
+ * Input Parameters:
+ *   lpcycles - light sleep cycles
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void btdm_sleep_enter_phase1_wrapper(uint32_t lpcycles)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  else
+    {
+      wlerr("timer start failed");
+      DEBUGASSERT(0);
+    }
+}
+
+/****************************************************************************
+ * Name: btdm_sleep_enter_phase2_wrapper
+ *
+ * Description:
+ *   ESP32C3 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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * Name: btdm_sleep_exit_phase3_wrapper
+ *
+ * Description:
+ *   ESP32C3 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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();

Review comment:
       Check with @Ouss4 if it isn't the case of using `spin_lock_irqsave`




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716261464



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean

Review comment:
       ```suggestion
    *   mask - Mask used to indicate the bits to enable interrupt.
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] gustavonihei commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
gustavonihei commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r718553018



##########
File path: arch/xtensa/src/esp32/Kconfig
##########
@@ -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 simultaneos connections"

Review comment:
       ```suggestion
   	int "Maximum BLE simultaneous connections"
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] acassis commented on pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
acassis commented on pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#issuecomment-932225039


   > Some nxstyle errors still need fixing: ![image](https://user-images.githubusercontent.com/38959758/135625098-43d3aaf0-c919-4457-8a84-b206cd64e841.png)
   
   Fixed! Thank you!!!


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] gustavonihei commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
gustavonihei commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r719680379



##########
File path: 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,

Review comment:
       ```suggestion
   ```
   `esp32_ble_send_ready` is an empty function, so no need to neither define it or attribute it here.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] acassis commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
acassis commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r720452228



##########
File path: 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

Review comment:
       Good finding! Thank you!




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716993766



##########
File path: boards/xtensa/esp32/esp32-devkitc/src/esp32_bringup.c
##########
@@ -207,6 +211,15 @@ int esp32_bringup(void)
     }
 #endif
 
+#ifdef CONFIG_ESP32_BLE
+  ret = esp32_ble_initialize();
+  if (ret)
+    {
+      syslog(LOG_ERR, "ERROR: Failed to initialize BLE\n");

Review comment:
       ```suggestion
         syslog(LOG_ERR, "ERROR: Failed to initialize BLE: %d \n", ret);
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716973818



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      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 -1;
+    }
+
+  btdm_controller_deinit();
+
+  if (g_lp_stat.phy_enabled)
+    {
+      bt_phy_disable();
+      g_lp_stat.phy_enabled = 0;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+
+#ifdef CONFIG_PM
+  /* deinit low power control resources */
+
+  g_lp_stat.pm_lock_released = 0;
+
+  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 = 0;
+      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 -1;
+    }
+
+  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 == 0)
+    {
+      esp32_pm_lockrelease();
+      g_lp_stat.pm_lock_released = 1;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+#endif
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp32_bt_controller_enable
+ *
+ * Description:
+ *    Enable  BT controller.
+ * Input Parameters:
+ *    None
+ *
+ * Returned Value:
+ *    None

Review comment:
       Update




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716976005



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      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 -1;
+    }
+
+  btdm_controller_deinit();
+
+  if (g_lp_stat.phy_enabled)
+    {
+      bt_phy_disable();
+      g_lp_stat.phy_enabled = 0;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+
+#ifdef CONFIG_PM
+  /* deinit low power control resources */
+
+  g_lp_stat.pm_lock_released = 0;
+
+  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 = 0;
+      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 -1;
+    }
+
+  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 == 0)
+    {
+      esp32_pm_lockrelease();
+      g_lp_stat.pm_lock_released = 1;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+#endif
+
+  return 0;
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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 = 0;
+
+  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 == 0)
+    {
+      esp32_pm_lockrelease();
+      g_lp_stat.pm_lock_released = 1;
+    }
+#endif
+
+  return ret;
+}
+
+esp_bt_controller_status_t esp32_bt_controller_get_status(void)

Review comment:
       Header




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715183797



##########
File path: arch/xtensa/src/esp32/esp32_ble.c
##########
@@ -0,0 +1,344 @@
+/****************************************************************************
+ * 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 HCI comand will callback this function.
+ *
+ * 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 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 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)
+    {
+      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-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

Review comment:
       ```suggestion
    *   data - BT packet data buffer pointer
    *   len  - BT packet length
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] gustavonihei commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
gustavonihei commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r719679820



##########
File path: 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)

Review comment:
       Remove empty function.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716262744



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),

Review comment:
       Make sure this reset register doesn't need to first be set to 1 and then be set to 0.
   I've been seen many reset procedures like this one in our chips. Should not be different for Wi-Fi regs.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] acassis commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
acassis commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r719459293



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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

Review comment:
       Many BLE OSI Functions return true or false, but its return time is int instead of boolean.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716269311



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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.

Review comment:
       ```suggestion
    *   Acquire PM lock and stop esp timer.
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716264318



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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

Review comment:
       ```suggestion
    *   Take a semaphore from an ISR
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] acassis commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
acassis commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r717980756



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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);
+

Review comment:
       Ok!




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] acassis commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
acassis commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r717880425



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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 */

Review comment:
       Agree, it could become boolean!




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] acassis commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
acassis commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r717978264



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */

Review comment:
       Ok




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716959188



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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");

Review comment:
       ```suggestion
             wlerr("Failed to get time %d\n", ret);
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716965169



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      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 -1;

Review comment:
       ```suggestion
         return -ERROR;
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716951996



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\n");

Review comment:
       ```suggestion
         wlerr("Failed to create mqueue %d \n", ret);
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716267943



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size

Review comment:
       ```suggestion
    *  size - buffer size
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716972818



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      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 -1;
+    }
+
+  btdm_controller_deinit();
+
+  if (g_lp_stat.phy_enabled)
+    {
+      bt_phy_disable();
+      g_lp_stat.phy_enabled = 0;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+
+#ifdef CONFIG_PM
+  /* deinit low power control resources */
+
+  g_lp_stat.pm_lock_released = 0;
+
+  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 = 0;
+      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.

Review comment:
       ```suggestion
    *    Disable  BT controller.
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715174441



##########
File path: arch/xtensa/src/esp32/Make.defs
##########
@@ -229,7 +229,13 @@ 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 -lcoexist -lespnow -lphy -lwpa_supplicant

Review comment:
       I think you forgot to delete this line.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715182646



##########
File path: arch/xtensa/src/esp32/esp32_ble.c
##########
@@ -0,0 +1,344 @@
+/****************************************************************************
+ * 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 HCI comand will callback this function.
+ *
+ * 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 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 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)
+    {
+      ret = ERROR;
+    }
+  else
+    {
+      /* send packet to host */

Review comment:
       ```suggestion
         /* Send packet to host */
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] acassis commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
acassis commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716700605



##########
File path: arch/xtensa/src/esp32/esp32_ble.c
##########
@@ -0,0 +1,344 @@
+/****************************************************************************
+ * 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 HCI comand will callback this function.
+ *
+ * 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 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 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)

Review comment:
       Sara, "valid" is already boolean, this way, it is correct to use !valid




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716985878



##########
File path: 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_RISCV_SRC_ESP32_ESP32_BLE_ADAPTER_H
+#define __ARCH_RISCV_SRC_ESP32_ESP32_BLE_ADAPTER_H

Review comment:
       ```suggestion
   #ifndef __ARCH_XTENSA_SRC_ESP32_ESP32_BLE_ADAPTER_H
   #define __ARCH_XTENSA_SRC_ESP32_ESP32_BLE_ADAPTER_H
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715178207



##########
File path: arch/xtensa/src/esp32/esp32_ble.c
##########
@@ -0,0 +1,344 @@
+/****************************************************************************
+ * 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,

Review comment:
       Is it related to `UART_BTH4`?
   Shouldn't it be protected with guards only if `CONFIG_UART_BTH4` is enabled?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716984815



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      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 -1;
+    }
+
+  btdm_controller_deinit();
+
+  if (g_lp_stat.phy_enabled)
+    {
+      bt_phy_disable();
+      g_lp_stat.phy_enabled = 0;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+
+#ifdef CONFIG_PM
+  /* deinit low power control resources */
+
+  g_lp_stat.pm_lock_released = 0;
+
+  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 = 0;
+      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 -1;
+    }
+
+  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 == 0)
+    {
+      esp32_pm_lockrelease();
+      g_lp_stat.pm_lock_released = 1;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+#endif
+
+  return 0;
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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 = 0;
+
+  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 == 0)
+    {
+      esp32_pm_lockrelease();
+      g_lp_stat.pm_lock_released = 1;
+    }
+#endif
+
+  return ret;
+}
+
+esp_bt_controller_status_t esp32_bt_controller_get_status(void)
+{
+  return btdm_controller_status;
+}
+
+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;
+}
+
+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;
+}
+
+static bool coex_bt_wakeup_request(void)
+{
+  return async_wakeup_request(BTDM_ASYNC_WAKEUP_REQ_COEX);
+}
+
+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 point
+ *  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 = -1;

Review comment:
       ```suggestion
     int ret = -ERROR;
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716982774



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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)
+    {
+      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\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);
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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)
+    {
+      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 -1;
+    }
+
+  btdm_controller_deinit();
+
+  if (g_lp_stat.phy_enabled)
+    {
+      bt_phy_disable();
+      g_lp_stat.phy_enabled = 0;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+
+#ifdef CONFIG_PM
+  /* deinit low power control resources */
+
+  g_lp_stat.pm_lock_released = 0;
+
+  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 = 0;
+      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 -1;
+    }
+
+  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 == 0)
+    {
+      esp32_pm_lockrelease();
+      g_lp_stat.pm_lock_released = 1;
+    }
+  else
+    {
+      DEBUGASSERT(0);
+    }
+#endif
+
+  return 0;
+}
+
+/****************************************************************************
+ * 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 -1;
+    }
+
+  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 = 0;
+
+  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 == 0)
+    {
+      esp32_pm_lockrelease();
+      g_lp_stat.pm_lock_released = 1;
+    }
+#endif
+
+  return ret;
+}
+
+esp_bt_controller_status_t esp32_bt_controller_get_status(void)
+{
+  return btdm_controller_status;
+}
+
+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;
+}
+
+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;
+}
+
+static bool coex_bt_wakeup_request(void)
+{
+  return async_wakeup_request(BTDM_ASYNC_WAKEUP_REQ_COEX);
+}
+
+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.

Review comment:
       ```suggestion
    *    Host send packet to controller.
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715191842



##########
File path: 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_RISCV_SRC_ESP32_ESP32_BLE_H
+#define __ARCH_RISCV_SRC_ESP32_ESP32_BLE_H

Review comment:
       ```suggestion
   #ifndef __ARCH_XTENSA_SRC_ESP32_ESP32_BLE_H
   #define __ARCH_XTENSA_SRC_ESP32_ESP32_BLE_H
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r715186489



##########
File path: arch/xtensa/src/esp32/esp32_ble.c
##########
@@ -0,0 +1,344 @@
+/****************************************************************************
+ * 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 HCI comand will callback this function.
+ *
+ * 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 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 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)
+    {
+      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-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 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 -EINVAL;

Review comment:
       ```suggestion
         return -EOVERFLOW;
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] gustavonihei commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
gustavonihei commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r719685081



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2959 @@
+/****************************************************************************
+ * 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
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0

Review comment:
       ```suggestion
   ```
   These are already defined in `esp32_dport.h` and should be included from there.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716264386



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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

Review comment:
       ```suggestion
    * Input Parameters:
    *   semphr - Semaphore data pointer.
    *   hptw     - Unused.
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716262510



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }

Review comment:
       enable is not being used




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716265299



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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");

Review comment:
       ```suggestion
             wlerr("Failed to wait sem %d\n", ret);
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] saramonteiro commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
saramonteiro commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r716950025



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2817 @@
+/****************************************************************************
+ * 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) 
+(
+  int __interrupt = (int)(v);
+  __asm__ __volatile__("wsr.intset %0" :: "a"(__interrupt):"memory"); 
+)
+
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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
+
+  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 - No mean
+ *
+ * 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);
+      }
+    }
+}
+
+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;
+  }
+}
+
+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;
+  }
+}
+
+static uint32_t get_rst_en_mask(periph_module_e periph, bool enable)
+{
+  switch (periph)
+  {
+    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 0;
+    default:
+      return 0;
+  }
+}
+
+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;
+}
+
+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;
+}
+
+static void bt_periph_module_enable(periph_module_e periph)
+{
+  DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph),
+                          get_clk_en_mask(periph));
+  DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph),
+                            get_rst_en_mask(periph, true));
+}
+
+/****************************************************************************
+ * 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
+ *
+ * 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)
+{
+  *((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:
+ *  szie - buffer size
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void *malloc_wrapper(size_t size)
+{
+  void * p = NULL;
+
+  p = kmm_malloc(size);
+  DEBUGASSERT(p);
+
+  return p;
+}
+
+/* FIXME Description */
+
+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));
+}
+
+/* FIXME Description */
+
+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 half us.
+ *
+ * Input Parameters:
+ *  cycles
+ * error_corr
+ *
+ * Returned Value:
+ *   us
+ *
+ ****************************************************************************/
+
+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)
+{
+  DEBUGASSERT(g_lp_cntl.enable == 1);
+
+  if (g_lp_stat.pm_lock_released)
+    {
+      esp32_pm_lockacquire();
+      g_lp_stat.pm_lock_released = 0;
+    }
+
+  int event = (int) param;
+
+  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 = 0;
+    }
+
+  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)
+{
+  if (g_lp_cntl.wakeup_timer_required == 0)
+    {
+      return;
+    }
+
+  /* start a timer to wake up and acquire the pm_lock before sleep awakes */
+
+  uint32_t us_to_sleep = btdm_lpcycles_2_us(lpcycles, NULL);
+
+  DEBUGASSERT(us_to_sleep > BTDM_MIN_TIMER_UNCERTAINTY_US);
+  uint32_t 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 == 0);
+
+  if (esp_timer_start_once(g_btdm_slp_tmr,
+                           us_to_sleep - uncertainty) == ESP_OK)
+    {
+      g_lp_stat.wakeup_timer_started = 1;
+    }
+  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 = 0;
+        }
+      else
+        {
+          DEBUGASSERT(0);
+        }
+
+      if (g_lp_stat.pm_lock_released == 0)
+        {
+          esp32_pm_lockrelease();
+          g_lp_stat.pm_lock_released = 1;
+        }
+    }
+}
+
+/****************************************************************************
+ * 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 = 0;
+    }
+
+  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 == 0)
+        {
+          bt_phy_enable();
+          g_lp_stat.phy_enabled = 1;
+        }
+    }
+
+  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 = 0;
+    }
+}
+#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.

Review comment:
       ```suggestion
    *    Disable BT phy.
    
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] acassis commented on a change in pull request #4509: esp32: Add initial support to Bluetooth Low Energy

Posted by GitBox <gi...@apache.org>.
acassis commented on a change in pull request #4509:
URL: https://github.com/apache/incubator-nuttx/pull/4509#discussion_r717883790



##########
File path: arch/xtensa/src/esp32/esp32_ble_adapter.c
##########
@@ -0,0 +1,2814 @@
+/****************************************************************************
+ * 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 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 modem sleep */
+#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
+ ****************************************************************************/
+
+#define RTC_CLK_CAL_FRACT  19  /* Number of fractional bits in values returned by rtc_clk_cal */
+
+/* DPORT_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define DPORT_WIFI_CLK_EN    0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_M  ((DPORT_WIFI_CLK_EN_V)<<(DPORT_WIFI_CLK_EN_S))
+#define DPORT_WIFI_CLK_EN_V  0xFFFFFFFF
+#define DPORT_WIFI_CLK_EN_S  0
+
+/* Write value to DPORT register (does not require protecting) */
+
+#define DPORT_REG_WRITE(_r, _v)   _DPORT_REG_WRITE((_r), (_v))
+#define DPORT_REG_READ(_r)    _DPORT_REG_READ(_r)
+
+#define DPORT_READ_PERI_REG(addr)        _DPORT_READ_PERI_REG(addr)
+#define _DPORT_READ_PERI_REG(addr)       (*((volatile uint32_t *)(addr)))
+#define _DPORT_WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val)
+
+/* Write value to register */
+
+#define DPORT_WRITE_PERI_REG(addr, val) _DPORT_WRITE_PERI_REG((addr), (val))
+
+/* Set bits of register controlled by mask */
+
+#define DPORT_SET_PERI_REG_MASK(reg, mask)   DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)|(mask)))
+
+/* clear bits of register controlled by mask */
+
+#define DPORT_CLEAR_PERI_REG_MASK(reg, mask) DPORT_WRITE_PERI_REG((reg), (DPORT_READ_PERI_REG(reg)&(~(mask))))
+
+/* 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;
+
+#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)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_schm_register_btdm_callback(void *callback)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_register_wifi_channel_change_callback(void *cb)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static int adapter_coex_wifi_channel_get(uint8_t *primary,
+                                         uint8_t *secondary)
+{
+  wlinfo("I'm here!\n");
+  return -1;
+}
+
+static void adapter_coex_schm_status_bit_clear(uint32_t type,
+                                               uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static void adapter_coex_schm_status_bit_set(uint32_t type, uint32_t status)
+{
+  wlinfo("I'm here!\n");
+}
+
+static uint32_t adapter_coex_schm_interval_get(void)
+{
+  wlinfo("I'm here!\n");
+  return ESP_ERR_INVALID_STATE;
+}
+
+static uint8_t adapter_coex_schm_curr_period_get(void)
+{
+  wlinfo("I'm here!\n");
+  return 0;
+}
+
+static void *adapter_coex_schm_curr_phase_get(void)
+{
+  wlinfo("I'm here!\n");
+  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)

Review comment:
       I cannot convert it to bool because it is returned by many wrapper function that aren't expecting boolean type!




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org