소스 검색

Merge branch 'feature/btdm_controller' into 'master'

BT support

Initial version of BT support.

BT and WiFi are mutually exclusive at this point, so we have a new option to select which stack is used.
Precompiled BT libraries are added as a submodule.


See merge request !109

Wu Jian Gang 9 년 전
부모
커밋
4480ab6c8c

+ 3 - 0
.gitmodules

@@ -4,3 +4,6 @@
 [submodule "components/esptool_py/esptool"]
 	path = components/esptool_py/esptool
 	url = https://github.com/themadinventor/esptool.git
+[submodule "components/bt/lib"]
+	path = components/bt/lib
+	url = https://github.com/espressif/esp32-bt-lib.git

+ 0 - 32
Kconfig

@@ -19,38 +19,6 @@ config PYTHON
 	help
 	    The executable name/path that is used to run python. On some systems Python 2.x
 		may need to be invoked as python2.
-
-config MEMMAP_BT
-	bool "Reserve space for Bluetooth stack"
-	default "n"
-	help
-		The Bluetooth stack uses memory that cannot be used as generic memory anymore. This
-		reserves the space for that within the memory map of the compiled binary.
-
-config MEMMAP_SMP
-	bool "Reserve memory for two cores"
-	default "y"
-	help
-		The ESP32 contains two cores. If you plan to only use one, you can disable this item
-		to save some memory. (ToDo: Make this automatically depend on unicore support)
-
-config MEMMAP_TRACEMEM
-	bool "Use TRAX tracing feature"
-	default "n"
-	help
-		The ESP32 contains a feature which allows you to trace the execution path the processor
-		has taken through the program. This is stored in a chunk of 32K (16K for single-processor)
-		of memory that can't be used for general purposes anymore. Disable this if you do not know
-		what this is.
-
-config MEMMAP_SPISRAM
-	bool "Use external SPI SRAM chip as main memory"
-	default "n"
-	help
-		The ESP32 can control an external SPI SRAM chip, adding the memory it contains to the 
-		main memory map. Enable this if you have this hardware and want to use it in the same
-		way as on-chip RAM.
-
 endmenu
 
 source "$COMPONENT_KCONFIGS_PROJBUILD"

+ 13 - 13
components/bt/Kconfig

@@ -3,21 +3,21 @@ visible if MEMMAP_BT
 
 
 config BT_ENABLED
-	bool "Enable low-level BT stack"
-	depends on MEMMAP_BT
+	bool
+	depends on ESP32_ENABLE_STACK_BT
 	help
 		This compiles in the low-level BT stack.
 
-config BT_BTLE
-	bool "Enable BTLE"
-	depends on BT_ENABLED
-	help
-		This compiles BTLE support
-
-config BT_BT
-	bool "Enable classic BT"
-	depends on BT_ENABLED
-	help
-		This enables classic BT support
+#config BT_BTLE
+#	bool "Enable BTLE"
+#	depends on BT_ENABLED
+#	help
+#		This compiles BTLE support
+#
+#config BT_BT
+#	bool "Enable classic BT"
+#	depends on BT_ENABLED
+#	help
+#		This enables classic BT support
 
 endmenu

+ 121 - 0
components/bt/bt.c

