Samples: Bluetooth: Add ST BLE Demo sample
This sample demonstrates BLE peripheral for ST BLE Sensor. You can test button notification and LED service using ST BLE Sensor Android application Signed-off-by: Marcio Montenegro <mtuxpe@gmail.com>
This commit is contained in:
parent
0297e7ec15
commit
dd5d2e37f5
12
samples/bluetooth/st_ble_sensor/CMakeLists.txt
Normal file
12
samples/bluetooth/st_ble_sensor/CMakeLists.txt
Normal file
|
@ -0,0 +1,12 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
cmake_minimum_required(VERSION 3.13.1)
|
||||
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
|
||||
project(st_ble_sensor)
|
||||
|
||||
FILE(GLOB app_sources src/*.c)
|
||||
target_sources(app PRIVATE
|
||||
${app_sources}
|
||||
)
|
||||
|
||||
zephyr_library_include_directories($ENV{ZEPHYR_BASE}/samples/bluetooth)
|
41
samples/bluetooth/st_ble_sensor/README.rst
Normal file
41
samples/bluetooth/st_ble_sensor/README.rst
Normal file
|
@ -0,0 +1,41 @@
|
|||
.. _bluetooth-st_ble_sensor:
|
||||
|
||||
Bluetooth: ST BLE Sensor Demo
|
||||
#############################
|
||||
|
||||
Overview
|
||||
********
|
||||
|
||||
This application demonstrates BLE peripheral by exposing vendor-specific
|
||||
GATT services. Currently only button notification and LED service are
|
||||
implemented. Other BLE sensor services can easily be added.
|
||||
See `BlueST protocol`_ document for details of how to add a new service.
|
||||
|
||||
Requirements
|
||||
************
|
||||
|
||||
* `ST BLE Sensor Android app <ST BLE Sensor app>`_
|
||||
* A board with BLE support
|
||||
|
||||
Building and Running
|
||||
********************
|
||||
|
||||
This sample can be found under :zephyr_file:`samples/bluetooth/st_ble_sensor` in the
|
||||
Zephyr tree.
|
||||
|
||||
See :ref:`bluetooth samples section <bluetooth-samples>` for details.
|
||||
|
||||
.. _ST BLE Sensor app:
|
||||
https://play.google.com/store/apps/details?id=com.st.bluems
|
||||
|
||||
.. _ST Nucleo WB55RG:
|
||||
https://www.st.com/en/microcontrollers-microprocessors/stm32wb55rg.html
|
||||
|
||||
.. _STM32CubeProgrammer:
|
||||
https://www.st.com/en/development-tools/stm32cubeprog.html
|
||||
|
||||
.. _BlueST protocol:
|
||||
https://www.st.com/resource/en/user_manual/dm00550659.pdf
|
||||
|
||||
.. _STM32WB github:
|
||||
https://github.com/STMicroelectronics/STM32CubeWB/tree/master/Projects/STM32WB_Copro_Wireless_Binaries
|
8
samples/bluetooth/st_ble_sensor/prj.conf
Normal file
8
samples/bluetooth/st_ble_sensor/prj.conf
Normal file
|
@ -0,0 +1,8 @@
|
|||
CONFIG_BT=y
|
||||
CONFIG_BT_DEBUG_LOG=y
|
||||
CONFIG_BT_PERIPHERAL=y
|
||||
CONFIG_BT_DEVICE_NAME="P2PSRV1"
|
||||
CONFIG_BT_GATT_CLIENT=y
|
||||
CONFIG_BT_DEBUG=y
|
||||
CONFIG_LOG=y
|
||||
CONFIG_LOG_BUFFER_SIZE=2048
|
8
samples/bluetooth/st_ble_sensor/sample.yaml
Normal file
8
samples/bluetooth/st_ble_sensor/sample.yaml
Normal file
|
@ -0,0 +1,8 @@
|
|||
sample:
|
||||
description: TBD
|
||||
name: TBD
|
||||
tests:
|
||||
sample.bluetooth.st_ble_sensor:
|
||||
harness: bluetooth
|
||||
platform_whitelist: nucleo_wb55rg
|
||||
tags: bluetooth
|
81
samples/bluetooth/st_ble_sensor/src/button_svc.c
Normal file
81
samples/bluetooth/st_ble_sensor/src/button_svc.c
Normal file
|
@ -0,0 +1,81 @@
|
|||
/** @file
|
||||
* @brief Button Service sample
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2019 Marcio Montenegro <mtuxpe@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/types.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/printk.h>
|
||||
#include <sys/byteorder.h>
|
||||
#include <zephyr.h>
|
||||
#include <drivers/gpio.h>
|
||||
#include <logging/log.h>
|
||||
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/hci.h>
|
||||
#include <bluetooth/conn.h>
|
||||
#include <bluetooth/uuid.h>
|
||||
#include <bluetooth/gatt.h>
|
||||
#include "button_svc.h"
|
||||
|
||||
LOG_MODULE_REGISTER(button_svc);
|
||||
|
||||
#define BUT_PORT DT_ALIAS_SW0_GPIOS_CONTROLLER
|
||||
#define BUT_PIN DT_ALIAS_SW0_GPIOS_PIN
|
||||
|
||||
extern struct bt_conn *conn;
|
||||
extern struct bt_gatt_service_static stsensor_svc[];
|
||||
extern volatile bool notify_enable;
|
||||
|
||||
static struct device *button_dev;
|
||||
static struct gpio_callback gpio_cb;
|
||||
u16_t but_val;
|
||||
|
||||
void button_pressed(struct device *gpiob, struct gpio_callback *cb,
|
||||
u32_t pins)
|
||||
{
|
||||
int err;
|
||||
|
||||
LOG_INF("Button SW1 pressed");
|
||||
if (conn) {
|
||||
if (notify_enable) {
|
||||
err = bt_gatt_notify(NULL, &stsensor_svc->attrs[2],
|
||||
&but_val, sizeof(but_val));
|
||||
if (err) {
|
||||
LOG_ERR("Notify error: %d", err);
|
||||
} else {
|
||||
LOG_INF("Send notify ok");
|
||||
but_val = (but_val == 0) ? 0x100 : 0;
|
||||
}
|
||||
} else {
|
||||
LOG_INF("Notify not enabled");
|
||||
}
|
||||
} else {
|
||||
LOG_INF("BLE not connected");
|
||||
}
|
||||
}
|
||||
|
||||
int button_init(void)
|
||||
{
|
||||
button_dev = device_get_binding(BUT_PORT);
|
||||
if (!button_dev) {
|
||||
return (-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
gpio_pin_configure(button_dev, BUT_PIN,
|
||||
GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE |
|
||||
GPIO_PUD_PULL_UP | GPIO_INT_DEBOUNCE |
|
||||
GPIO_INT_ACTIVE_LOW);
|
||||
gpio_init_callback(&gpio_cb, button_pressed, BIT(BUT_PIN));
|
||||
gpio_add_callback(button_dev, &gpio_cb);
|
||||
gpio_pin_enable_callback(button_dev, BUT_PIN);
|
||||
but_val = 0;
|
||||
return 0;
|
||||
}
|
19
samples/bluetooth/st_ble_sensor/src/button_svc.h
Normal file
19
samples/bluetooth/st_ble_sensor/src/button_svc.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
/** @file
|
||||
* @brief Button Service
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2019 Marcio Montenegro <mtuxpe@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int button_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
49
samples/bluetooth/st_ble_sensor/src/led_svc.c
Normal file
49
samples/bluetooth/st_ble_sensor/src/led_svc.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
/** @file
|
||||
* @brief Button Service sample
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2019 Marcio Montenegro <mtuxpe@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/types.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/printk.h>
|
||||
#include <sys/byteorder.h>
|
||||
#include <zephyr.h>
|
||||
#include <drivers/gpio.h>
|
||||
#include <logging/log.h>
|
||||
|
||||
LOG_MODULE_REGISTER(led_svc);
|
||||
|
||||
#define LED_PORT DT_ALIAS_LED0_GPIOS_CONTROLLER
|
||||
#define LED DT_ALIAS_LED0_GPIOS_PIN
|
||||
|
||||
struct device *led_dev;
|
||||
bool led_state;
|
||||
|
||||
void led_on_off(u32_t led_state)
|
||||
{
|
||||
if (led_dev) {
|
||||
gpio_pin_write(led_dev, LED, led_state);
|
||||
}
|
||||
}
|
||||
|
||||
int led_init(void)
|
||||
{
|
||||
led_dev = device_get_binding(LED_PORT);
|
||||
if (!led_dev) {
|
||||
return (-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
/* Set LED pin as output */
|
||||
gpio_pin_configure(led_dev, LED, GPIO_DIR_OUT);
|
||||
led_state = false;
|
||||
gpio_pin_write(led_dev, LED, 0);
|
||||
led_on_off(0);
|
||||
return 0;
|
||||
}
|
20
samples/bluetooth/st_ble_sensor/src/led_svc.h
Normal file
20
samples/bluetooth/st_ble_sensor/src/led_svc.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
/** @file
|
||||
* @brief LED Service sample
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2019 Marcio Montenegro <mtuxpe@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void led_on_off(u32_t led_state);
|
||||
int led_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
192
samples/bluetooth/st_ble_sensor/src/main.c
Normal file
192
samples/bluetooth/st_ble_sensor/src/main.c
Normal file
|
@ -0,0 +1,192 @@
|
|||
/* main.c - Application main entry point */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2015-2016 Intel Corporation
|
||||
* Copyright (c) 2019 Marcio Montenegro <mtuxpe@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/types.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/printk.h>
|
||||
#include <sys/byteorder.h>
|
||||
#include <zephyr.h>
|
||||
#include <drivers/gpio.h>
|
||||
#include <logging/log.h>
|
||||
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/hci.h>
|
||||
#include <bluetooth/conn.h>
|
||||
#include <bluetooth/uuid.h>
|
||||
#include <bluetooth/gatt.h>
|
||||
#include "button_svc.h"
|
||||
#include "led_svc.h"
|
||||
|
||||
LOG_MODULE_REGISTER(main);
|
||||
|
||||
extern u16_t but_val;
|
||||
extern struct device *led_dev;
|
||||
extern bool led_state;
|
||||
|
||||
/* Prototype */
|
||||
static ssize_t recv(struct bt_conn *conn,
|
||||
const struct bt_gatt_attr *attr, const void *buf,
|
||||
u16_t len, u16_t offset, u8_t flags);
|
||||
|
||||
/* ST Custom Service */
|
||||
static struct bt_uuid_128 st_service_uuid = BT_UUID_INIT_128(
|
||||
0x8f, 0xe5, 0xb3, 0xd5, 0x2e, 0x7f, 0x4a, 0x98,
|
||||
0x2a, 0x48, 0x7a, 0xcc, 0x40, 0xfe, 0x00, 0x00);
|
||||
|
||||
/* ST LED service */
|
||||
static struct bt_uuid_128 led_char_uuid = BT_UUID_INIT_128(
|
||||
0x19, 0xed, 0x82, 0xae, 0xed, 0x21, 0x4c, 0x9d,
|
||||
0x41, 0x45, 0x22, 0x8e, 0x41, 0xfe, 0x00, 0x00);
|
||||
|
||||
/* ST Notify button service */
|
||||
static struct bt_uuid_128 but_notif_uuid = BT_UUID_INIT_128(
|
||||
0x19, 0xed, 0x82, 0xae, 0xed, 0x21, 0x4c, 0x9d,
|
||||
0x41, 0x45, 0x22, 0x8e, 0x42, 0xfe, 0x00, 0x00);
|
||||
|
||||
#define DEVICE_NAME CONFIG_BT_DEVICE_NAME
|
||||
#define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1)
|
||||
#define ADV_LEN 12
|
||||
|
||||
/* Advertising data */
|
||||
static u8_t manuf_data[ADV_LEN] = {
|
||||
0x01 /*SKD version */,
|
||||
0x83 /* STM32WB - P2P Server 1 */,
|
||||
0x00 /* GROUP A Feature */,
|
||||
0x00 /* GROUP A Feature */,
|
||||
0x00 /* GROUP B Feature */,
|
||||
0x00 /* GROUP B Feature */,
|
||||
0x00, /* BLE MAC start -MSB */
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00, /* BLE MAC stop */
|
||||
};
|
||||
|
||||
static const struct bt_data ad[] = {
|
||||
BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
|
||||
BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN),
|
||||
BT_DATA(BT_DATA_MANUFACTURER_DATA, manuf_data, ADV_LEN)
|
||||
};
|
||||
|
||||
/* BLE connection */
|
||||
struct bt_conn *conn;
|
||||
/* Notification state */
|
||||
volatile bool notify_enable;
|
||||
|
||||
static void mpu_ccc_cfg_changed(const struct bt_gatt_attr *attr, u16_t value)
|
||||
{
|
||||
ARG_UNUSED(attr);
|
||||
notify_enable = (value == BT_GATT_CCC_NOTIFY);
|
||||
LOG_INF("Notification %s", notify_enable ? "enabled" : "disabled");
|
||||
}
|
||||
|
||||
/* The embedded board is acting as GATT server.
|
||||
* The ST BLE Android app is the BLE GATT client.
|
||||
*/
|
||||
|
||||
/* ST BLE Sensor GATT services and characteristic */
|
||||
|
||||
BT_GATT_SERVICE_DEFINE(stsensor_svc,
|
||||
BT_GATT_PRIMARY_SERVICE(&st_service_uuid),
|
||||
BT_GATT_CHARACTERISTIC(&led_char_uuid.uuid,
|
||||
BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE_WITHOUT_RESP,
|
||||
BT_GATT_PERM_WRITE, NULL, recv, (void *)1),
|
||||
BT_GATT_CHARACTERISTIC(&but_notif_uuid.uuid, BT_GATT_CHRC_NOTIFY,
|
||||
BT_GATT_PERM_READ, NULL, NULL, &but_val),
|
||||
BT_GATT_CCC(mpu_ccc_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),
|
||||
);
|
||||
|
||||
static ssize_t recv(struct bt_conn *conn,
|
||||
const struct bt_gatt_attr *attr, const void *buf,
|
||||
u16_t len, u16_t offset, u8_t flags)
|
||||
{
|
||||
if (led_dev) {
|
||||
if (led_state == true) {
|
||||
led_on_off(0);
|
||||
LOG_INF("Turn off LED");
|
||||
} else {
|
||||
led_on_off(1);
|
||||
LOG_INF("Turn on LED");
|
||||
}
|
||||
|
||||
led_state = !led_state;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bt_ready(int err)
|
||||
{
|
||||
if (err) {
|
||||
LOG_ERR("Bluetooth init failed (err %d)", err);
|
||||
return;
|
||||
}
|
||||
LOG_INF("Bluetooth initialized");
|
||||
/* Start advertising */
|
||||
err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), NULL, 0);
|
||||
if (err) {
|
||||
LOG_ERR("Advertising failed to start (err %d)", err);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INF("Configuration mode: waiting connections...");
|
||||
}
|
||||
|
||||
static void connected(struct bt_conn *connected, u8_t err)
|
||||
{
|
||||
if (err) {
|
||||
LOG_ERR("Connection failed (err %u)", err);
|
||||
} else {
|
||||
LOG_INF("Connected");
|
||||
if (!conn) {
|
||||
conn = bt_conn_ref(connected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void disconnected(struct bt_conn *disconn, u8_t reason)
|
||||
{
|
||||
if (conn) {
|
||||
bt_conn_unref(conn);
|
||||
conn = NULL;
|
||||
}
|
||||
|
||||
LOG_INF("Disconnected (reason %u)", reason);
|
||||
}
|
||||
|
||||
static struct bt_conn_cb conn_callbacks = {
|
||||
.connected = connected,
|
||||
.disconnected = disconnected,
|
||||
};
|
||||
|
||||
void main(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = button_init();
|
||||
if (err) {
|
||||
LOG_ERR("Button init error: (err %d)", err);
|
||||
}
|
||||
|
||||
led_init();
|
||||
bt_conn_cb_register(&conn_callbacks);
|
||||
|
||||
/* Initialize the Bluetooth Subsystem */
|
||||
err = bt_enable(bt_ready);
|
||||
if (err) {
|
||||
LOG_ERR("Bluetooth init failed (err %d)", err);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
k_sleep(K_SECONDS(1));
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue