diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index d8b6046c..b527a61b 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -14,7 +14,7 @@ jobs: - "examples/arduino-bluefruit-bleuart" - "examples/arduino-nina-b1-generic-example" - "examples/arduino-serial-plotter" - - "examples/mbed-rtos-ble-thermometer" + - "examples/mbed-rtos-ble-battery" - "examples/mbed-rtos-blink-baremetal" - "examples/mbed-rtos-nfc" - "examples/zephyr-ble-beacon" diff --git a/examples/mbed-rtos-ble-thermometer/.gitignore b/examples/mbed-rtos-ble-battery/.gitignore similarity index 100% rename from examples/mbed-rtos-ble-thermometer/.gitignore rename to examples/mbed-rtos-ble-battery/.gitignore diff --git a/examples/mbed-rtos-ble-battery/.mbedignore b/examples/mbed-rtos-ble-battery/.mbedignore new file mode 100644 index 00000000..e15224c4 --- /dev/null +++ b/examples/mbed-rtos-ble-battery/.mbedignore @@ -0,0 +1,10 @@ +mbed-os/connectivity/cellular/* +mbed-os/connectivity/libraries/* +mbed-os/connectivity/drivers/* +mbed-os/connectivity/lorawan/* +mbed-os/connectivity/lwipstack/* +mbed-os/connectivity/mbedtls/* +mbed-os/connectivity/nanostack/* +mbed-os/connectivity/netsocket/* +mbed-os/features/* +mbed-os/storage/* diff --git a/examples/mbed-rtos-ble-thermometer/README.md b/examples/mbed-rtos-ble-battery/README.md similarity index 97% rename from examples/mbed-rtos-ble-thermometer/README.md rename to examples/mbed-rtos-ble-battery/README.md index bcdd2719..df5dab4c 100644 --- a/examples/mbed-rtos-ble-thermometer/README.md +++ b/examples/mbed-rtos-ble-battery/README.md @@ -8,7 +8,7 @@ How to build PlatformIO based project ```shell # Change directory to example -$ cd platform-nordicnrf52/examples/mbed-legacy-examples/mbed-rtos-ble-thermometer +$ cd platform-nordicnrf52/examples/mbed-legacy-examples/mbed-rtos-ble-battery # Build project $ pio run diff --git a/examples/mbed-rtos-ble-thermometer/include/README b/examples/mbed-rtos-ble-battery/include/README similarity index 100% rename from examples/mbed-rtos-ble-thermometer/include/README rename to examples/mbed-rtos-ble-battery/include/README diff --git a/examples/mbed-rtos-ble-thermometer/lib/README b/examples/mbed-rtos-ble-battery/lib/README similarity index 100% rename from examples/mbed-rtos-ble-thermometer/lib/README rename to examples/mbed-rtos-ble-battery/lib/README diff --git a/examples/mbed-rtos-ble-thermometer/mbed_app.json b/examples/mbed-rtos-ble-battery/mbed_app.json similarity index 63% rename from examples/mbed-rtos-ble-thermometer/mbed_app.json rename to examples/mbed-rtos-ble-battery/mbed_app.json index 205b8cd4..f81ce44c 100644 --- a/examples/mbed-rtos-ble-thermometer/mbed_app.json +++ b/examples/mbed-rtos-ble-battery/mbed_app.json @@ -1,5 +1,13 @@ { "target_overrides": { + "*": { + "platform.stdio-baud-rate": 115200, + "mbed-trace.enable": false, + "mbed-trace.max-level": "TRACE_LEVEL_DEBUG", + "cordio.trace-hci-packets": false, + "cordio.trace-cordio-wsf-traces": false, + "ble.trace-human-readable-enums": false + }, "K64F": { "target.components_add": ["BlueNRG_MS"], "target.features_add": ["BLE"], diff --git a/examples/mbed-rtos-ble-thermometer/platformio.ini b/examples/mbed-rtos-ble-battery/platformio.ini similarity index 100% rename from examples/mbed-rtos-ble-thermometer/platformio.ini rename to examples/mbed-rtos-ble-battery/platformio.ini diff --git a/examples/mbed-rtos-ble-battery/src/main.cpp b/examples/mbed-rtos-ble-battery/src/main.cpp new file mode 100644 index 00000000..ebab4116 --- /dev/null +++ b/examples/mbed-rtos-ble-battery/src/main.cpp @@ -0,0 +1,190 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2019 ARM Limited + * + * Licensed 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. + */ + +#include +#include "ble/BLE.h" +#include "ble/Gap.h" +#include "pretty_printer.h" +#include "mbed-trace/mbed_trace.h" + +const static char DEVICE_NAME[] = "BATTERY"; + +using namespace std::literals::chrono_literals; + +static events::EventQueue event_queue(/* event count */ 16 * EVENTS_EVENT_SIZE); + +class BatteryDemo : ble::Gap::EventHandler { +public: + BatteryDemo(BLE &ble, events::EventQueue &event_queue) : + _ble(ble), + _event_queue(event_queue), + _battery_level(50), + _adv_data_builder(_adv_buffer) + { + } + + void start() + { + /* mbed will call on_init_complete when when ble is ready */ + _ble.init(this, &BatteryDemo::on_init_complete); + + /* this will never return */ + _event_queue.dispatch_forever(); + } + +private: + /** Callback triggered when the ble initialization process has finished */ + void on_init_complete(BLE::InitializationCompleteCallbackContext *params) + { + if (params->error != BLE_ERROR_NONE) { + print_error(params->error, "Ble initialization failed."); + return; + } + + print_mac_address(); + + start_advertising(); + } + + void start_advertising() + { + /* create advertising parameters and payload */ + + ble::AdvertisingParameters adv_parameters( + /* you cannot connect to this device, you can only read its advertising data, + * scannable means that the device has extra advertising data that the peer can receive if it + * "scans" it which means it is using active scanning (it sends a scan request) */ + ble::advertising_type_t::SCANNABLE_UNDIRECTED, + ble::adv_interval_t(ble::millisecond_t(1000)) + ); + + /* when advertising you can optionally add extra data that is only sent + * if the central requests it by doing active scanning (sending scan requests), + * in this example we set this payload first because we want to later reuse + * the same _adv_data_builder builder for payload updates */ + + const uint8_t _vendor_specific_data[4] = { 0xAD, 0xDE, 0xBE, 0xEF }; + _adv_data_builder.setManufacturerSpecificData(_vendor_specific_data); + + _ble.gap().setAdvertisingScanResponse( + ble::LEGACY_ADVERTISING_HANDLE, + _adv_data_builder.getAdvertisingData() + ); + + /* now we set the advertising payload that gets sent during advertising without any scan requests */ + + _adv_data_builder.clear(); + _adv_data_builder.setFlags(); + _adv_data_builder.setName(DEVICE_NAME); + + /* we add the battery level as part of the payload so it's visible to any device that scans, + * this part of the payload will be updated periodically without affecting the rest of the payload */ + _adv_data_builder.setServiceData(GattService::UUID_BATTERY_SERVICE, {&_battery_level, 1}); + + /* setup advertising */ + + ble_error_t error = _ble.gap().setAdvertisingParameters( + ble::LEGACY_ADVERTISING_HANDLE, + adv_parameters + ); + + if (error) { + print_error(error, "_ble.gap().setAdvertisingParameters() failed"); + return; + } + + error = _ble.gap().setAdvertisingPayload( + ble::LEGACY_ADVERTISING_HANDLE, + _adv_data_builder.getAdvertisingData() + ); + + if (error) { + print_error(error, "_ble.gap().setAdvertisingPayload() failed"); + return; + } + + /* start advertising */ + + error = _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE); + + if (error) { + print_error(error, "_ble.gap().startAdvertising() failed"); + return; + } + + /* we simulate battery discharging by updating it every second */ + _event_queue.call_every( + 1000ms, + [this]() { + update_battery_level(); + } + ); + } + + void update_battery_level() + { + if (_battery_level-- == 10) { + _battery_level = 100; + } + + /* update the payload with the new value of the bettery level, the rest of the payload remains the same */ + ble_error_t error = _adv_data_builder.setServiceData(GattService::UUID_BATTERY_SERVICE, make_Span(&_battery_level, 1)); + + if (error) { + print_error(error, "_adv_data_builder.setServiceData() failed"); + return; + } + + /* set the new payload, we don't need to stop advertising */ + error = _ble.gap().setAdvertisingPayload( + ble::LEGACY_ADVERTISING_HANDLE, + _adv_data_builder.getAdvertisingData() + ); + + if (error) { + print_error(error, "_ble.gap().setAdvertisingPayload() failed"); + return; + } + } + +private: + BLE &_ble; + events::EventQueue &_event_queue; + + uint8_t _battery_level; + + uint8_t _adv_buffer[ble::LEGACY_ADVERTISING_MAX_SIZE]; + ble::AdvertisingDataBuilder _adv_data_builder; +}; + +/* Schedule processing of events from the BLE middleware in the event queue. */ +void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) +{ + event_queue.call(Callback(&context->ble, &BLE::processEvents)); +} + +int main() +{ + mbed_trace_init(); + + BLE &ble = BLE::Instance(); + ble.onEventsToProcess(schedule_ble_events); + + BatteryDemo demo(ble, event_queue); + demo.start(); + + return 0; +} diff --git a/examples/mbed-rtos-ble-thermometer/src/pretty_printer.h b/examples/mbed-rtos-ble-battery/src/pretty_printer.h similarity index 100% rename from examples/mbed-rtos-ble-thermometer/src/pretty_printer.h rename to examples/mbed-rtos-ble-battery/src/pretty_printer.h diff --git a/examples/mbed-rtos-ble-thermometer/test/README b/examples/mbed-rtos-ble-battery/test/README similarity index 100% rename from examples/mbed-rtos-ble-thermometer/test/README rename to examples/mbed-rtos-ble-battery/test/README diff --git a/examples/mbed-rtos-ble-thermometer/src/main.cpp b/examples/mbed-rtos-ble-thermometer/src/main.cpp deleted file mode 100644 index cecaafb5..00000000 --- a/examples/mbed-rtos-ble-thermometer/src/main.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed 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. - */ - -#include -#include "mbed.h" -#include "ble/BLE.h" -#include "ble/services/HealthThermometerService.h" -#include "pretty_printer.h" - -DigitalOut led1(LED1, 1); - -const static char DEVICE_NAME[] = "Therm"; - -static events::EventQueue event_queue(/* event count */ 16 * EVENTS_EVENT_SIZE); - -class ThermometerDemo : ble::Gap::EventHandler { -public: - ThermometerDemo(BLE &ble, events::EventQueue &event_queue) : - _ble(ble), - _event_queue(event_queue), - _sensor_event_id(0), - _thermometer_uuid(GattService::UUID_HEALTH_THERMOMETER_SERVICE), - _current_temperature(39.6f), - _thermometer_service(NULL), - _adv_data_builder(_adv_buffer) { } - - void start() { - _ble.gap().setEventHandler(this); - - _ble.init(this, &ThermometerDemo::on_init_complete); - - _event_queue.call_every(500, this, &ThermometerDemo::blink); - - _event_queue.dispatch_forever(); - } - -private: - /** Callback triggered when the ble initialization process has finished */ - void on_init_complete(BLE::InitializationCompleteCallbackContext *params) { - if (params->error != BLE_ERROR_NONE) { - print_error(params->error, "Ble initialization failed."); - return; - } - - print_mac_address(); - - /* Setup primary service. */ - _thermometer_service = new HealthThermometerService(_ble, _current_temperature, HealthThermometerService::LOCATION_EAR); - - start_advertising(); - } - - void start_advertising() { - /* Create advertising parameters and payload */ - - ble::AdvertisingParameters adv_parameters( - ble::advertising_type_t::CONNECTABLE_UNDIRECTED, - ble::adv_interval_t(ble::millisecond_t(1000)) - ); - - _adv_data_builder.setFlags(); - _adv_data_builder.setLocalServiceList(mbed::make_Span(&_thermometer_uuid, 1)); - _adv_data_builder.setAppearance(ble::adv_data_appearance_t::THERMOMETER_EAR); - _adv_data_builder.setName(DEVICE_NAME); - - /* Setup advertising */ - - ble_error_t error = _ble.gap().setAdvertisingParameters( - ble::LEGACY_ADVERTISING_HANDLE, - adv_parameters - ); - - if (error) { - print_error(error, "_ble.gap().setAdvertisingParameters() failed"); - return; - } - - error = _ble.gap().setAdvertisingPayload( - ble::LEGACY_ADVERTISING_HANDLE, - _adv_data_builder.getAdvertisingData() - ); - - if (error) { - print_error(error, "_ble.gap().setAdvertisingPayload() failed"); - return; - } - - /* Start advertising */ - - error = _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE); - - if (error) { - print_error(error, "_ble.gap().startAdvertising() failed"); - return; - } - } - - void update_sensor_value() { - _current_temperature = (_current_temperature + 0.1f > 43.0f) ? 39.6f : _current_temperature + 0.1f; - _thermometer_service->updateTemperature(_current_temperature); - } - - void blink(void) { - led1 = !led1; - } - -private: - /* Event handler */ - - virtual void onDisconnectionComplete(const ble::DisconnectionCompleteEvent&) { - _event_queue.cancel(_sensor_event_id); - _ble.gap().startAdvertising(ble::LEGACY_ADVERTISING_HANDLE); - } - - virtual void onConnectionComplete(const ble::ConnectionCompleteEvent &event) { - if (event.getStatus() == BLE_ERROR_NONE) { - _sensor_event_id = _event_queue.call_every(1000, this, &ThermometerDemo::update_sensor_value); - } - } - -private: - BLE &_ble; - events::EventQueue &_event_queue; - - int _sensor_event_id; - - UUID _thermometer_uuid; - - float _current_temperature; - HealthThermometerService *_thermometer_service; - - uint8_t _adv_buffer[ble::LEGACY_ADVERTISING_MAX_SIZE]; - ble::AdvertisingDataBuilder _adv_data_builder; -}; - -/** Schedule processing of events from the BLE middleware in the event queue. */ -void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *context) { - event_queue.call(Callback(&context->ble, &BLE::processEvents)); -} - -int main() -{ - BLE &ble = BLE::Instance(); - ble.onEventsToProcess(schedule_ble_events); - - ThermometerDemo demo(ble, event_queue); - demo.start(); - - return 0; -} diff --git a/examples/mbed-rtos-nfc/.mbedignore b/examples/mbed-rtos-nfc/.mbedignore new file mode 100644 index 00000000..23cfe7af --- /dev/null +++ b/examples/mbed-rtos-nfc/.mbedignore @@ -0,0 +1,10 @@ +mbed-os/connectivity/cellular/* +mbed-os/connectivity/FEATURE_BLE/* +mbed-os/connectivity/libraries/* +mbed-os/connectivity/lorawan/* +mbed-os/connectivity/lwipstack/* +mbed-os/connectivity/mbedtls/* +mbed-os/connectivity/nanostack/* +mbed-os/connectivity/netsocket/* +mbed-os/features/* +mbed-os/storage/* diff --git a/platform.json b/platform.json index 9bd15621..11e32494 100644 --- a/platform.json +++ b/platform.json @@ -18,7 +18,7 @@ "type": "git", "url": "https://github.com/platformio/platform-nordicnrf52.git" }, - "version": "10.0.0", + "version": "10.1.0", "frameworks": { "arduino": { "package": "framework-arduinonordicnrf5", @@ -47,7 +47,7 @@ "type": "framework", "optional": true, "owner": "platformio", - "version": "~6.60900.0" + "version": "~6.61700.0" }, "framework-arduinoadafruitnrf52": { "type": "framework",