@@ -0,0 +1,121 @@
+// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/queue.h"
+#include "freertos/semphr.h"
+#include "freertos/xtensa_api.h"
+#include "freertos/portmacro.h"
+#include "esp_types.h"
+#include "esp_system.h"
+#include "esp_task.h"
+#include "esp_intr.h"
+#include "esp_attr.h"
+#include "bt.h"
+
+#if CONFIG_BT_ENABLED
+
+/* not for user call, so don't put to include file */
+extern void btdm_osi_funcs_register(void *osi_funcs);
+extern void btdm_controller_init(void);
+
+
+static bt_app_startup_cb_t app_startup_cb;
+static void *app_startup_ctx;
+
+#define BT_DEBUG(...)
+#define BT_API_CALL_CHECK(info, api_call, ret) \
+do{\
+    esp_err_t __err = (api_call);\
+    if ((ret) != __err) {\
+        BT_DEBUG("%s %d %s ret=%d\n", __FUNCTION__, __LINE__, (info), __err);\
+        return __err;\
+    }\
+} while(0)
+
+struct osi_funcs_t {
+    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 *(*_semphr_create)(uint32_t max, uint32_t init);
+    void *(*_semphr_give_from_isr)(void *semphr, void *hptw);
+    void *(*_semphr_take)(void *semphr, uint32_t block_time);
+    esp_err_t (* _read_efuse_mac)(uint8_t mac[6]);
+};
+
+static portMUX_TYPE global_int_mux = portMUX_INITIALIZER_UNLOCKED;
+
+static void IRAM_ATTR interrupt_disable(void)
+{
+    portENTER_CRITICAL(&global_int_mux);
+}
+
+static void IRAM_ATTR interrupt_restore(void)
+{
+    portEXIT_CRITICAL(&global_int_mux);
+}
+
+static void * IRAM_ATTR semphr_take_wrapper(void *semphr, uint32_t block_time)
+{
+    return (void *)xSemaphoreTake(semphr, block_time);
+}
+
+static struct osi_funcs_t osi_funcs = {
+    ._set_isr = xt_set_interrupt_handler,
+    ._ints_on = xt_ints_on,
+    ._interrupt_disable = interrupt_disable,
+    ._interrupt_restore = interrupt_restore,
+    ._task_yield = vPortYield,
+    ._semphr_create = xQueueCreateCountingSemaphore,
+    ._semphr_give_from_isr = (void *)xQueueGiveFromISR,
+    ._semphr_take = semphr_take_wrapper,
+    ._read_efuse_mac = system_efuse_read_mac,
+};
+
+static void bt_controller_task(void *pvParam)
+{
+    btdm_osi_funcs_register(&osi_funcs);
+    btdm_controller_init();
+}
+
+
+static void bt_init_task(void *pvParameters)
+{
+    xTaskCreatePinnedToCore(bt_controller_task, "btControllerTask", ESP_TASK_BT_CONTROLLER_STACK, NULL, ESP_TASK_BT_CONTROLLER_PRIO, NULL, 0);
+
+    if (app_startup_cb) {
+        app_startup_cb(app_startup_ctx);
+    }
+
+    vTaskDelete(NULL);
+}
+
+
+esp_err_t esp_bt_startup(bt_app_startup_cb_t cb, void *ctx)
+{
+    app_startup_cb = cb;
+    app_startup_ctx = ctx;
+
+    xTaskCreatePinnedToCore(bt_init_task, "btInitTask", ESP_TASK_BT_INIT_STACK, NULL, ESP_TASK_BT_INIT_PRIO, NULL, 0);
+
+    return ESP_OK;
+}
+#endif

+ 25 - 0
components/bt/component.mk

@@ -0,0 +1,25 @@
+#
+# Component Makefile
+#
+
+#COMPONENT_ADD_INCLUDEDIRS := 
+
+CURRENT_DIR=$(IDF_PATH)/components/bt
+
+COMPONENT_ADD_INCLUDEDIRS := ./include
+
+CFLAGS += -Wno-error=unused-label -Wno-error=return-type -Wno-error=missing-braces -Wno-error=pointer-sign -Wno-error=parentheses
+
+LIBS := btdm_app
+
+COMPONENT_ADD_LDFLAGS := -lbt -L$(abspath lib) \
+                           $(addprefix -l,$(LIBS)) \
+                          $(LINKER_SCRIPTS)
+
+
+ALL_LIB_FILES := $(patsubst %,$(COMPONENT_PATH)/lib/lib%.a,$(LIBS))
+$(COMPONENT_LIBRARY): $(ALL_LIB_FILES)
+
+COMPONENT_SRCDIRS := ./
+
+include $(IDF_PATH)/make/component_common.mk

+ 66 - 0
components/bt/include/bt.h

@@ -0,0 +1,66 @@
+// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed 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 __BT_H__
+#define __BT_H__
+
+#include "freertos/FreeRTOS.h"
+#include "esp_err.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef void (* bt_app_startup_cb_t)(void *param);
+
+esp_err_t esp_bt_startup(bt_app_startup_cb_t cb, void *ctx);
+
+/* @breif: vhci_host_callback
+ *  used for vhci call host function to notify what host need to do
+ *  
+ *  notify_host_send_available: notify host can send packet to controller
+ *  notify_host_recv: notify host that controller has packet send to host
+ */
+typedef struct vhci_host_callback {
+
+    void (*notify_host_send_available)(void);
+    int (*notify_host_recv)(uint8_t *data, uint16_t len);
+} vhci_host_callback_t;
+
+/* @breif: API_vhci_host_check_send_available
+ *  used for check actively if the host can send packet to controller or not.
+ *  return true for ready to send, false means cannot send packet
+ */
+bool API_vhci_host_check_send_available(void);
+
+/* @breif: API_vhci_host_send_packet 
+ * host send packet to controller
+ * param data is the packet point, the param len is the packet length
+ * return void
+ */
+void API_vhci_host_send_packet(uint8_t *data, uint16_t len);
+
+/* @breif: API_vhci_host_register_callback
+ * register the vhci referece callback, the call back
+ * struct defined by vhci_host_callback structure.
+ * param is the vhci_host_callback type variable
+ */
+void API_vhci_host_register_callback(const vhci_host_callback_t *callback);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BT_H__ */

