Skip to content

Commit

Permalink
Merge branch 'feature/add_bluetooth_nimble_lightsleep_example_v4.4' i…
Browse files Browse the repository at this point in the history
…nto 'release/v4.4'

bt: Added an example of Bluetooth using light sleep(v4.4)

See merge request espressif/esp-idf!23694
  • Loading branch information
jack0c committed Jun 9, 2023
2 parents b4c06ed + 7312f37 commit 7053e48
Show file tree
Hide file tree
Showing 18 changed files with 1,312 additions and 2 deletions.
4 changes: 2 additions & 2 deletions components/bt/controller/esp32c3/Kconfig.in
Original file line number Diff line number Diff line change
Expand Up @@ -390,15 +390,15 @@ menu "MODEM SLEEP Options"
than other bluetooth low power clock sources.
config BT_CTRL_LPCLK_SEL_EXT_32K_XTAL
bool "External 32kHz crystal"
depends on ESP32C3_RTC_CLK_SRC_EXT_CRYS
depends on (ESP32C3_RTC_CLK_SRC_EXT_CRYS || ESP32S3_RTC_CLK_SRC_EXT_CRYS)
help
External 32kHz crystal has a nominal frequency of 32.768kHz and provides good frequency
stability. If used as Bluetooth low power clock, External 32kHz can support Bluetooth
modem sleep to be used with both DFS and light sleep.

config BT_CTRL_LPCLK_SEL_RTC_SLOW
bool "Internal 150kHz RC oscillator"
depends on ESP32C3_RTC_CLK_SRC_INT_RC
depends on (ESP32C3_RTC_CLK_SRC_INT_RC || ESP32S3_RTC_CLK_SRC_INT_RC)
help
Internal 150kHz RC oscillator. The accuracy of this clock is a lot larger than 500ppm which is required
in Bluetooth communication, so don't select this option in scenarios such as BLE connection state.
Expand Down
6 changes: 6 additions & 0 deletions examples/bluetooth/nimble/power_save/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# The following lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)

include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(power_save)
8 changes: 8 additions & 0 deletions examples/bluetooth/nimble/power_save/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
# project subdirectory.
#

PROJECT_NAME := power_save

include $(IDF_PATH)/make/project.mk
113 changes: 113 additions & 0 deletions examples/bluetooth/nimble/power_save/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
| Supported Targets | ESP32 | ESP32-C3 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- |

Bluetooth Power Save Example
=================================

This example is based on the [bleprph](../bleprph) example to show how to use the bluetooth power save mode.

If the modem sleep mode is enabled, bluetooth will switch periodically between active and sleep.
In sleep state, RF, PHY and BB are turned off in order to reduce power consumption.

This example contains five build configurations. For each configuration, a few configuration options are set:
- `sdkconfig.defaults.esp32`: ESP32 uses 32kHz XTAL as low power clock in light sleep enabled.
- `sdkconfig.defaults.esp32c3`: ESP32C3 uses 32kHz XTAL as low power clock in light sleep enabled.
- `sdkconfig.40m.esp32c3`: ESP32C3 uses main XTAL as low power clock in light sleep enabled.
- `sdkconfig.defaults.esp32s3`: ESP32S3 uses 32kHz XTAL as low power clock in light sleep enabled.
- `sdkconfig.40m.esp32s3`: ESP32S3 uses main XTAL as low power clock in light sleep enabled.
## How to use example

### Hardware Required

This example should be able to run on any commonly available ESP32/ESP32-C3/ESP32-S3 development board.

### Configure the project

```
idf.py menuconfig
```

1. Configure RTC clock source:
- `Component config > Hardware Settings > RTC Clock Config > RTC clock source`
2. Enable power management:
- `Component config > Power Management > [*] Support for power management`
3. Configure FreeRTOS:
- `Component config > FreeRTOS > Kernel`
- `(1000) configTICK_RATE_HZ`
- `[*] configUSE_TICKLESS_IDLE`
- `(3) configEXPECTED_IDLE_TIME_BEFORE_SLEEP`
4. Enable power down MAC and baseband:
- `Component config > PHY > [*] Power down MAC and baseband of Wi-Fi and Bluetooth when PHY is disabled`
5. Enable bluetooth modem sleep:
- `Component config > Bluetooth > Controller Options > MODEM SLEEP Options`
- `[*] Bluetooth modem sleep`
- `[*] Bluetooth Modem sleep Mode 1`
6. Configure bluetooth low power clock:
- `Component config > Bluetooth > Controller Options > MODEM SLEEP Options > Bluetooth modem sleep > Bluetooth Modem sleep Mode 1 > Bluetooth low power clock`
7. Enable power up main XTAL during light sleep:
- `Component config > Bluetooth > Controller Options > MODEM SLEEP Options > [*] power up main XTAL during light sleep`

