1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #18439 from gschorcht/cpu/esp32/enable_ble_nimble

cpu/esp32: add Bluetooth LE and NimBLE host support
This commit is contained in:
benpicco 2022-08-24 13:50:54 +02:00 committed by GitHub
commit 2abc8501b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
49 changed files with 945 additions and 26 deletions

View File

@ -16,6 +16,17 @@ config HAS_CPU_ESP32
help
Indicates that the current CPU belongs to the ESP32x SoC series.
config HAS_ESP_BLE
bool
help
Indicates that the used ESP32x SoC supports Bluetooth LE.
config HAS_ESP_BLE_ESP32
bool
help
Indicates that the ESP32x SoC uses the SDK Bluetooth LE library
for the ESP32 variant.
config HAS_ESP_HW_COUNTER
bool
help

View File

@ -9,6 +9,13 @@ if TEST_KCONFIG && HAS_ARCH_ESP32
# define configuration menu entries that common for all ESP32x SoC variants
config MODULE_ESP_BLE
bool "Enable Bluetooth LE interface"
depends on HAS_ESP_BLE
select MODULE_ESP_IDF_BLE
select PACKAGE_ESP32_SDK_LIB_PHY
select PACKAGE_ESP32_SDK_LIB_BT_ESP32 if HAS_ESP_BLE_ESP32
config MODULE_ESP_JTAG
bool "Enable JTAG debugging interface"
depends on HAS_ESP_JTAG
@ -24,6 +31,7 @@ config MODULE_ESP_SPI_RAM
Say y to use external SPI RAM connected through the SPI interface.
rsource "bootloader/Kconfig"
rsource "esp-ble-nimble/Kconfig"
rsource "esp-idf/Kconfig"
rsource "esp-idf-api/Kconfig"
rsource "periph/Kconfig"

View File

@ -18,6 +18,10 @@ config CPU_FAM_ESP32
select CPU_CORE_XTENSA_LX6
select HAS_ARCH_ESP32
select HAS_CPU_ESP32
select HAS_BLE_NIMBLE
select HAS_BLE_NIMBLE_NETIF
select HAS_ESP_BLE
select HAS_ESP_BLE_ESP32
select HAS_ESP_HW_COUNTER
select HAS_ESP_WIFI_ENTERPRISE
select HAS_PUF_SRAM

View File

@ -13,6 +13,10 @@ ifneq (, $(filter esp_bootloader, $(USEMODULE)))
DIRS += bootloader
endif
ifneq (, $(filter esp_ble_nimble, $(USEMODULE)))
DIRS += esp-ble-nimble
endif
ifneq (, $(filter esp_eth, $(USEMODULE)))
DIRS += esp-eth
endif

View File

@ -17,6 +17,17 @@ ifneq (,$(filter cpp,$(USEMODULE)))
USEMODULE += pthread
endif
ifneq (,$(filter esp_ble,$(USEMODULE)))
# add additional modules and packages used for any BLE interface
FEATURES_REQUIRED += esp_ble
USEMODULE += esp_idf_ble
USEPKG += esp32_sdk_lib_phy
ifeq (esp32,$(CPU_FAM))
FEATURES_REQUIRED += esp_ble_esp32
USEPKG += esp32_sdk_lib_bt_esp32
endif
endif
ifneq (,$(filter esp_eth,$(USEMODULE)))
FEATURES_REQUIRED += esp_eth
USEMODULE += esp_idf_eth
@ -120,6 +131,14 @@ ifneq (,$(filter mtd,$(USEMODULE)))
USEMODULE += esp_idf_spi_flash
endif
ifneq (,$(filter nimble,$(USEPKG)))
USEMODULE += esp_ble
USEMODULE += esp_ble_nimble
USEMODULE += nimble_host
USEMODULE += nimble_transport_hci_h4
USEMODULE += ztimer_msec
endif
ifneq (,$(filter periph_adc,$(USEMODULE)))
USEMODULE += esp_idf_adc
endif

View File

@ -23,6 +23,13 @@ ifeq (xtensa,$(CPU_ARCH))
FEATURES_PROVIDED += esp_hw_counter
endif
ifeq (esp32,$(CPU_FAM))
FEATURES_PROVIDED += ble_nimble
FEATURES_PROVIDED += ble_nimble_netif
FEATURES_PROVIDED += esp_ble
FEATURES_PROVIDED += esp_ble_esp32
endif
ifneq (,$(filter esp32-wrover% esp32s2%r2 esp32s3%r2 esp32s3%r8 esp32s3%r8v,$(CPU_MODEL)))
FEATURES_PROVIDED += esp_spi_ram
ifneq (,$(filter esp32s3%r8 esp32s3%r8v,$(CPU_MODEL)))

View File

@ -36,6 +36,7 @@ else
$(error Unkwnown ESP32x SoC architecture)
endif
PSEUDOMODULES += esp_ble
PSEUDOMODULES += esp_bootloader
PSEUDOMODULES += esp_gdbstub
PSEUDOMODULES += esp_hw_counter
@ -80,6 +81,15 @@ ifneq (,$(filter xtensa%,$(TARGET_ARCH)))
INCLUDES += -I$(ESP32_SDK_DIR)/components/xtensa/$(CPU_FAM)/include
endif
ifneq (,$(filter esp_ble,$(USEMODULE)))
INCLUDES += -I$(ESP32_SDK_DIR)/components/bt/include/$(CPU_FAM)/include
endif
ifneq (,$(filter esp_ble_nimble,$(USEMODULE)))
INCLUDES += -I$(RIOTCPU)/$(CPU)/include/esp_ble_nimble
INCLUDES += $(NIMIBASE)/nimble/transport/common/hci_h4/include
endif
ifneq (,$(filter esp_spi_ram,$(USEMODULE)))
INCLUDES += -I$(ESP32_SDK_DIR)/components/esp_hw_support/include/soc/$(CPU_FAM)
endif
@ -150,8 +160,14 @@ ifneq (,$(filter xtensa%,$(TARGET_ARCH)))
endif
LINKFLAGS += -L$(RIOTCPU)/$(CPU)/ld/$(CPU_FAM)/
LINKFLAGS += -T$(RIOTCPU)/$(CPU)/ld/$(CPU_FAM)/memory.ld
ifeq (,$(filter esp_ble,$(USEMODULE)))
LINKFLAGS += -T$(RIOTCPU)/$(CPU)/ld/$(CPU_FAM)/memory.ld
else
LINKFLAGS += -T$(RIOTCPU)/$(CPU)/ld/$(CPU_FAM)/memory_bt.ld
endif
LINKFLAGS += -T$(RIOTCPU)/$(CPU)/ld/$(CPU_FAM)/sections.ld
LINKFLAGS += -T$(ESP32_SDK_DIR)/components/soc/$(CPU_FAM)/ld/$(CPU_FAM).peripherals.ld
LINKFLAGS += -T$(ESP32_SDK_DIR)/components/esp_rom/$(CPU_FAM)/ld/$(CPU_FAM).rom.api.ld
LINKFLAGS += -T$(ESP32_SDK_DIR)/components/esp_rom/$(CPU_FAM)/ld/$(CPU_FAM).rom.ld
@ -182,7 +198,7 @@ ifneq (,$(filter esp_wifi_any,$(USEMODULE)))
LINKFLAGS += -L$(ESP32_SDK_LIB_PHY_DIR)/$(CPU_FAM)
ARCHIVES += -lcoexist -lcore -lmesh -lnet80211 -lpp
ARCHIVES += -lphy -lstdc++
ifneq (,$(filter esp32,$(CPU_FAM)))
ifeq (esp32,$(CPU_FAM))
ARCHIVES += -lrtc
endif
endif
@ -192,6 +208,17 @@ ifneq (,$(filter esp_now,$(USEMODULE)))
ARCHIVES += -lespnow -lmesh
endif
# Libraries needed when using esp_ble
ifneq (,$(filter esp_ble,$(USEMODULE)))
LINKFLAGS += -L$(ESP32_SDK_LIB_PHY_DIR)/$(CPU_FAM)
LINKFLAGS += -L$(ESP32_SDK_LIB_BT_DIR)/$(CPU_FAM)
ARCHIVES += -lbtdm_app
ARCHIVES += -lphy -lstdc++
ifeq (esp32,$(CPU_FAM))
ARCHIVES += -lrtc
endif
endif
ifneq (,$(filter cpp,$(USEMODULE)))
ARCHIVES += -lstdc++
endif