+ 1 - 0
components/bt/lib

@@ -0,0 +1 @@
+Subproject commit 6c9a6de656262113a0aab63907d6871a64e00fae

+ 54 - 2
components/esp32/Kconfig

@@ -20,13 +20,65 @@ config ESP32_DEFAULT_CPU_FREQ_MHZ
     default 160 if ESP32_DEFAULT_CPU_FREQ_160
     default 240 if ESP32_DEFAULT_CPU_FREQ_240
 
+choice ESP32_WIFI_OR_BT
+    prompt "Select stack to enable (WiFi or BT)"
+    default ESP32_ENABLE_WIFI
+    help
+        Temporarily, WiFi and BT stacks can not be used at the same time.
+        Select which stack to enable.
+
+config ESP32_ENABLE_STACK_WIFI
+    bool "WiFi"
+    select WIFI_ENABLED if ESP32_ENABLE_STACK_WIFI
+config ESP32_ENABLE_STACK_BT
+    bool "BT"
+    select MEMMAP_BT if ESP32_ENABLE_STACK_BT
+    select BT_ENABLED if ESP32_ENABLE_STACK_BT
+config ESP32_ENABLE_STACK_NONE
+    bool "None"
+endchoice
+
+config MEMMAP_BT
+    bool
+    depends on ESP32_ENABLE_STACK_BT
+    help
+        The Bluetooth stack uses memory that cannot be used as generic memory anymore. This
+        reserves the space for that within the memory map of the compiled binary.
+        This option is required to enable BT stack.
+        Temporarily, this option is not compatible with WiFi stack.
+
+config MEMMAP_SMP
+    bool "Reserve memory for two cores"
+    default "y"
+    help
+        The ESP32 contains two cores. If you plan to only use one, you can disable this item
+        to save some memory. (ToDo: Make this automatically depend on unicore support)
+
+config MEMMAP_TRACEMEM
+    bool "Use TRAX tracing feature"
+    default "n"
+    help
+        The ESP32 contains a feature which allows you to trace the execution path the processor
+        has taken through the program. This is stored in a chunk of 32K (16K for single-processor)
+        of memory that can't be used for general purposes anymore. Disable this if you do not know
+        what this is.
+
+config MEMMAP_SPISRAM
+    bool "Use external SPI SRAM chip as main memory"
+    default "n"
+    help
+        The ESP32 can control an external SPI SRAM chip, adding the memory it contains to the 
+        main memory map. Enable this if you have this hardware and want to use it in the same
+        way as on-chip RAM.
+
 config WIFI_ENABLED
-    bool "Enable low-level WiFi stack"
+    bool
     default "y"
+    depends on ESP32_ENABLE_STACK_WIFI
     help
         This compiles in the low-level WiFi stack.
 
-		Temporarily, this option requires that FreeRTOS runs in single core mode.
+		Temporarily, this option is not compatible with BT stack.
 
 config WIFI_AUTO_STARTUP
     bool "Start WiFi with system startup"

+ 7 - 1
components/esp32/cpu_start.c

@@ -48,6 +48,9 @@ static void IRAM_ATTR call_user_start_cpu1();
 static void IRAM_ATTR user_start_cpu1(void);
 extern void ets_setup_syscalls(void);
 extern esp_err_t app_main(void *ctx);
+#if CONFIG_BT_ENABLED
+extern void bt_app_main(void *param);
+#endif
 
 extern int _bss_start;
 extern int _bss_end;
@@ -161,7 +164,10 @@ void user_start_cpu0(void)
 
 #if CONFIG_WIFI_ENABLED && CONFIG_WIFI_AUTO_STARTUP
 #include "esp_wifi.h"
