diff --git a/samples/boards/stm32/power_mgmt/stm32wb_ble/CMakeLists.txt b/samples/boards/stm32/power_mgmt/stm32wb_ble/CMakeLists.txt new file mode 100644 index 00000000000..9464b38612a --- /dev/null +++ b/samples/boards/stm32/power_mgmt/stm32wb_ble/CMakeLists.txt @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(ble_shutdown) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/boards/stm32/power_mgmt/stm32wb_ble/README.rst b/samples/boards/stm32/power_mgmt/stm32wb_ble/README.rst new file mode 100644 index 00000000000..8a395be20f8 --- /dev/null +++ b/samples/boards/stm32/power_mgmt/stm32wb_ble/README.rst @@ -0,0 +1,24 @@ +.. _boards-stm32-power_mgmt-stm32wb_ble-sample: + +Boards: STM32WB BLE Power Management +#################################### + +Overview +******** + +A simple application demonstrating the BLE operations (advertising) with +Zephyr power management enabled (:kconfig:`CONFIG_PM`). + +After startup, a first 2 seconds beacon is performed, 1 second break and +beacon is started again. +Finally, platform shutdown is triggered. It can be restarted by pressing the +board reset button. + +Using a power measurement tool, user can observe the platform reaching STOP2 mode +before beacon is started and between advertising peaks besides as SHUTDOWN mode +when requested. + +Requirements +************ + +* For now, only compatible with nucleo_wb55rg. diff --git a/samples/boards/stm32/power_mgmt/stm32wb_ble/prj.conf b/samples/boards/stm32/power_mgmt/stm32wb_ble/prj.conf new file mode 100644 index 00000000000..de6fe12424b --- /dev/null +++ b/samples/boards/stm32/power_mgmt/stm32wb_ble/prj.conf @@ -0,0 +1,5 @@ +CONFIG_BT=y +CONFIG_BT_DEVICE_NAME="Test beacon" +CONFIG_PM=y + +#CONFIG_DEBUG=y diff --git a/samples/boards/stm32/power_mgmt/stm32wb_ble/sample.yaml b/samples/boards/stm32/power_mgmt/stm32wb_ble/sample.yaml new file mode 100644 index 00000000000..15aa44dd842 --- /dev/null +++ b/samples/boards/stm32/power_mgmt/stm32wb_ble/sample.yaml @@ -0,0 +1,7 @@ +sample: + name: Bluetooth shutdown +tests: + sample.boards.stm32.pm.stm32wb_ble_pm: + harness: bluetooth + platform_allow: nucleo_wb55rg + tags: bluetooth pm diff --git a/samples/boards/stm32/power_mgmt/stm32wb_ble/src/main.c b/samples/boards/stm32/power_mgmt/stm32wb_ble/src/main.c new file mode 100644 index 00000000000..1e1fd57ffc7 --- /dev/null +++ b/samples/boards/stm32/power_mgmt/stm32wb_ble/src/main.c @@ -0,0 +1,122 @@ +/* main.c - Application main entry point */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * Copyright (c) 2021 Linaro Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#define DEVICE_NAME CONFIG_BT_DEVICE_NAME +#define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1) + +/* + * Set Advertisement data. Based on the Eddystone specification: + * https://github.com/google/eddystone/blob/master/protocol-specification.md + * https://github.com/google/eddystone/tree/master/eddystone-url + */ +static const struct bt_data ad[] = { + BT_DATA_BYTES(BT_DATA_FLAGS, BT_LE_AD_NO_BREDR), + BT_DATA_BYTES(BT_DATA_UUID16_ALL, 0xaa, 0xfe), + BT_DATA_BYTES(BT_DATA_SVC_DATA16, + 0xaa, 0xfe, /* Eddystone UUID */ + 0x10, /* Eddystone-URL frame type */ + 0x00, /* Calibrated Tx power at 0m */ + 0x00, /* URL Scheme Prefix http://www. */ + 'z', 'e', 'p', 'h', 'y', 'r', + 'p', 'r', 'o', 'j', 'e', 'c', 't', + 0x08) /* .org */ +}; + +/* Set Scan Response data */ +static const struct bt_data sd[] = { + BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN), +}; + +static void bt_ready(int err) +{ + char addr_s[BT_ADDR_LE_STR_LEN]; + bt_addr_le_t addr = {0}; + size_t count = 1; + + if (err) { + printk("Bluetooth init failed (err %d)\n", err); + return; + } + + printk("Bluetooth initialized\n"); + + k_sleep(K_MSEC(500)); + + /* Start advertising */ + err = bt_le_adv_start(BT_LE_ADV_NCONN_IDENTITY, ad, ARRAY_SIZE(ad), + sd, ARRAY_SIZE(sd)); + if (err) { + printk("Advertising failed to start (err %d)\n", err); + return; + } + + /* For connectable advertising you would use + * bt_le_oob_get_local(). For non-connectable non-identity + * advertising an non-resolvable private address is used; + * there is no API to retrieve that. + */ + + bt_id_get(&addr, &count); + bt_addr_le_to_str(&addr, addr_s, sizeof(addr_s)); + + printk("Beacon started, advertising as %s\n", addr_s); + + k_sleep(K_SECONDS(2)); + + err = bt_le_adv_stop(); + if (err != 0) { + printk("Advertising failed to stop: %d", err); + return; + } + + printk("Beacon stopped\n"); + + k_sleep(K_SECONDS(1)); + + /* Start advertising */ + err = bt_le_adv_start(BT_LE_ADV_NCONN_IDENTITY, ad, ARRAY_SIZE(ad), + sd, ARRAY_SIZE(sd)); + if (err) { + printk("Advertising failed to start (err %d)\n", err); + return; + } + + printk("Beacon started\n"); +} + +void main(void) +{ + int err; + + printk("Starting Beacon Demo\n"); + + k_sleep(K_MSEC(500)); + + /* Initialize the Bluetooth Subsystem */ + err = bt_enable(bt_ready); + if (err) { + printk("Bluetooth init failed (err %d)\n", err); + } + + k_sleep(K_SECONDS(6)); + + printk("Device shutdown\n"); + + pm_power_state_force((struct pm_state_info){PM_STATE_SOFT_OFF, 0, 0}); +}