### Build and Flash

```
idf.py -D SDKCONFIG_DEFAULTS="sdkconfig.defaults;sdkconfig.40m.esp32c3" set-target ESP32C3 build
```

* `-D SDKCONFIG_DEFAULTS` select configuration file to be used for creating app sdkconfig.
* `set-target ` Set the chip target to build.


To flash the project and see the output, run:


```
idf.py -p PORT flash monitor
```

(Replace PORT with the name of the serial port to use.)

(To exit the serial monitor, type ``Ctrl-]``.)

See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.

## Example Output

When you run this example, the prints the following at the very begining:

```
I (333) cpu_start: Starting scheduler.
I (347) pm: Frequency switching config: CPU_MAX: 160, APB_MAX: 80, APB_MIN: 40, Light sleep: ENABLED
I (351) sleep: Enable automatic switching of GPIO sleep configuration
I (358) BTDM_INIT: BT controller compile version [f2e5d81]
I (365) BTDM_INIT: Bluetooth will use main XTAL as Bluetooth sleep clock.
I (372) phy_init: phy_version 912,d001756,Jun 2 2022,16:28:07
I (411) system_api: Base MAC address is not set
I (412) system_api: read default base MAC address from EFUSE
I (412) BTDM_INIT: Bluetooth MAC: 7c:df:a1:61:b6:f6
I (419) NimBLE_BLE_PRPH: BLE Host Task Started
I (424) uart: queue free spaces: 8
I (432) NimBLE: GAP procedure initiated: stop advertising.
I (435) NimBLE: Device Address:
I (437) NimBLE: 7c:df:a1:61:b6:f6
I (441) NimBLE:
I (446) NimBLE: GAP procedure initiated: advertise;
I (450) NimBLE: disc_mode=2
I (453) NimBLE: adv_channel_map=0 own_addr_type=0 adv_filter_policy=0 adv_itvl_min=0 adv_itvl_max=0
I (463) NimBLE:
```

## Typical current consumption with management enabled

| | max current | modem sleep | light sleep (main XTAL)| light sleep (32KHz XTAL)|
|-------- | ----------- | ------------ | ---------------------- |------------------------ |
| ESP32 | 231 mA | 14.1 mA | X | 1.9 mA |
| ESP32C3 | 262 mA | 12 mA | 2.3 mA | 140 uA |
| ESP32S3 | 240 mA | 17.9 mA | 3.3 mA | 230 uA |
X: This feature is currently not supported.

## Example Breakdown

- ESP32 does not support the use of main XTAL in light sleep mode, so an external 32kHz crystal is required.
7 changes: 7 additions & 0 deletions examples/bluetooth/nimble/power_save/main/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
set(srcs "main.c"
"gatt_svr.c"
"misc.c"
"scli.c")

idf_component_register(SRCS "${srcs}"
INCLUDE_DIRS ".")
127 changes: 127 additions & 0 deletions examples/bluetooth/nimble/power_save/main/Kconfig.projbuild
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
menu "Example Configuration"

choice EXAMPLE_MAX_CPU_FREQ
prompt "Maximum CPU frequency"
default EXAMPLE_MAX_CPU_FREQ_160
depends on PM_ENABLE
help
Maximum CPU frequency to use for dynamic frequency scaling.

config EXAMPLE_MAX_CPU_FREQ_80
bool "80 MHz"
config EXAMPLE_MAX_CPU_FREQ_160
bool "160 MHz"
config EXAMPLE_MAX_CPU_FREQ_240
bool "240 MHz"
depends on IDF_TARGET_ESP32 || IDF_TARGET_ESP32S3
endchoice

config EXAMPLE_MAX_CPU_FREQ_MHZ
int
default 80 if EXAMPLE_MAX_CPU_FREQ_80
default 160 if EXAMPLE_MAX_CPU_FREQ_160
default 240 if EXAMPLE_MAX_CPU_FREQ_240

choice EXAMPLE_MIN_CPU_FREQ
prompt "Minimum CPU frequency"
default EXAMPLE_MIN_CPU_FREQ_40M
depends on PM_ENABLE
help
Minimum CPU frequency to use for dynamic frequency scaling.
Should be set to XTAL frequency or XTAL frequency divided by integer.