-    esp_wifi_startup(app_main, NULL);
+	esp_wifi_startup(app_main, NULL);
+#elif CONFIG_BT_ENABLED
+#include "bt.h"
+        esp_bt_startup(bt_app_main, NULL);
 #else
     app_main(NULL);
 #endif

+ 7 - 1
components/esp32/include/esp_task.h

@@ -43,6 +43,11 @@
 #define ESP_TASK_WPS_PRIO             (ESP_TASK_PRIO_MIN + 2)
 #define ESP_TASK_WPS_STACK            2048
 
+/* Bt contoller Task */
+/* controller */
+#define ESP_TASK_BT_CONTROLLER_PRIO   (ESP_TASK_PRIO_MAX - 1)
+#define ESP_TASK_BT_CONTROLLER_STACK  4096
+
 /* idf task */
 #define ESP_TASKD_EVENT_PRIO          (ESP_TASK_PRIO_MAX - 5)
 #define ESP_TASKD_EVENT_STACK         CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE
@@ -50,5 +55,6 @@
 #define ESP_TASK_WIFI_STARTUP_STACK   4096
 #define ESP_TASK_TCPIP_PRIO           (ESP_TASK_PRIO_MAX - 7)
 #define ESP_TASK_TCPIP_STACK          2048
-
+#define ESP_TASK_BT_INIT_PRIO         (ESP_TASK_PRIO_MAX - 7)
+#define ESP_TASK_BT_INIT_STACK        2048
 #endif

+ 3 - 3
components/esp32/include/soc/soc.h

