From a75c2d467c94768e388bbe780a4526ce8d7385ce Mon Sep 17 00:00:00 2001 From: H4CK3R-01 Date: Fri, 8 Sep 2023 13:28:04 +0200 Subject: [PATCH] Added new bluetooth samples --- data/main.c | 1 + script.sh | 131 ++++++++++++++++++++++--- snippets/bluetooth/base/code1.txt | 128 ++++++++++++++++++++++++ snippets/bluetooth/base/config.txt | 6 ++ snippets/bluetooth/button/button_svc.c | 54 ++++++++++ snippets/bluetooth/button/button_svc.h | 26 +++++ snippets/bluetooth/button/code1.txt | 21 ++++ snippets/bluetooth/button/code2.txt | 17 ++++ snippets/bluetooth/led/code1.txt | 6 ++ snippets/bluetooth/led/code2.txt | 17 ++++ snippets/bluetooth/led/led_svc.c | 52 ++++++++++ snippets/bluetooth/led/led_svc.h | 25 +++++ 12 files changed, 469 insertions(+), 15 deletions(-) create mode 100644 snippets/bluetooth/base/code1.txt create mode 100644 snippets/bluetooth/base/config.txt create mode 100644 snippets/bluetooth/button/button_svc.c create mode 100644 snippets/bluetooth/button/button_svc.h create mode 100644 snippets/bluetooth/button/code1.txt create mode 100644 snippets/bluetooth/button/code2.txt create mode 100644 snippets/bluetooth/led/code1.txt create mode 100644 snippets/bluetooth/led/code2.txt create mode 100644 snippets/bluetooth/led/led_svc.c create mode 100644 snippets/bluetooth/led/led_svc.h diff --git a/data/main.c b/data/main.c index 7fbe9b0..c1f9887 100644 --- a/data/main.c +++ b/data/main.c @@ -8,6 +8,7 @@ int main(void) { + int err; printk("Zephyr Example Application %s\n", APP_VERSION_STRING); return 0; diff --git a/script.sh b/script.sh index 884d76a..3c988e4 100755 --- a/script.sh +++ b/script.sh @@ -6,7 +6,7 @@ HEIGHT=-1 WIDTH=-1 # Choices -PLATTFORM=nrf52840dongle_nrf52840 +PLATTFORM=esp32_devkitc_wroom CONNECTIVITY= INTERFACES= PROTOCOLS= @@ -32,7 +32,8 @@ main_dialog() { "4" "Build project" \ "5" "Flash project" \ "6" "Clean build directory" \ - "7" "Exit") + "7" "Get Shell" \ + "8" "Exit") case $selection in 1 ) @@ -54,6 +55,10 @@ main_dialog() { clean_build_dir ;; 7 ) + clear + /bin/bash + ;; + 8 ) clear exit ;; @@ -99,6 +104,7 @@ plattform_dialog() { --no-cancel \ --radiolist "Select plattform:" $HEIGHT $WIDTH 4 \ esp32c3_devkitm "ESP32-C3" $(equals "$PLATTFORM" "esp32c3_devkitm") \ + esp32_devkitc_wroom "ESP32" $(equals "$PLATTFORM" "esp32_devkitc_wroom") \ nrf5340dk_nrf5340_cpuapp "nRF5340 DK" $(equals "$PLATTFORM" "nrf5340dk_nrf5340_cpuapp") \ nrf52840dongle_nrf52840 "nRF52840 Dongle" $(equals "$PLATTFORM" "nrf52840dongle_nrf52840") \ thingy91_nrf9160_ns "Thingy:91 (nRF9160)" $(equals "$PLATTFORM" "thingy91_nrf9160_ns") \ @@ -109,6 +115,46 @@ plattform_dialog() { fi } +ble_dialog() { + # TODO + ble=$( dialog --stdout \ + --backtitle "Connectivity" \ + --menu "Please select:" $HEIGHT $WIDTH 4 \ + 1 "WiFi" \ + 2 "Bluetooth" \ + 3 "BLE" \ + 4 "LoRaWAN" \ + 5 "NB-IoT") + + case $connectivity in + 1 ) # WiFi + # TODO + ;; + 2 ) # Bluetooth + sed -i '/int main(void)/e cat /opt/snippets/ble_gatt/code1.txt' /workdir/app/src/main.c + + code2=$(cat /opt/snippets/ble_gatt/code2.txt) + echo "$code2" >> /workdir/app/src/peripheral_gatt_write.c + + code3=$(cat /opt/snippets/ble_gatt/code3.txt) + echo "$code3" >> /workdir/app/src/gatt_write_common.c + + config=$(cat /opt/snippets/ble_gatt/config.txt) + echo "$config" >> /workdir/app/prj.conf + + display_result 'Added functionality' "Added functionality successfully at the end of main.c.\nYou have to call the function like in the example manually." + ;; + 3 ) # BLE + ;; + 4 ) # LoRaWAN + # TODO + ;; + 5 ) # NB-IoT + # TODO + ;; + esac +} + connectivity_dialog() { # TODO connectivity=$( dialog --stdout \ @@ -116,31 +162,76 @@ connectivity_dialog() { --menu "Please select:" $HEIGHT $WIDTH 4 \ 1 "WiFi" \ 2 "Bluetooth" \ - 3 "LoRaWAN" \ - 4 "NB-IoT") + 3 "BLE" \ + 4 "LoRaWAN" \ + 5 "NB-IoT") case $connectivity in 1 ) # WiFi # TODO ;; 2 ) # Bluetooth - sed -i '/int main(void)/e cat snippets/ble_gatt/code1.txt' /workdir/app/src/main.c + sed -i '/int main(void)/e cat /opt/snippets/ble_gatt/code1.txt' /workdir/app/src/main.c - code2=$(cat snippets/ble_gatt/code2.txt) + code2=$(cat /opt/snippets/ble_gatt/code2.txt) echo "$code2" >> /workdir/app/src/peripheral_gatt_write.c - code3=$(cat snippets/ble_gatt/code3.txt) + code3=$(cat /opt/snippets/ble_gatt/code3.txt) echo "$code3" >> /workdir/app/src/gatt_write_common.c - config=$(cat snippets/ble_gatt/config.txt) + config=$(cat /opt/snippets/ble_gatt/config.txt) echo "$config" >> /workdir/app/prj.conf display_result 'Added functionality' "Added functionality successfully at the end of main.c.\nYou have to call the function like in the example manually." ;; - 3 ) # LoRaWAN + 3 ) # BLE + features=$(dialog --stdout \ + --backtitle "BLE features" \ + --checklist "Select BLE features:" $HEIGHT $WIDTH 4 \ + 2 "LED" ON \ + 3 "Button" ON ) + + # Base + sed -i '/int main(void)/e cat /opt/snippets/bluetooth/base/code1.txt' /workdir/app/src/main.c + + config=$(cat /opt/snippets/bluetooth/base/config.txt) + echo "$config" >> /workdir/app/prj.conf + + # Button + if [[ "$features" == *"3"* ]]; then + sed -i '/#include /a#include "button_svc.h"' /workdir/app/src/main.c + sed -i '/LOG_MODULE_REGISTER(main);/astatic uint16_t but_val;' /workdir/app/src/main.c + sed -i '/static struct bt_uuid_128 st_service_uuid = BT_UUID_INIT_128(BT_UUID_128_ENCODE(0x0000fe40, 0xcc7a, 0x482a, 0x984a, 0x7f2ed5b3e58f));/astatic struct bt_uuid_128 but_notif_uuid = BT_UUID_INIT_128(BT_UUID_128_ENCODE(0x0000fe42, 0x8e22, 0x4541, 0x9d4c, 0x21edae82ed19));' /workdir/app/src/main.c + sed -i '/BT_GATT_PRIMARY_SERVICE(&st_service_uuid),/aBT_GATT_CHARACTERISTIC(&but_notif_uuid.uuid, BT_GATT_CHRC_NOTIFY, BT_GATT_PERM_READ, NULL, NULL, &but_val),' /workdir/app/src/main.c + + sed -i '/static void bt_ready(int err)/e cat /opt/snippets/bluetooth/button/code1.txt' /workdir/app/src/main.c + + sed -i '/int main(void)/e cat /opt/snippets/bluetooth/button/code2.txt' /workdir/app/src/main.c + + cp /opt/snippets/bluetooth/button/button_svc.h /workdir/app/src/ + cp /opt/snippets/bluetooth/button/button_svc.c /workdir/app/src/ + fi + + # LED + if [[ "$features" == *"2"* ]]; then + sed -i '/#include /a#include "led_svc.h"' /workdir/app/src/main.c + sed -i '/static struct bt_uuid_128 st_service_uuid = BT_UUID_INIT_128(BT_UUID_128_ENCODE(0x0000fe40, 0xcc7a, 0x482a, 0x984a, 0x7f2ed5b3e58f));/astatic struct bt_uuid_128 led_char_uuid = BT_UUID_INIT_128(BT_UUID_128_ENCODE(0x0000fe41, 0x8e22, 0x4541, 0x9d4c, 0x21edae82ed19));' /workdir/app/src/main.c + sed -i '/BT_GATT_PRIMARY_SERVICE(&st_service_uuid),/aBT_GATT_CHARACTERISTIC(&led_char_uuid.uuid, BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE_WITHOUT_RESP, BT_GATT_PERM_WRITE, NULL, recv, (void *)1),' /workdir/app/src/main.c + + sed -i '/static void bt_ready(int err)/e cat /opt/snippets/bluetooth/led/code1.txt' /workdir/app/src/main.c + + sed -i '/int main(void)/e cat /opt/snippets/bluetooth/led/code2.txt' /workdir/app/src/main.c + + cp /opt/snippets/bluetooth/led/led_svc.h /workdir/app/src/ + cp /opt/snippets/bluetooth/led/led_svc.c /workdir/app/src/ + fi + + display_result 'Added functionality' "Added functionality successfully at the end of main.c.\nYou have to call the function like in the example manually." + ;; + 4 ) # LoRaWAN # TODO ;; - 4 ) # NB-IoT + 5 ) # NB-IoT # TODO ;; esac @@ -199,9 +290,9 @@ sensors_dialog() { case $sensors in 1 ) # Button - sed -i '/int main(void)/e cat snippets/button/code.txt' /workdir/app/src/main.c + sed -i '/int main(void)/e cat /opt/snippets/button/code.txt' /workdir/app/src/main.c - config=$(cat snippets/button/config.txt) + config=$(cat /opt/snippets/button/config.txt) echo "$config" >> /workdir/app/prj.conf display_result 'Added functionality' "Added functionality successfully at the end of main.c.\nYou have to call the function like in the example manually." @@ -227,9 +318,9 @@ actuators_dialog() { case $actuators in 1 ) # LED - sed -i '/int main(void)/e cat snippets/led/code.txt' /workdir/app/src/main.c + sed -i '/int main(void)/e cat /opt/snippets/led/code.txt' /workdir/app/src/main.c - config=$(cat snippets/led/config.txt) + config=$(cat /opt/snippets/led/config.txt) echo "$config" >> /workdir/app/prj.conf display_result 'Added functionality' "Added functionality successfully at the end of main.c.\nYou have to call the function like in the example manually." @@ -280,7 +371,15 @@ flash_project() { case "$PLATTFORM" in "nrf52840dongle_nrf52840") - display_result 'Flash project' "Please run those commands in an environment where nrfutil and the compiled hex files are available:\\n\\n\\nnrfutil pkg generate --hw-version 52 --sd-req=0x00 --application build/zephyr/zephyr.hex --application-version 1 mcuboot.zip\\n\\nnrfutil dfu usb-serial -pkg mcuboot.zip -p /dev/ttyACM0" + display_result 'Flash project' \ + "Please run those commands in an environment where nrfutil and the compiled hex files are available: \ + \\n\\n\\nnrfutil pkg generate --hw-version 52 --sd-req=0x00 --application build/zephyr/zephyr.hex --application-version 1 mcuboot.zip \ + \\n\\nnrfutil dfu usb-serial -pkg mcuboot.zip -p /dev/ttyACM0" ;; + "esp32_devkitc_wroom") + display_result 'Flash project' \ + "Please run those commands in an environment where esptool.py and the compiled bin files are available: \ + \\n\\n\\nesptool.py --chip auto --baud 921600 --before default_reset --after hard_reset write_flash -u --flash_mode dio --flash_freq 40m --flash_size detect 0x1000 app/build/esp-idf/build/bootloader/bootloader.bin 0x8000 app/build/esp-idf/build/partitions_singleapp.bin 0x10000 app/build/zephyr/zephyr.bin" + ;; *) display_result "Error" "Board not configured in this tool yet\nSee https://docs.zephyrproject.org/latest/boards/index.html#boards" @@ -315,6 +414,8 @@ then sudo apt update && sudo apt install dialog fi +cd /workdir + while true; do main_dialog done \ No newline at end of file diff --git a/snippets/bluetooth/base/code1.txt b/snippets/bluetooth/base/code1.txt new file mode 100644 index 0000000..371e414 --- /dev/null +++ b/snippets/bluetooth/base/code1.txt @@ -0,0 +1,128 @@ + + +/* --------------------------- */ +/* BLE */ +/* --------------------------- */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(main); + +static ssize_t recv(struct bt_conn *conn, const struct bt_gatt_attr *attr, const void *buf, uint16_t len, uint16_t offset, uint8_t flags); + +/* ST Custom Service */ +static struct bt_uuid_128 st_service_uuid = BT_UUID_INIT_128(BT_UUID_128_ENCODE(0x0000fe40, 0xcc7a, 0x482a, 0x984a, 0x7f2ed5b3e58f)); + +#define DEVICE_NAME CONFIG_BT_DEVICE_NAME +#define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1) +#define ADV_LEN 12 + +/* Advertising data */ +static uint8_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 *ble_conn; +/* Notification state */ +volatile bool notify_enable; + +static void mpu_ccc_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value) +{ + ARG_UNUSED(attr); + notify_enable = (value == BT_GATT_CCC_NOTIFY); + LOG_INF("Notification %s", notify_enable ? "enabled" : "disabled"); +} + +BT_GATT_SERVICE_DEFINE(stsensor_svc, +BT_GATT_PRIMARY_SERVICE(&st_service_uuid), +BT_GATT_CCC(mpu_ccc_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE), +); + +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, uint8_t err) +{ + if (err) { + LOG_ERR("Connection failed (err %u)", err); + } else { + LOG_INF("Connected"); + if (!ble_conn) { + ble_conn = bt_conn_ref(connected); + } + } +} + +static void disconnected(struct bt_conn *disconn, uint8_t reason) +{ + if (ble_conn) { + bt_conn_unref(ble_conn); + ble_conn = NULL; + } + + LOG_INF("Disconnected (reason %u)", reason); +} + +BT_CONN_CB_DEFINE(conn_callbacks) = { + .connected = connected, + .disconnected = disconnected, +}; + + +/* +Example: + +err = bt_enable(bt_ready); +if (err) { + LOG_ERR("Bluetooth init failed (err %d)", err); +} +*/ + +/* --------------------------- */ +/* End BLE */ +/* --------------------------- */ + diff --git a/snippets/bluetooth/base/config.txt b/snippets/bluetooth/base/config.txt new file mode 100644 index 0000000..dd73824 --- /dev/null +++ b/snippets/bluetooth/base/config.txt @@ -0,0 +1,6 @@ +CONFIG_BT=y +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_DEVICE_NAME="Zephyr" +CONFIG_BT_GATT_CLIENT=y +CONFIG_LOG=y +CONFIG_LOG_BUFFER_SIZE=2048 \ No newline at end of file diff --git a/snippets/bluetooth/button/button_svc.c b/snippets/bluetooth/button/button_svc.c new file mode 100644 index 0000000..2f1ff57 --- /dev/null +++ b/snippets/bluetooth/button/button_svc.c @@ -0,0 +1,54 @@ +/** @file + * @brief Button Service sample + */ + +/* + * Copyright (c) 2019 Marcio Montenegro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "button_svc.h" + +#include +#include + +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(button_svc); + +static const struct gpio_dt_spec button = GPIO_DT_SPEC_GET(DT_ALIAS(sw0), gpios); +static struct gpio_callback gpio_cb; + +int button_init(gpio_callback_handler_t handler) +{ + int ret; + + if (!gpio_is_ready_dt(&button)) { + LOG_ERR("Error: button GPIO device %s is not ready", + button.port->name); + return -ENODEV; + } + + ret = gpio_pin_configure_dt(&button, GPIO_INPUT); + if (ret != 0) { + LOG_ERR("Error %d: can't configure button on GPIO %s pin %d", + ret, button.port->name, button.pin); + return ret; + + } + + gpio_init_callback(&gpio_cb, handler, BIT(button.pin)); + gpio_add_callback(button.port, &gpio_cb); + ret = gpio_pin_interrupt_configure_dt(&button, GPIO_INT_EDGE_TO_ACTIVE); + if (ret != 0) { + LOG_ERR("Error %d: can't configure button interrupt on " + "GPIO %s pin %d", ret, button.port->name, button.pin); + return ret; + } + return 0; +} diff --git a/snippets/bluetooth/button/button_svc.h b/snippets/bluetooth/button/button_svc.h new file mode 100644 index 0000000..b3b6da9 --- /dev/null +++ b/snippets/bluetooth/button/button_svc.h @@ -0,0 +1,26 @@ +/** @file + * @brief Button Service + */ + +/* + * Copyright (c) 2019 Marcio Montenegro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ST_BLE_SENSOR_BUTTON_SVC_H_ +#define ST_BLE_SENSOR_BUTTON_SVC_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int button_init(gpio_callback_handler_t handler); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/snippets/bluetooth/button/code1.txt b/snippets/bluetooth/button/code1.txt new file mode 100644 index 0000000..1cbb75c --- /dev/null +++ b/snippets/bluetooth/button/code1.txt @@ -0,0 +1,21 @@ +static void button_callback(const struct device *gpiob, struct gpio_callback *cb, uint32_t pins) +{ + int err; + + LOG_INF("Button pressed"); + if (ble_conn) { + if (notify_enable) { + err = bt_gatt_notify(NULL, &stsensor_svc.attrs[4], &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"); + } +} diff --git a/snippets/bluetooth/button/code2.txt b/snippets/bluetooth/button/code2.txt new file mode 100644 index 0000000..846cc02 --- /dev/null +++ b/snippets/bluetooth/button/code2.txt @@ -0,0 +1,17 @@ + + +/* --------------------------- */ +/* Button */ +/* --------------------------- */ +/* +Example: + +err = button_init(button_callback); +if (err) { + return 0; +} +*/ +/* --------------------------- */ +/* Button LED */ +/* --------------------------- */ + diff --git a/snippets/bluetooth/led/code1.txt b/snippets/bluetooth/led/code1.txt new file mode 100644 index 0000000..32452a0 --- /dev/null +++ b/snippets/bluetooth/led/code1.txt @@ -0,0 +1,6 @@ +static ssize_t recv(struct bt_conn *conn, const struct bt_gatt_attr *attr, const void *buf, uint16_t len, uint16_t offset, uint8_t flags) +{ + led_update(); + + return 0; +} diff --git a/snippets/bluetooth/led/code2.txt b/snippets/bluetooth/led/code2.txt new file mode 100644 index 0000000..bd407f3 --- /dev/null +++ b/snippets/bluetooth/led/code2.txt @@ -0,0 +1,17 @@ + + +/* --------------------------- */ +/* LED */ +/* --------------------------- */ +/* +Example: + +err = led_init(); +if (err) { + return 0; +} +*/ +/* --------------------------- */ +/* End LED */ +/* --------------------------- */ + diff --git a/snippets/bluetooth/led/led_svc.c b/snippets/bluetooth/led/led_svc.c new file mode 100644 index 0000000..ea1aed3 --- /dev/null +++ b/snippets/bluetooth/led/led_svc.c @@ -0,0 +1,52 @@ +/** @file + * @brief Button Service sample + */ + +/* + * Copyright (c) 2019 Marcio Montenegro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "led_svc.h" + +#include +#include +#include + +LOG_MODULE_REGISTER(led_svc); + +static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(DT_ALIAS(led0), gpios); +static bool led_state; /* Tracking state here supports GPIO expander-based LEDs. */ +static bool led_ok; + +void led_update(void) +{ + if (!led_ok) { + return; + } + + led_state = !led_state; + LOG_INF("Turn %s LED", led_state ? "on" : "off"); + gpio_pin_set(led.port, led.pin, led_state); +} + +int led_init(void) +{ + int ret; + + led_ok = gpio_is_ready_dt(&led); + if (!led_ok) { + LOG_ERR("Error: LED on GPIO %s pin %d is not ready", + led.port->name, led.pin); + return -ENODEV; + } + + ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_INACTIVE); + if (ret < 0) { + LOG_ERR("Error %d: failed to configure GPIO %s pin %d", + ret, led.port->name, led.pin); + } + + return ret; +} diff --git a/snippets/bluetooth/led/led_svc.h b/snippets/bluetooth/led/led_svc.h new file mode 100644 index 0000000..90a7ec1 --- /dev/null +++ b/snippets/bluetooth/led/led_svc.h @@ -0,0 +1,25 @@ +/** @file + * @brief LED Service sample + */ + +/* + * Copyright (c) 2019 Marcio Montenegro + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ST_BLE_SENSOR_LED_SVC_H_ +#define ST_BLE_SENSOR_LED_SVC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +void led_update(void); +int led_init(void); + +#ifdef __cplusplus +} +#endif + +#endif