config EXAMPLE_MIN_CPU_FREQ_80M
bool "80 MHz"
depends on !(IDF_TARGET_ESP32 && EXAMPLE_MAX_CPU_FREQ_240)
help
ESP32 does not support switching between 240M and 80M.The root cause
is that when switching between 240M and 80M, we need to disable
BBPLL and then re-enable it with a different frequency.Since the
Bluetooth baseband works from PLL frequency, it will temporarily
lose its 80 MHz clock, while the BBPLL is disabled.
config EXAMPLE_MIN_CPU_FREQ_40M
bool "40 MHz (use with 40MHz XTAL)"
depends on XTAL_FREQ_40 || XTAL_FREQ_AUTO
config EXAMPLE_MIN_CPU_FREQ_20M
bool "20 MHz (use with 40MHz XTAL)"
depends on XTAL_FREQ_40 || XTAL_FREQ_AUTO
config EXAMPLE_MIN_CPU_FREQ_10M
bool "10 MHz (use with 40MHz XTAL)"
depends on XTAL_FREQ_40 || XTAL_FREQ_AUTO
endchoice

config EXAMPLE_MIN_CPU_FREQ_MHZ
int
default 80 if EXAMPLE_MIN_CPU_FREQ_80M
default 40 if EXAMPLE_MIN_CPU_FREQ_40M
default 20 if EXAMPLE_MIN_CPU_FREQ_20M
default 10 if EXAMPLE_MIN_CPU_FREQ_10M

config EXAMPLE_ADVERTISE_INTERVAL
int "BLE Advertise interval"
range 0 5000
default 100
help
Wake up interval for BLE advertising. Unit: 1 microsecond.

choice EXAMPLE_USE_IO_TYPE
prompt "I/O Capability"
default BLE_SM_IO_CAP_NO_IO
help
I/O capability of device.

config BLE_SM_IO_CAP_DISP_ONLY
bool "DISPLAY ONLY"
config BLE_SM_IO_CAP_DISP_YES_NO
bool "DISPLAY YESNO"
config BLE_SM_IO_CAP_KEYBOARD_ONLY
bool "KEYBOARD ONLY"
config BLE_SM_IO_CAP_NO_IO
bool "Just works"
config BLE_SM_IO_CAP_KEYBOARD_DISP
bool "Both KEYBOARD & DISPLAY"
endchoice

config EXAMPLE_IO_TYPE
int
default 0 if BLE_SM_IO_CAP_DISP_ONLY
default 1 if BLE_SM_IO_CAP_DISP_YES_NO
default 2 if BLE_SM_IO_CAP_KEYBOARD_ONLY
default 3 if BLE_SM_IO_CAP_NO_IO
default 4 if BLE_SM_IO_CAP_KEYBOARD_DISP

config EXAMPLE_BONDING
bool
default n
prompt "Use Bonding"
help
Use this option to enable/disable bonding.

config EXAMPLE_MITM
bool
default n
prompt "MITM security"
help
Use this option to enable/disable MITM security.

config EXAMPLE_USE_SC
bool
depends on BT_NIMBLE_SM_SC
default n
prompt "Use Secure Connection feature"
help
Use this option to enable/disable Security Manager Secure Connection 4.2 feature.

config EXAMPLE_ENCRYPTION
bool
prompt "Enable Link Encryption"
help
This adds Encrypted Read and Write permissions in the custom GATT server.

config EXAMPLE_RESOLVE_PEER_ADDR
bool
prompt "Enable resolving peer address"
help
Use this option to enable resolving peer's address.

endmenu
56 changes: 56 additions & 0 deletions examples/bluetooth/nimble/power_save/main/bleprph.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* 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 H_BLEPRPH_
#define H_BLEPRPH_

#include <stdbool.h>
#include "nimble/ble.h"
#include "modlog/modlog.h"
#ifdef __cplusplus
extern "C" {
#endif

struct ble_hs_cfg;
struct ble_gatt_register_ctxt;

/** GATT server. */
#define GATT_SVR_SVC_ALERT_UUID 0x1811
#define GATT_SVR_CHR_SUP_NEW_ALERT_CAT_UUID 0x2A47
#define GATT_SVR_CHR_NEW_ALERT 0x2A46
#define GATT_SVR_CHR_SUP_UNR_ALERT_CAT_UUID 0x2A48
#define GATT_SVR_CHR_UNR_ALERT_STAT_UUID 0x2A45
#define GATT_SVR_CHR_ALERT_NOT_CTRL_PT 0x2A44

void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg);
int gatt_svr_init(void);

/* Console */
int scli_init(void);
int scli_receive_key(int *key);

/** Misc. */
void print_bytes(const uint8_t *bytes, int len);
void print_addr(const void *addr);

#ifdef __cplusplus
}
#endif

#endif
4 changes: 4 additions & 0 deletions examples/bluetooth/nimble/power_save/main/component.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#
# "main" pseudo-component makefile.
#
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
Loading

0 comments on commit 7053e48

Please sign in to comment.