@@ -260,14 +260,14 @@
 /*************************************************************************************************************
  *      Intr num                Level           Type                    PRO CPU usage           APP CPU uasge
  *      0                       1               extern level            WMAC                    Reserved
- *      1                       1               extern level            BT/BLE Host             Reserved
+ *      1                       1               extern level            BT/BLE Host VHCI        Reserved
  *      2                       1               extern level            FROM_CPU                FROM_CPU
  *      3                       1               extern level            TG0_WDT                 Reserved
  *      4                       1               extern level            WBB
- *      5                       1               extern level            Reserved
+ *      5                       1               extern level            BT Controller 
  *      6                       1               timer                   FreeRTOS Tick(L1)       FreeRTOS Tick(L1)
  *      7                       1               software                Reserved                Reserved
- *      8                       1               extern level            Reserved
+ *      8                       1               extern level            BLE Controller 
  *      9                       1               extern level            
  *      10                      1               extern edge             Internal Timer
  *      11                      3               profiling

+ 9 - 0
examples/04_ble_adv/Makefile

@@ -0,0 +1,9 @@
+#
+# This is a project Makefile. It is assumed the directory this Makefile resides in is a
+# project subdirectory.
+#
+
+PROJECT_NAME := ble_adv
+
+include $(IDF_PATH)/make/project.mk
+

+ 6 - 0
examples/04_ble_adv/README.rst

@@ -0,0 +1,6 @@
+ESP-IDF ble_advertising app
+====================
+
+This is a BLE advertising demo with virtual HCI interface. Send Reset/ADV_PARAM/ADV_DATA/ADV_ENABLE HCI command for BLE advertising.
+
+

+ 204 - 0
examples/04_ble_adv/main/app_bt.c

@@ -0,0 +1,204 @@
+#include <stdio.h>
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "bt.h"
+#include <string.h>
+
+#define HCI_H4_CMD_PREAMBLE_SIZE           (4)
+
+/*  HCI Command opcode group field(OGF) */
+#define HCI_GRP_HOST_CONT_BASEBAND_CMDS    (0x03 << 10)            /* 0x0C00 */
+#define HCI_GRP_BLE_CMDS                   (0x08 << 10)
+
+#define HCI_RESET                          (0x0003 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
+#define HCI_BLE_WRITE_ADV_ENABLE           (0x000A | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_WRITE_ADV_PARAMS           (0x0006 | HCI_GRP_BLE_CMDS)
+#define HCI_BLE_WRITE_ADV_DATA             (0x0008 | HCI_GRP_BLE_CMDS)
+
+#define HCIC_PARAM_SIZE_WRITE_ADV_ENABLE        (1)
+#define HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS    (15)
+#define HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA      (31)
+
+#define BD_ADDR_LEN     (6)                     /* Device address length */
+typedef uint8_t bd_addr_t[BD_ADDR_LEN];         /* Device address */
+
+#define UINT16_TO_STREAM(p, u16) {*(p)++ = (uint8_t)(u16); *(p)++ = (uint8_t)((u16) >> 8);}
+#define UINT8_TO_STREAM(p, u8)   {*(p)++ = (uint8_t)(u8);}
+#define BDADDR_TO_STREAM(p, a)   {int ijk; for (ijk = 0; ijk < BD_ADDR_LEN;  ijk++) *(p)++ = (uint8_t) a[BD_ADDR_LEN - 1 - ijk];}
+#define ARRAY_TO_STREAM(p, a, len) {int ijk; for (ijk = 0; ijk < len;        ijk++) *(p)++ = (uint8_t) a[ijk];}
+
+enum {
+    H4_TYPE_COMMAND = 1,
+    H4_TYPE_ACL     = 2,
+    H4_TYPE_SCO     = 3,
+    H4_TYPE_EVENT   = 4
+};
+
+static uint8_t hci_cmd_buf[128];
+
+/* 
+ * @brief: BT controller callback function, used to notify the upper layer that
+ *         controller is ready to receive command
+ */
+static void controller_rcv_pkt_ready(void)
+{
+    printf("controller rcv pkt ready\n");
+}
+
+/* 
+ * @brief: BT controller callback function, to transfer data packet to upper
+ *         controller is ready to receive command
+ */
+static int host_rcv_pkt(uint8_t *data, uint16_t len)
+{
+    printf("host rcv pkt: ");
+    for (uint16_t i=0; i<len; i++)
+        printf("%02x", data[i]);
+    printf("\n");
+    return 0;
+}
+
+static vhci_host_callback_t vhci_host_cb = {
+    controller_rcv_pkt_ready,
+    host_rcv_pkt
+};
+
+static uint16_t make_cmd_reset(uint8_t *buf)
+{
+    UINT8_TO_STREAM (buf, H4_TYPE_COMMAND);
+    UINT16_TO_STREAM (buf, HCI_RESET);
+    UINT8_TO_STREAM (buf, 0);
+    return HCI_H4_CMD_PREAMBLE_SIZE;
+}
+
+static uint16_t make_cmd_ble_set_adv_enable (uint8_t *buf, uint8_t adv_enable)
+{
+    UINT8_TO_STREAM (buf, H4_TYPE_COMMAND);
+    UINT16_TO_STREAM (buf, HCI_BLE_WRITE_ADV_ENABLE);
+    UINT8_TO_STREAM  (buf, HCIC_PARAM_SIZE_WRITE_ADV_ENABLE);
+    UINT8_TO_STREAM (buf, adv_enable);
+    return HCI_H4_CMD_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_ADV_ENABLE;
+}
+
+static uint16_t make_cmd_ble_set_adv_param (uint8_t *buf, uint16_t adv_int_min, uint16_t adv_int_max,
+                                            uint8_t adv_type, uint8_t addr_type_own,
+                                            uint8_t addr_type_dir, bd_addr_t direct_bda,
+                                            uint8_t channel_map, uint8_t adv_filter_policy)
+{
+    UINT8_TO_STREAM (buf, H4_TYPE_COMMAND);
+    UINT16_TO_STREAM (buf, HCI_BLE_WRITE_ADV_PARAMS);
+    UINT8_TO_STREAM  (buf, HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS );
+
+    UINT16_TO_STREAM (buf, adv_int_min);
+    UINT16_TO_STREAM (buf, adv_int_max);
+    UINT8_TO_STREAM (buf, adv_type);
+    UINT8_TO_STREAM (buf, addr_type_own);
+    UINT8_TO_STREAM (buf, addr_type_dir);
+    BDADDR_TO_STREAM (buf, direct_bda);
+    UINT8_TO_STREAM (buf, channel_map);
+    UINT8_TO_STREAM (buf, adv_filter_policy);
+    return HCI_H4_CMD_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS;
+}
+
+
+static uint16_t make_cmd_ble_set_adv_data(uint8_t *buf, uint8_t data_len, uint8_t *p_data)
+{
+    UINT8_TO_STREAM (buf, H4_TYPE_COMMAND);
+    UINT16_TO_STREAM (buf, HCI_BLE_WRITE_ADV_DATA);
+    UINT8_TO_STREAM  (buf, HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1);
+
+    memset(buf, 0, HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA);
+
+    if (p_data != NULL && data_len > 0) {
+        if (data_len > HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA) {
+            data_len = HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA;
+        }
+
+        UINT8_TO_STREAM (buf, data_len);
+
+        ARRAY_TO_STREAM (buf, p_data, data_len);
+    }
+    return HCI_H4_CMD_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1;
+}
+
+static void hci_cmd_send_reset(void)
+{
+    uint16_t sz = make_cmd_reset (hci_cmd_buf);
+    API_vhci_host_send_packet(hci_cmd_buf, sz);
+}
+
+static void hci_cmd_send_ble_adv_start(void)
+{
+    uint16_t sz = make_cmd_ble_set_adv_enable (hci_cmd_buf, 1);
+    API_vhci_host_send_packet(hci_cmd_buf, sz);
+}
+
+static void hci_cmd_send_ble_set_adv_param(void)
+{
+    uint16_t adv_intv_min = 256; // 160ms
+    uint16_t adv_intv_max = 256; // 160ms
+    uint8_t adv_type = 0; // connectable undirected advertising (ADV_IND)
+    uint8_t own_addr_type = 0; // Public Device Address
+    uint8_t peer_addr_type = 0; // Public Device Address
+    uint8_t peer_addr[6] = {0x80, 0x81, 0x82, 0x83, 0x84, 0x85};
+    uint8_t adv_chn_map = 0x07; // 37, 38, 39
+    uint8_t adv_filter_policy = 0; // Process All Conn and Scan
+    
+    uint16_t sz = make_cmd_ble_set_adv_param(hci_cmd_buf,
+                                             adv_intv_min,
+                                             adv_intv_max,
+                                             adv_type,
+                                             own_addr_type,
+                                             peer_addr_type,
+                                             peer_addr,
+                                             adv_chn_map,
+                                             adv_filter_policy);
+    API_vhci_host_send_packet(hci_cmd_buf, sz);
+}
+
+static void hci_cmd_send_ble_set_adv_data(void)
+{
+    char *adv_name = "ESP-BLE-HELLO";
+    uint8_t name_len = (uint8_t)strlen(adv_name);
+    uint8_t adv_data[31] = {0x02, 0x01, 0x06, 0x0, 0x09};
+    uint8_t adv_data_len;
+    
+    adv_data[3] = name_len + 1;
+    for (int i=0; i<name_len; i++) {
+        adv_data[5+i] = (uint8_t)adv_name[i];
+    }
+    adv_data_len = 5 + name_len;
+
+    uint16_t sz = make_cmd_ble_set_adv_data(hci_cmd_buf, adv_data_len, (uint8_t *)adv_data);
+    API_vhci_host_send_packet(hci_cmd_buf, sz);
+}
+
+/*
+ * @brief: send HCI commands to perform BLE advertising;
+ */
+void bleAdvtTask(void *pvParameters)
+{
+    int cmd_cnt = 0;
+    bool send_avail = false;
+    API_vhci_host_register_callback(&vhci_host_cb);
+    printf("BLE advt task start\n");
+    while (1) {
+        vTaskDelay(1000 / portTICK_PERIOD_MS);
+        send_avail = API_vhci_host_check_send_available();
+        if (send_avail) {
+            switch (cmd_cnt) {
+            case 0: hci_cmd_send_reset(); ++cmd_cnt; break;
+            case 1: hci_cmd_send_ble_set_adv_param(); ++cmd_cnt; break;
+            case 2: hci_cmd_send_ble_set_adv_data(); ++cmd_cnt; break;
+            case 3: hci_cmd_send_ble_adv_start(); ++cmd_cnt; break;
+            }
+        }
+        printf("BLE Advertise, flag_send_avail: %d, cmd_sent: %d\n", send_avail, cmd_cnt);
+    }
+}
+
+void bt_app_main()
+{
+    xTaskCreatePinnedToCore(&bleAdvtTask, "bleAdvtTask", 2048, NULL, 5, NULL, 0);
+}
+

+ 10 - 0
examples/04_ble_adv/main/component.mk

@@ -0,0 +1,10 @@
+#
+# Main Makefile. This is basically the same as a component makefile.
+#
+# This Makefile should, at the very least, just include $(SDK_PATH)/make/component_common.mk. By default, 
+# this will take the sources in the src/ directory, compile them and link them into 
+# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable,
+# please read the ESP-IDF documents if you need to do this.
+#
+
+include $(IDF_PATH)/make/component_common.mk