View File

@ -55,6 +55,7 @@ This document describes the RIOT implementation for supported variants
2. [WiFi Network Interface](#esp32_wifi_network_interface)
3. [WiFi SoftAP Network Interface](#esp32_wifi_ap_network_interface)
4. [ESP-NOW Network Interface](#esp32_esp_now_network_interface)
4. [Bluetooth Interface](#esp32_esp_bluetooth_interface)
5. [Other Network Devices](#esp32_other_network_devices)
10. [Application-Specific Configurations](#esp32_application_specific_configurations)
1. [Make Variable `CFLAGS`](#esp32_config_make_variable)
@ -204,7 +205,7 @@ The key features of ESP32 are:
| SPIs | 4 | yes (2) |
| UARTs | 3 | yes |
| WiFi | IEEE 802.11 b/g/n built in | yes |
| Bluetooth | v4.2 BR/EDR and BLE | no |
| Bluetooth | v4.2 BR/EDR and BLE | yes |
| Ethernet | MAC interface with dedicated DMA and IEEE 1588 support | yes |
| CAN | version 2.0 | yes |
| IR | up to 8 channels TX/RX | no |
@ -335,7 +336,6 @@ at the moment:
- Only **one core** (the PRO CPU) is used because RIOT does not support running
multiple threads simultaneously.
- **Bluetooth** cannot be used at the moment.
- **Flash encryption** is not yet supported.
[Back to table of contents](#esp32_toc)
@ -1691,6 +1691,21 @@ the channel of the AP asvalue for the parameter 'ESP_NOW_CHANNEL'.
[Back to table of contents](#esp32_toc)
## Bluetooth Network Interface {#esp32_esp_bluetooth_interface}
The following ESP32x SoC variants (families) integrate a Bluetooth Link
Controller and a Bluetooth baseband system:
- ESP32 supports Bluetooth v4.2 BR/EDR and Bluetooth LE
- ESP32-C3, ESP32-S3 support Bluetooth 5 and Bluetooth mesh
The Bluetooth interface can be used with the Bluetooth host implementation
of the NimBLE package. Use one of the `nimble_*` modules for different
applications to enable the Bluetooth interface and the NimBLE host
implementation. Please refer to the NimBle package documentation for details.
[Back to table of contents](#esp32_toc)
## Other Network Devices {#esp32_other_network_devices}
RIOT provides a number of driver modules for different types of network

View File

@ -0,0 +1,22 @@
# Copyright (c) 2022 HAW Hamburg
#
# This file is subject to the terms and conditions of the GNU Lesser
# General Public License v2.1. See the file LICENSE in the top level
# directory for more details.
#
config MODULE_ESP_BLE_NIMBLE
bool "ESP32 Bluetooth LE HCI for NimBLE host"
depends on TEST_KCONFIG
depends on CPU_FAM_ESP32
depends on HAS_ESP_BLE
default y if TEST_KCONFIG && MODULE_NIMBLE
select MODULE_ESP_BLE
select MODULE_NIMBLE_HOST
select MODULE_NIMBLE_TRANSPORT_HCI_H4
select MODULE_ZTIMER_MSEC
config HAS_ESP_BLE
bool
help
Indicates that a ESP32 Buetooth LE controller.

View File

@ -0,0 +1,3 @@
MODULE=esp_ble_nimble
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,17 @@
/*
* Copyright (C) 2022 Gunar Schorcht
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @defgroup cpu_esp32_esp_ble_nimble ESP32 Bluetooth LE HCI for NimBLE host
* @ingroup cpu_esp32
* @brief ESP32 Bluetooth LE HCI implementation for NimBLE host
*
* This module realizes the HCI for NimBLE host using the ESP32 Bluetooth controller
*
* @author Gunar Schorcht <gunar@schorcht.net>
*/

View File

@ -0,0 +1,227 @@
/*
* Copyright (C) 2022 Gunar Schorcht
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup cpu_esp32_esp_ble_nimble
* @{
*
* @file
* @brief Implementation of the Bluetooth LE Host Controller Interface
*
* ESP32x SoC Bluetooth LE controller uses the uses UART H4 transport protocol.
*
* @author Gunar Schorcht <gunar@schorcht.net>
* @}
*/
#include "log.h"
#include "esp_bt.h"
#include "mutex.h"
#include "od.h"
#include "host/ble_hs.h"
#include "nimble/hci_common.h"
#include "nimble/nimble_port.h"
#include "nimble/transport/hci_h4.h"
#include "sysinit/sysinit.h"
#define ENABLE_DEBUG 0
#include "debug.h"
/* The size of an HCI command packet is defined as POOL_CMD_SIZE
* in `./nimble/transport/src/transport.c.`. Since there is no defined
* symbol in the header files, we have to define it here. According to
* the BLE specification, controllers must accept HCI command packets
* with up to 255 bytes of data excluding the header. */
#define BLE_HCI_CMD_SIZE (255 + BLE_HCI_CMD_HDR_LEN)
#define BLE_HCI_CMD_HDR_LEN (3)
#define BLE_HCI_EVT_HDR_LEN (2)
#define BLE_VHCI_TIMEOUT_MS 2000
/* Definition of UART H4 packet types */
enum {
BLE_HCI_UART_H4_NONE = 0x00,
BLE_HCI_UART_H4_CMD = 0x01,
BLE_HCI_UART_H4_ACL = 0x02,
BLE_HCI_UART_H4_SCO = 0x03,
BLE_HCI_UART_H4_EVT = 0x04
};
static const char *LOG_TAG = "esp_nimble";
static mutex_t _esp_vhci_semaphore = MUTEX_INIT;
static struct hci_h4_sm _esp_h4sm;
static void _ble_vhci_controller_ready_cb(void)
{
mutex_unlock(&_esp_vhci_semaphore);
}
static int _ble_vhci_packet_received_cb(uint8_t *data, uint16_t len)
{
/* process the HCI H4 formatted packet and call ble_transport_to_hs_* */
len = hci_h4_sm_rx(&_esp_h4sm, data, len);
return 0;
}
static const esp_vhci_host_callback_t vhci_host_cb = {
.notify_host_send_available = _ble_vhci_controller_ready_cb,
.notify_host_recv = _ble_vhci_packet_received_cb,
};
static inline int _ble_transport_to_ll(uint8_t *packet, uint16_t len)
{
uint8_t rc = 0;
/* check whether the controller is ready to accept packets */
if (!esp_vhci_host_check_send_available()) {
LOG_TAG_DEBUG(LOG_TAG, "Controller not ready to accept packets");
}
/* take the semaphore with timeout and send the packet to the controller */
if (ztimer_mutex_lock_timeout(ZTIMER_MSEC, &_esp_vhci_semaphore,
BLE_VHCI_TIMEOUT_MS) == 0) {
esp_vhci_host_send_packet(packet, len);
}
else {
rc = BLE_HS_ETIMEOUT_HCI;
}
return rc;
}
int ble_transport_to_ll_cmd_impl(void *buf)
{
uint16_t len;
uint8_t rc = 0;
uint8_t packet[BLE_HCI_CMD_SIZE + 1];
uint8_t* cmd = buf;
assert(cmd != NULL);
/* Prepare the HCI H4 formatted packet. HCI H4 uses one byte HCI packet
* indicator in front of the HCI command packet. */
len = BLE_HCI_CMD_HDR_LEN + cmd[2] + 1; /* overall length */
packet[0] = BLE_HCI_UART_H4_CMD; /* first byte is the packet indicator */
memcpy(packet + 1, cmd, len - 1);
if (ENABLE_DEBUG && IS_USED(MODULE_OD)) {
printf("CMD host to ctrl:\n");
od_hex_dump(packet + 1, len - 1, OD_WIDTH_DEFAULT);
}
/* send the packet */
rc = _ble_transport_to_ll(packet, len);
/* release the packet buffer */
ble_transport_free(buf);
return rc;
}
int ble_transport_to_ll_acl_impl(struct os_mbuf *om)
{
uint16_t len = 0;
uint8_t rc = 0;
uint8_t packet[MYNEWT_VAL(BLE_TRANSPORT_ACL_SIZE) + 1];
assert(om != NULL);
/* If this packet is zero length, just free it */
if (OS_MBUF_PKTLEN(om) == 0) {
os_mbuf_free_chain(om);
return 0;
}
/* Prepare the HCI H4 formatted packet. HCI H4 uses one byte HCI packet
indicator in front of the HCI command packet. */
packet[0] = BLE_HCI_UART_H4_ACL;
len++;
if (ENABLE_DEBUG && IS_USED(MODULE_OD)) {
printf("ACL host to ctrl:\n");
od_hex_dump(packet + 1,
(om->om_len < 32) ? om->om_len : 32, OD_WIDTH_DEFAULT);
}
os_mbuf_copydata(om, 0, OS_MBUF_PKTLEN(om), &packet[1]);
len += OS_MBUF_PKTLEN(om);
/* send the packet */
rc = _ble_transport_to_ll(packet, len);
/* release the mbuf */
os_mbuf_free_chain(om);
return rc;
}
static int _esp_hci_h4_frame_cb(uint8_t pkt_type, void *data)
{
int rc = 0;
switch (pkt_type) {
case HCI_H4_ACL:
if (ENABLE_DEBUG && IS_USED(MODULE_OD)) {
printf("ACL ctrl to host:\n");
od_hex_dump((uint8_t *)data, 4, OD_WIDTH_DEFAULT);
}
rc = ble_transport_to_hs_acl(data);
break;
case HCI_H4_EVT:
if (ENABLE_DEBUG && IS_USED(MODULE_OD)) {
printf("EVT ctrl to host:\n");
od_hex_dump((uint8_t *)data, ((uint8_t *)data)[1] + 2, OD_WIDTH_DEFAULT);
}
rc = ble_transport_to_hs_evt(data);
break;
default:
assert(0);
break;
}
return rc;
}
void esp_ble_nimble_init(void)
{
esp_err_t ret;
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
/* TODO: BLE mode only used, the memory for BT Classic could be released
if ((ret = esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT);) != ESP_OK) {
LOG_TAG_ERROR(LOG_TAG,
"Bluetooth controller release classic bt memory failed: %s",
esp_err_to_name(ret));
assert(0);
}
*/
/* init and enable the Bluetooth LE controller */
if ((ret = esp_bt_controller_init(&bt_cfg)) != ESP_OK) {
LOG_TAG_ERROR(LOG_TAG, "Bluetooth controller initialize failed: %d", ret);
assert(0);
}
if ((ret = esp_bt_controller_enable(ESP_BT_MODE_BLE)) != ESP_OK) {
LOG_TAG_ERROR(LOG_TAG, "Bluetooth controller enable failed: %d", ret);
assert(0);
}
/* register callbacks from Bluetooth LE controller */
if ((ret = esp_vhci_host_register_callback(&vhci_host_cb)) != ESP_OK) {
assert(0);
}
/* init HCI H4 processing */
hci_h4_sm_init(&_esp_h4sm, &hci_h4_allocs_from_ll, _esp_hci_h4_frame_cb);
}

View File

@ -18,6 +18,7 @@ config MODULE_ESP_IDF
Espressif IoT Development Framework.
rsource "adc/Kconfig"
rsource "ble/Kconfig"
rsource "common/Kconfig"
rsource "efuse/Kconfig"
rsource "eth/Kconfig"

View File

@ -8,6 +8,10 @@ ifneq (,$(filter esp_idf_adc,$(USEMODULE)))
DIRS += adc
endif
ifneq (,$(filter esp_idf_ble,$(USEMODULE)))
DIRS += ble
endif
ifneq (,$(filter esp_idf_common,$(USEMODULE)))
DIRS += common
endif

View File

@ -0,0 +1,16 @@
# Copyright (c) 2022 Gunar Schorcht
#
# This file is subject to the terms and conditions of the GNU Lesser
# General Public License v2.1. See the file LICENSE in the top level
# directory for more details.
#
config MODULE_ESP_IDF_BLE
bool
depends on TEST_KCONFIG
depends on MODULE_ESP_IDF
default y if MODULE_ESP_BLE
help
ESP-IDF code for Bluetooth LE interface.

View File

@ -0,0 +1,34 @@
MODULE = esp_idf_ble
# source files to be compiled for this module
ESP32_SDK_SRC = \
components/bt/controller/$(CPU_FAM)/bt.c \
#
ifeq (,$(filter esp_idf_wifi,$(USEMODULE)))
ESP32_SDK_SRC += \
components/esp_hw_support/port/$(CPU_FAM)/dport_access.c \
components/esp_phy/src/phy_init.c \
components/esp_wifi/src/wifi_init.c \
#
endif
INCLUDES += -I$(ESP32_SDK_DIR)/components/esp_event/include
INCLUDES += -I$(ESP32_SDK_DIR)/components/esp_netif/include
INCLUDES += -I$(ESP32_SDK_DIR)/components/esp_phy/include
INCLUDES += -I$(ESP32_SDK_DIR)/components/esp_phy/$(CPU_FAM)/include
INCLUDES += -I$(ESP32_SDK_DIR)/components/esp_wifi/include
INCLUDES += -I$(ESP32_SDK_DIR)/components/nvs_flash/include
INCLUDES += -I$(ESP32_SDK_DIR)/components/wpa_supplicant/esp_supplicant/include
INCLUDES += -I$(ESP32_SDK_DIR)/components/tcpip_adapter/include
CFLAGS += -Wno-cast-function-type
CFLAGS += -Wno-implicit-fallthrough
include $(RIOTBASE)/Makefile.base
ESP32_SDK_BIN = $(BINDIR)/$(MODULE)
include ../esp_idf.mk
include ../esp_idf_cflags.mk

View File

@ -18,6 +18,7 @@ ESP32_SDK_SRCXX = \
# additional include pathes required by this module
INCLUDES += -I$(ESP32_SDK_DIR)/components/esp_rom/include
INCLUDES += -I$(ESP32_SDK_DIR)/components/nvs_flash/include
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,41 @@
/*
* Copyright (C) 2022 Gunar Schorcht
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup cpu_esp32_esp_ble_nimble
* @{
*
* @file
* @brief NimBLE configuration for ESP32x SoCs
*
* @author Gunar Schorcht <gunar@schorcht.net>
*/
#ifndef ESP_BLE_NIMBLE_SYSCFG_SYSCFG_H
#define ESP_BLE_NIMBLE_SYSCFG_SYSCFG_H
#if !DOXYGEN
/* disable native transport mechanism and enable the custom transport mechanism */
#define MYNEWT_VAL_BLE_TRANSPORT_LL__custom (1)
#define MYNEWT_VAL_BLE_TRANSPORT_LL__native (0)
#include_next "syscfg/syscfg.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /* !DOXYGEN */
#endif /* ESP_BLE_NIMBLE_SYSCFG_SYSCFG_H */
/** @} */

View File

@ -38,7 +38,7 @@ extern "C" {
*/
#define CPU_INUM_GPIO 2 /**< Level interrupt with low priority 1 */
#define CPU_INUM_CAN 3 /**< Level interrupt with low priority 1 */
#define CPU_INUM_UART 5 /**< Level interrupt with low priority 1 */
#define CPU_INUM_UART 4 /**< Level interrupt with low priority 1 */
#define CPU_INUM_RTT 9 /**< Level interrupt with low priority 1 */
#define CPU_INUM_I2C 12 /**< Level interrupt with low priority 1 */
#define CPU_INUM_WDT 13 /**< Level interrupt with low priority 1 */
@ -47,6 +47,7 @@ extern "C" {
#define CPU_INUM_TIMER 19 /**< Level interrupt with medium priority 2 */
#define CPU_INUM_FRC2 20 /**< Level interrupt with medium priority 2 */
#define CPU_INUM_SYSTIMER 20 /**< Level interrupt with medium priority 2 */
#define CPU_INUM_BLE 21 /**< Level interrupt with medium priority 2 */
#define CPU_INUM_CACHEERR 25 /**< Level interrupt with high priority 4 */
/** @} */

View File

@ -100,10 +100,16 @@
#define CONFIG_PARTITION_TABLE_OFFSET 0x8000
/**
* Bluetooth configuration (DO NOT CHANGE)
* BLE driver configuration (DO NOT CHANGE)
*/
#define CONFIG_BT_ENABLED 0
#define CONFIG_BT_RESERVE_DRAM 0
#ifdef MODULE_ESP_BLE
#define CONFIG_ESP32_WIFI_ENABLED 1 /* WiFi module has to be enabled */
#define CONFIG_BT_ENABLED 1
#define CONFIG_BT_CONTROLLER_ONLY 1
#else
#define CONFIG_BT_ENABLED 0
#define CONFIG_BTDM_RESERVE_DRAM 0
#endif
/**
* SPI RAM configuration (DO NOT CHANGE)
@ -179,6 +185,9 @@
#if defined(MODULE_ESP_WIFI_AP) || defined(MODULE_ESP_NOW)
#define CONFIG_ESP_WIFI_SOFTAP_SUPPORT 1
#endif
#ifdef MODULE_ESP_BLE
#define CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE 1
#endif
#endif
/**

View File

@ -162,6 +162,55 @@ extern "C" {
#define CONFIG_ETH_DMA_TX_BUFFER_NUM 10
#endif
/**
* ESP32 specific BLE driver configuration (DO NOT CHANGE)
*/
#ifdef MODULE_ESP_BLE
#define CONFIG_BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD 20
#define CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP 1
#define CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM 100
#define CONFIG_BTDM_BLE_DEFAULT_SCA_250PPM 1
#define CONFIG_BTDM_BLE_SCAN_DUPL 1
#define CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF 1
#define CONFIG_BTDM_CTRL_BLE_MAX_CONN 3
#define CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF 3
#define CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF 0
#define CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF 0
#define CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF 0
#define CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED 1
#define CONFIG_BTDM_CTRL_HCI_MODE_VHCI 1
#define CONFIG_BTDM_CTRL_HLI 0 /* ESP-IDF uses 1 by default */
#define CONFIG_BTDM_CTRL_LPCLK_SEL_MAIN_XTAL 1
#define CONFIG_BTDM_CTRL_MODE_BLE_ONLY 1
#define CONFIG_BTDM_CTRL_MODEM_SLEEP 1
#define CONFIG_BTDM_CTRL_MODEM_SLEEP_MODE_ORIG 1
#define CONFIG_BTDM_CTRL_PCM_ROLE_EFF 0
#define CONFIG_BTDM_CTRL_PCM_POLAR_EFF 0
#define CONFIG_BTDM_CTRL_PINNED_TO_CORE_0 1
#define CONFIG_BTDM_CTRL_PINNED_TO_CORE 0
#define CONFIG_BTDM_RESERVE_DRAM 0xdb5c
#define CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE 200
#define CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE 1
#define CONFIG_BTDM_SCAN_DUPL_TYPE 0
#define CONFIG_BLE_ADV_REPORT_DISCARD_THRSHOLD CONFIG_ BTDM_BLE_ADV_REPORT_DISCARD_THRSHOLD
#define CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_NUM CONFIG_ BTDM_BLE_ADV_REPORT_FLOW_CTRL_NUM
#define CONFIG_BLE_ADV_REPORT_FLOW_CONTROL_SUPPORTED CONFIG_BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP
#define CONFIG_BLE_SCAN_DUPLICATE CONFIG_BTDM_BLE_SCAN_DUPL
#define CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN CONFIG_BTDM_CTRL_BLE_MAX_CONN
#define CONFIG_BTDM_CONTROLLER_FULL_SCAN_SUPPORTED CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED
#define CONFIG_BTDM_CONTROLLER_HCI_MODE_VHCI CONFIG_BTDM_CTRL_HCI_MODE_VHCI
#define CONFIG_BTDM_CONTROLLER_MODEM_SLEEP CONFIG_BTDM_CTRL_MODEM_SLEEP
#define CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY CONFIG_BTDM_CTRL_MODE_BLE_ONLY
#define CONFIG_DUPLICATE_SCAN_CACHE_SIZE CONFIG_BTDM_SCAN_DUPL_CACHE_SIZE
#define CONFIG_SCAN_DUPLICATE_BY_DEVICE_ADDR CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE
#else
#define CONFIG_BTDM_RESERVE_DRAM 0
#endif
#ifdef __cplusplus
}
#endif

View File

@ -79,6 +79,7 @@ static const struct intr_handle_data_t _irq_data_table[] = {
#if !defined(CPU_FAM_ESP32)
{ ETS_SYSTIMER_TARGET2_EDGE_INTR_SOURCE, CPU_INUM_SYSTIMER, 2 },
#endif
{ ETS_INTERNAL_SW1_INTR_SOURCE, CPU_INUM_BLE, 2 }
};
#define IRQ_DATA_TABLE_SIZE ARRAY_SIZE(_irq_data_table)

View File

@ -0,0 +1,103 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/* ESP32 Linker Script Memory Layout
This file describes the memory layout (memory blocks) as virtual
memory addresses.
esp32.project.ld contains output sections to link compiler output
into these memory blocks.
***
This linker script is passed through the C preprocessor to include
configuration options.
Please use preprocessor features sparingly! Restrict
to simple macros with numeric values, and/or #if/#endif blocks.
*/
/*
* Automatically generated file. DO NOT EDIT.
* Espressif IoT Development Framework (ESP-IDF) Configuration Header
*/
/* List of deprecated options */
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/* CPU instruction prefetch padding size for flash mmap scenario */
_esp_flash_mmap_prefetch_pad_size = 16;
/* CPU instruction prefetch padding size for memory protection scenario */
_esp_memprot_prefetch_pad_size = 0;
/* Memory alignment size for PMS */
_esp_memprot_align_size = 0;
/* If BT is not built at all */
MEMORY
{
/* All these values assume the flash cache is on, and have the blocks this uses subtracted from the length
of the various regions. The 'data access port' dram/drom regions map to the same iram/irom regions but
are connected to the data port of the CPU and eg allow bytewise access. */
/* IRAM for PRO cpu. Not sure if happy with this, this is MMU area... */
iram0_0_seg (RX) : org = 0x40080000, len = 0x20000
/* Even though the segment name is iram, it is actually mapped to flash
*/
iram0_2_seg (RX) : org = 0x400D0020, len = 0x330000-0x20
/*
(0x20 offset above is a convenience for the app binary image generation.
Flash cache has 64KB pages. The .bin file which is flashed to the chip
has a 0x18 byte file header, and each segment has a 0x08 byte segment
header. Setting this offset makes it simple to meet the flash cache MMU's
constraint that (paddr % 64KB == vaddr % 64KB).)
*/
/* Shared data RAM, excluding memory reserved for ROM bss/data/stack.
Enabling Bluetooth & Trace Memory features in menuconfig will decrease
the amount of RAM available.
Note: Length of this section *should* be 0x50000, and this extra DRAM is available
in heap at runtime. However due to static ROM memory usage at this 176KB mark, the
additional static memory temporarily cannot be used.
*/
dram0_0_seg (RW) : org = 0x3FFB0000 + 0xdb5c,
len = 0x2c200 - 0xdb5c
/* Flash mapped constant data */
drom0_0_seg (R) : org = 0x3F400020, len = 0x400000-0x20
/* (See iram0_2_seg for meaning of 0x20 offset in the above.) */
/* RTC fast memory (executable). Persists over deep sleep.
*/
rtc_iram_seg(RWX) : org = 0x400C0000, len = 0x2000 - 0
/* RTC fast memory (same block as above), viewed from data bus */
rtc_data_seg(RW) : org = 0x3ff80000, len = 0x2000 - 0
/* RTC slow memory (data accessible). Persists over deep sleep.
Start of RTC slow memory is reserved for ULP co-processor code + data, if enabled.
*/
rtc_slow_seg(RW) : org = 0x50000000 + 0,
len = 0x2000 - 0
/* external memory */
extern_ram_seg(RWX) : org = 0x3F800000,
len = 0x400000
}
_static_data_end = _bss_end;
/* Heap ends at top of dram0_0_seg */
_heap_end = 0x40000000 - 0x0;
_data_seg_org = ORIGIN(rtc_data_seg);
/* The lines below define location alias for .rtc.data section based on Kconfig option.
When the option is not defined then use slow memory segment
else the data will be placed in fast memory segment */
REGION_ALIAS("rtc_data_location", rtc_slow_seg );
REGION_ALIAS("default_code_seg", iram0_2_seg);
REGION_ALIAS("default_rodata_seg", drom0_0_seg);
/**
* If rodata default segment is placed in `drom0_0_seg`, then flash's first rodata section must
* also be first in the segment.
*/
/* TODO
ASSERT(_rodata_start == ORIGIN(default_rodata_seg),
".flash.appdesc section must be placed at the beginning of the rodata segment.")
*/

View File

@ -298,7 +298,7 @@ SECTIONS
KEEP (*(SORT(.esp_system_init_fn) SORT(.esp_system_init_fn.*)))
_esp_system_init_fn_array_end = ABSOLUTE(.);
*(EXCLUDE_FILE(*libbt.a *libbtdm_app.a *libnimble.a) .data EXCLUDE_FILE(*libbt.a *libbtdm_app.a *libnimble.a) .data.*)
*(EXCLUDE_FILE(*components/bt/* *libbtdm_app.a) .data EXCLUDE_FILE(*components/bt/* *libbtdm_app.a) .data.*)
*(.dram1 .dram1.*)
_coredump_dram_start = ABSOLUTE(.);
*(.dram1.coredump .dram1.coredump.*)
@ -306,7 +306,7 @@ SECTIONS
*components/app_trace/app_trace.*(.rodata .rodata.*)
*components/app_trace/app_trace_util.*(.rodata .rodata.*)
_bt_data_start = ABSOLUTE(.);
*libbt.a:(.data .data.*)
*components/bt/*(.data .data.*)
. = ALIGN(4);
_bt_data_end = ABSOLUTE(.);
_btdm_data_start = ABSOLUTE(.);
@ -416,7 +416,7 @@ SECTIONS
*(.dynbss .dynsbss .gnu.linkonce.b .gnu.linkonce.b.* .gnu.linkonce.sb .gnu.linkonce.sb.* .gnu.linkonce.sb2 .gnu.linkonce.sb2.* .sbss .sbss.* .sbss2 .sbss2.* .scommon .share.mem)
*(COMMON)
_bt_bss_start = ABSOLUTE(.);
*libbt.a:(.bss .bss.* COMMON)
*components/bt/*(.bss .bss.* COMMON)
. = ALIGN(4);
_bt_bss_end = ABSOLUTE(.);
_btdm_bss_start = ABSOLUTE(.);

View File

@ -55,7 +55,7 @@ ifneq (,$(filter netdev_default,$(USEMODULE)))
endif
else
# otherwise use esp_now as default netdev if no other netdev is enabled
ifeq (,$(filter esp_wifi esp_eth,$(USEMODULE)))
ifeq (,$(filter esp_wifi esp_eth nimble_netif nimble_netif_ext,$(USEMODULE)))
USEMODULE += esp_now
endif
endif

View File

@ -95,7 +95,8 @@ QueueHandle_t xQueueCreateCountingSemaphore (const UBaseType_t uxMaxCount,
queue = xQueueGenericCreate(uxMaxCount, queueSEMAPHORE_QUEUE_ITEM_LENGTH,
queueQUEUE_TYPE_COUNTING_SEMAPHORE);
DEBUG("%s pid=%d queue=%p\n", __func__, thread_getpid(), queue);
DEBUG("%s pid=%d queue=%p max=%d initial=%d\n", __func__,
thread_getpid(), queue, uxMaxCount, uxInitialCount);
if (queue != NULL) {
queue->item_level = uxInitialCount;
@ -279,7 +280,7 @@ BaseType_t IRAM_ATTR _queue_generic_send(QueueHandle_t xQueue,
else {
/* suspend the calling thread to wait for space in the queue */
thread_t *me = thread_get_active();
sched_set_status(me, STATUS_SEND_BLOCKED);
sched_set_status(me, STATUS_MUTEX_BLOCKED);
/* waiting list is sorted by priority */
thread_add_to_list(&queue->sending, me);
@ -407,7 +408,7 @@ BaseType_t IRAM_ATTR _queue_generic_recv (QueueHandle_t xQueue,
else {
/* suspend the calling thread to wait for an item in the queue */
thread_t *me = thread_get_active();
sched_set_status(me, STATUS_RECEIVE_BLOCKED);
sched_set_status(me, STATUS_MUTEX_BLOCKED);
/* waiting list is sorted by priority */
thread_add_to_list(&queue->receiving, me);
@ -509,11 +510,12 @@ UBaseType_t uxQueueMessagesWaiting( QueueHandle_t xQueue )
BaseType_t xQueueGiveFromISR (QueueHandle_t xQueue,
BaseType_t * const pxHigherPriorityTaskWoken)
{
/* this function only satisfies the linker and should not be called */
assert(0);
DEBUG("%s pid=%d prio=%d queue=%p woken=%p\n", __func__,
thread_getpid(), thread_get_priority(thread_get_active()),
xQueue, pxHigherPriorityTaskWoken);
DEBUG("%s\n", __func__);
return pdFALSE;
return _queue_generic_send(xQueue, NULL, queueSEND_TO_BACK,
0, pxHigherPriorityTaskWoken);
}
#endif /* DOXYGEN */

View File

@ -26,8 +26,9 @@ extern "C" {
#define configASSERT assert
#endif
#define portTICK_PERIOD_MS 10
#define configTICK_RATE_HZ ((TickType_t)100)
#define portTICK_PERIOD_MS 10
#define portTICK_RATE_MS portTICK_PERIOD_MS
#define BaseType_t portBASE_TYPE

View File

@ -0,0 +1,24 @@
/*
* Copyright (C) 2022 Gunar Schorcht
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*
* FreeRTOS to RIOT-OS adaption module for source code compatibility
*/
/* Empty file, only required for source code compatibility */
#ifndef FREERTOS_PORTABLE_H
#define FREERTOS_PORTABLE_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /* FREERTOS_PORTABLE_H */

View File

@ -108,6 +108,11 @@ UBaseType_t uxQueueMessagesWaiting( QueueHandle_t xQueue );
( pxHigherPriorityTaskWoken ), \
queueSEND_TO_BACK )
#define xQueueSendToBackFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) \
xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), \
( pxHigherPriorityTaskWoken ), \
queueSEND_TO_BACK )
#define xQueueOverwriteFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) \
xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), \
( pxHigherPriorityTaskWoken ), \

View File

@ -31,6 +31,7 @@ extern "C" {
#define taskENTER_CRITICAL portENTER_CRITICAL
#define taskEXIT_CRITICAL portEXIT_CRITICAL
#define taskSCHEDULER_NOT_STARTED 1
#define taskSCHEDULER_RUNNING 2
typedef enum {

View File

@ -10,3 +10,7 @@ USEMODULE += cpu_common
FEATURES_OPTIONAL += vdd_lc_filter_reg1
# reg0 feature denotes stage 0 two-stage regulator models
FEATURES_OPTIONAL += vdd_lc_filter_reg0
ifneq (,$(filter nimble,$(USEPKG)))
USEPKG += nrfx
endif

View File

@ -0,0 +1,14 @@
# Copyright (c) 2021 Gunar Schorcht
#
# This file is subject to the terms and conditions of the GNU Lesser
# General Public License v2.1. See the file LICENSE in the top level
# directory for more details.
#
config PACKAGE_ESP32_SDK_LIB_BT_ESP32
bool "ESP32 SDK Bluetooth library for the ESP32 SoC"
depends on TEST_KCONFIG
depends on HAS_ARCH_ESP32
depends on HAS_ESP_BLE_ESP32
help
Vendor SDK Bluetooth library for ESP32 SoC

View File

@ -0,0 +1,10 @@
PKG_NAME=esp32_sdk_lib_bt_esp32
PKG_URL=https://github.com/espressif/esp32-bt-lib
# This is a version in the v4.4.1 release branch
PKG_VERSION=b877f7e1fc98dccfcf4dbf31f215c5cb44ec3f0d
PKG_LICENSE=Apache-2.0
include $(RIOTBASE)/pkg/pkg.mk
# there is nothing to compile
all:

View File

@ -0,0 +1,4 @@
# This package can only be used with the ESP32 CPU
FEATURES_REQUIRED += arch_esp32
FEATURES_REQUIRED += esp_ble
FEATURES_REQUIRED += esp_ble_esp32

View File

@ -0,0 +1,3 @@
export ESP32_SDK_LIB_BT_DIR ?= $(PKGDIRBASE)/esp32_sdk_lib_bt_esp32
PSEUDOMODULES += esp32_sdk_lib_bt_esp32

View File

@ -0,0 +1,6 @@
/**
* @defgroup pkg_esp32_sdk_lib_bt_esp32 ESP32 SDK Bluetooth library for the ESP32 SoC
* @ingroup pkg_esp32_sdk
* @brief Vendor SDK Bluetooth library for ESP32 SoC by Espressif
* @see https://github.com/espressif/esp32-bt-lib
*/

View File

@ -38,12 +38,15 @@ nimble_porting_nimble:
$(QQ)"$(MAKE)" -C $(PDIR)/porting/nimble/src/ -f $(RIOTPKG)/$(PKG_NAME)/nimble.porting.mk MODULE=$@
nimble_npl_riot:
$(QQ)"$(MAKE)" -C $(PDIR)/porting/npl/riot/src/ -f $(RIOTBASE)/Makefile.base MODULE=$@
$(QQ)"$(MAKE)" -C $(PDIR)/porting/npl/riot/src/ -f $(RIOTPKG)/$(PKG_NAME)/nimble.npl.mk MODULE=$@
# generic modules
nimble_transport:
$(QQ)"$(MAKE)" -C $(PDIR)/nimble/transport/src/ -f $(RIOTBASE)/Makefile.base MODULE=$@
nimble_transport_hci_h4:
$(QQ)"$(MAKE)" -C $(PDIR)/nimble/transport/common/hci_h4/src/ -f $(RIOTBASE)/Makefile.base MODULE=$@
# host modules
nimble_host:
$(QQ)"$(MAKE)" -C $(PDIR)/nimble/host/src/ -f $(TDIR)/nimble.host.mk

View File

@ -3,8 +3,6 @@ USEMODULE += sema
USEMODULE += event_callback
USEMODULE += ztimer_msec
USEPKG += nrfx
# Requires nimble feature
FEATURES_REQUIRED += ble_nimble

View File

@ -50,6 +50,10 @@ endif
# include transport headers
INCLUDES += $(NIMIBASE)/nimble/transport/include
ifneq (,$(filter nimble_transport_hci_h4,$(USEMODULE)))
INCLUDES += $(NIMIBASE)/nimble/transport/common/hci_h4/include
endif
# include services
ifneq (,$(filter nimble_svc_ans,$(USEMODULE)))
INCLUDES += $(NIMIBASE)/nimble/host/services/ans/include

View File

@ -57,14 +57,14 @@
#endif
#include "controller/ble_ll.h"
static char _stack_controller[NIMBLE_CONTROLLER_STACKSIZE];
#endif
#ifdef MODULE_NIMBLE_RPBLE
#include "nimble_rpble.h"
#include "nimble_rpble_params.h"
#endif
static char _stack_controller[NIMBLE_CONTROLLER_STACKSIZE];
#endif
#ifdef MODULE_NIMBLE_HOST
static char _stack_host[NIMBLE_HOST_STACKSIZE];

7
pkg/nimble/nimble.npl.mk Normal file
View File

@ -0,0 +1,7 @@
ifeq (,$(filter nrf51 nrf52 nrf53,$(CPU_FAM)))
# nrf5x_isr.c does only compile for nRF5x MCUs
IGNORE := nrf5x_isr.c
SRC := $(filter-out $(IGNORE),$(wildcard *.c))
endif
include $(RIOTBASE)/Makefile.base

View File

@ -1,5 +1,9 @@
ifneq (,$(filter mynewt-core,$(USEMODULE)))
SRC = nimble_port.c
else ifeq (,$(filter nrf51 nrf52 nrf53,$(CPU_FAM)))
# hal_timer.c does only compile for nRF5x MCUs
IGNORE := hal_timer.c
SRC := $(filter-out $(IGNORE),$(wildcard *.c))
endif
include $(RIOTBASE)/Makefile.base

View File

@ -195,6 +195,11 @@ extern void asymcute_handler_run(void);
AUTO_INIT(asymcute_handler_run,
AUTO_INIT_PRIO_MOD_ASYMCUTE);
#endif
#if IS_USED(MODULE_ESP_BLE_NIMBLE)
extern void esp_ble_nimble_init(void);
AUTO_INIT(esp_ble_nimble_init,
AUTO_INIT_PRIO_MOD_ESP_BLE_NIMBLE);
#endif
#if IS_USED(MODULE_NIMBLE)
extern void nimble_riot_init(void);
AUTO_INIT(nimble_riot_init,

View File

@ -209,6 +209,12 @@ extern "C" {
*/
#define AUTO_INIT_PRIO_MOD_ASYMCUTE 1310
#endif
#ifndef AUTO_INIT_PRIO_MOD_ESP_BLE_NIMBLE
/**
* @brief ESP BLE NimBLE priority
*/
#define AUTO_INIT_PRIO_MOD_ESP_BLE_NIMBLE 1319
#endif
#ifndef AUTO_INIT_PRIO_MOD_NIMBLE
/**
* @brief NimBLE priority

View File

@ -0,0 +1,68 @@
include ../Makefile.tests_common
# If no BOARD is found in the environment, use this default:
BOARD ?= esp32-wroom-32
# This has to be the absolute path to the RIOT base directory:
RIOTBASE ?= $(CURDIR)/../..
# We use the xtimer and the shell in this example
USEMODULE += shell
# works only for ESP32x SoC that have WiFi and BLE
FEATURES_REQUIRED += esp_ble
FEATURES_REQUIRED += esp_wifi
# use ESP WiFi in station mode as network interface
USEMODULE += esp_wifi
# configure and use Nimble
USEPKG += nimble
USEMODULE += nimble_scanner
USEMODULE += nimble_scanlist
# Include packages that pull up and auto-init the link layer.
# NOTE: 6LoWPAN will be included if IEEE802.15.4 devices are present
USEMODULE += netdev_default
USEMODULE += auto_init_gnrc_netif
# Enable single interface optimization.
# Remove this if more than one interface is present
USEMODULE += gnrc_netif_single
# Activate ICMPv6 error messages
USEMODULE += gnrc_icmpv6_error
# Specify the mandatory networking module for a IPv6 routing node
USEMODULE += gnrc_ipv6_router_default
# Add a routing protocol
USEMODULE += gnrc_rpl
USEMODULE += auto_init_gnrc_rpl
# Additional networking modules that can be dropped if not needed
USEMODULE += gnrc_icmpv6_echo
USEMODULE += gnrc_udp_cmd
# Add also the shell, some shell commands
USEMODULE += shell
USEMODULE += shell_commands
USEMODULE += ps
USEMODULE += netstats_l2
USEMODULE += netstats_ipv6
USEMODULE += netstats_rpl
# Optionally include DNS support. This includes resolution of names at an
# upstream DNS server and the handling of RDNSS options in Router Advertisements
# to auto-configure that upstream DNS server.
# USEMODULE += sock_dns # include DNS client
# USEMODULE += gnrc_ipv6_nib_dns # include RDNSS option handling
# Comment this out to disable code in RIOT that does safety checking
# which is not needed in a production environment but helps in the
# development process:
DEVELHELP ?= 1
# Change this to 0 show compiler invocation lines by default:
QUIET ?= 1
EXTERNAL_BOARD_DIRS += $(RIOTBASE)/tests/external_board_dirs/esp-ci-boards
include $(RIOTBASE)/Makefile.include
# Set a custom channel if needed
include $(RIOTMAKE)/default-radio-settings.inc.mk

View File

@ -0,0 +1,20 @@
# About
This application tests the coexistence of Bluetooth and WiFi interface.
For that purpose it uses the `NimBLE` BLE stack as a scanner and the
ESP32x WiFi interface simultaneously.
# Usage
Comile and flash the application with command
```
CFLAGS='-DESP_WIFI_SSID=\"myssid\" -DESP_WIFI_PASS=\"mypass\"'
BOARD=esp32-wroom-32 make -C tests/nimble_esp_wifi_coexist flash term
```
Once the test application is flashed and the WiFi connection is established,
ping the node from the host with command
```
sudo ping6 fe80::xxxx:xxxx:xxxx:xxxx%eth0 -i 0.01 -s 1280
```
to produce network load and execute the command `scan` on the node.
The scan should still work.

View File

@ -0,0 +1,106 @@
/*
* Copyright (C) 2019 Freie Universität Berlin
* 2022 Gunar Schorcht
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup examples
* @{
*
* @file
* @brief Example for using NimBLE as a BLE scanner and ESP WiFi in coexistence
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @author Gunar Schorcht <gunar@schorcht.net>
*
* @}
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "msg.h"
#include "timex.h"
#include "ztimer.h"
#include "shell.h"
#include "nimble_scanner.h"
#include "nimble_scanlist.h"
#define MAIN_QUEUE_SIZE (8)
static msg_t _main_msg_queue[MAIN_QUEUE_SIZE];
/* default scan interval */
#define DEFAULT_SCAN_INTERVAL_MS 30
/* default scan duration (1s) */
#define DEFAULT_DURATION_MS (1 * MS_PER_SEC)
int _cmd_scan(int argc, char **argv)
{
uint32_t timeout = DEFAULT_DURATION_MS;
if ((argc == 2) && (memcmp(argv[1], "help", 4) == 0)) {
printf("usage: %s [timeout in ms]\n", argv[0]);
return 0;
}
if (argc >= 2) {
timeout = atoi(argv[1]);
}
nimble_scanlist_clear();
printf("Scanning for %"PRIu32" ms now ...\n", timeout);
nimble_scanner_start();
ztimer_sleep(ZTIMER_MSEC, timeout);
nimble_scanner_stop();
puts("Done, results:");
nimble_scanlist_print();
puts("");
return 0;
}
static const shell_command_t _commands[] = {
{ "scan", "trigger a BLE scan", _cmd_scan },
{ NULL, NULL, NULL }
};
int main(void)
{
puts("NimBLE Scanner Example Application");
puts("Type `scan help` for more information");
/* in this example, we want Nimble to scan 'full time', so we set the
* window equal the interval */
nimble_scanner_cfg_t params = {
.itvl_ms = DEFAULT_SCAN_INTERVAL_MS,
.win_ms = DEFAULT_SCAN_INTERVAL_MS,
#if IS_USED(MODULE_NIMBLE_PHY_CODED)
.flags = NIMBLE_SCANNER_PHY_1M | NIMBLE_SCANNER_PHY_CODED,
#else
.flags = NIMBLE_SCANNER_PHY_1M,
#endif
};
/* initialize the nimble scanner */
nimble_scanlist_init();
nimble_scanner_init(&params, nimble_scanlist_update);
/* we need a message queue for the thread running the shell in order to
* receive potentially fast incoming networking packets */
msg_init_queue(_main_msg_queue, MAIN_QUEUE_SIZE);
puts("RIOT network stack example application");
/* start shell */
puts("All up, running the shell now");
char line_buf[SHELL_DEFAULT_BUFSIZE];
shell_run(_commands, line_buf, SHELL_DEFAULT_BUFSIZE);
return 0;
}