From 038413f46f397f2cd4ce73bcd56cea352d1fcd3c Mon Sep 17 00:00:00 2001 From: Neil Hao Date: Tue, 28 May 2024 19:30:15 +0800 Subject: [PATCH 01/80] User experience improvement - app battery icon (#3979) * 'app_battery_icon' * Undo VS automatic modifications to this file * 'app_battery_icon_2' --- .vscode/extensions.json | 2 +- src/PowerStatus.h | 11 ++++++++++- variants/station-g2/variant.h | 2 ++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 783791f0b..4fc84fa78 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -6,4 +6,4 @@ "platformio.platformio-ide", "trunk.io" ], -} \ No newline at end of file +} diff --git a/src/PowerStatus.h b/src/PowerStatus.h index 56d19b758..592a03328 100644 --- a/src/PowerStatus.h +++ b/src/PowerStatus.h @@ -59,9 +59,18 @@ class PowerStatus : public Status int getBatteryVoltageMv() const { return batteryVoltageMv; } /** - * Note: 0% battery means 'unknown/this board doesn't have a battery installed' + * Note: for boards with battery pin or PMU, 0% battery means 'unknown/this board doesn't have a battery installed' */ +#if defined(HAS_PMU) || defined(BATTERY_PIN) uint8_t getBatteryChargePercent() const { return getHasBattery() ? batteryChargePercent : 0; } +#endif + + /** + * Note: for boards without battery pin and PMU, 101% battery means 'the board is using external power' + */ +#if !defined(HAS_PMU) && !defined(BATTERY_PIN) + uint8_t getBatteryChargePercent() const { return getHasBattery() ? batteryChargePercent : 101; } +#endif bool matches(const PowerStatus *newStatus) const { diff --git a/variants/station-g2/variant.h b/variants/station-g2/variant.h index f781ceb24..8f0b4b220 100755 --- a/variants/station-g2/variant.h +++ b/variants/station-g2/variant.h @@ -40,6 +40,7 @@ Board Information: https://wiki.uniteng.com/en/meshtastic/station-g2 #define SX126X_MAX_POWER 19 #endif +/* #define BATTERY_PIN 4 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage #define ADC_CHANNEL ADC1_GPIO4_CHANNEL #define ADC_MULTIPLIER 4 @@ -50,3 +51,4 @@ Board Information: https://wiki.uniteng.com/en/meshtastic/station-g2 #define BAT_NOBATVOLT 4460 #define CELL_TYPE_LION // same curve for liion/lipo #define NUM_CELLS 2 +*/ From af9d825266c7c6d937326f52c97585e8aee2853e Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 28 May 2024 19:25:19 -0500 Subject: [PATCH 02/80] Send own node-info earlier and move others to the end of want-config flow (#3949) * Send own node-info earlier and move others to the end of want-config flow * Special nonce skips other nodeinfos * Missed it --- src/mesh/PhoneAPI.cpp | 81 ++++++++++++++++++++++++++----------------- src/mesh/PhoneAPI.h | 14 ++++---- 2 files changed, 57 insertions(+), 38 deletions(-) diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp index 2a69d6d56..26d0d9525 100644 --- a/src/mesh/PhoneAPI.cpp +++ b/src/mesh/PhoneAPI.cpp @@ -140,16 +140,18 @@ bool PhoneAPI::handleToRadio(const uint8_t *buf, size_t bufLength) * * We assume buf is at least FromRadio_size bytes long. * - * Our sending states progress in the following sequence (the client app ASSUMES THIS SEQUENCE, DO NOT CHANGE IT): - * STATE_SEND_MY_INFO, // send our my info record - * STATE_SEND_CHANNELS - * STATE_SEND_NODEINFO, // states progress in this order as the device sends to the client - STATE_SEND_CONFIG, - STATE_SEND_MODULE_CONFIG, - STATE_SEND_METADATA, - STATE_SEND_COMPLETE_ID, - STATE_SEND_PACKETS // send packets or debug strings + * Our sending states progress in the following sequence (the client apps ASSUME THIS SEQUENCE, DO NOT CHANGE IT): + STATE_SEND_MY_INFO, // send our my info record + STATE_SEND_OWN_NODEINFO, + STATE_SEND_METADATA, + STATE_SEND_CHANNELS + STATE_SEND_CONFIG, + STATE_SEND_MODULE_CONFIG, + STATE_SEND_OTHER_NODEINFOS, // states progress in this order as the device sends to the client + STATE_SEND_COMPLETE_ID, + STATE_SEND_PACKETS // send packets or debug strings */ + size_t PhoneAPI::getFromRadio(uint8_t *buf) { if (!available()) { @@ -171,37 +173,32 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf) // app not to send locations on our behalf. fromRadioScratch.which_payload_variant = meshtastic_FromRadio_my_info_tag; fromRadioScratch.my_info = myNodeInfo; - state = STATE_SEND_METADATA; + state = STATE_SEND_OWN_NODEINFO; service.refreshLocalMeshNode(); // Update my NodeInfo because the client will be asking for it soon. break; + case STATE_SEND_OWN_NODEINFO: { + LOG_INFO("getFromRadio=STATE_SEND_OWN_NODEINFO\n"); + auto us = nodeDB->readNextMeshNode(readIndex); + if (us) { + nodeInfoForPhone = TypeConversions::ConvertToNodeInfo(us); + fromRadioScratch.which_payload_variant = meshtastic_FromRadio_node_info_tag; + fromRadioScratch.node_info = nodeInfoForPhone; + // Should allow us to resume sending NodeInfo in STATE_SEND_OTHER_NODEINFOS + nodeInfoForPhone.num = 0; + } + state = STATE_SEND_METADATA; + break; + } + case STATE_SEND_METADATA: LOG_INFO("getFromRadio=STATE_SEND_METADATA\n"); fromRadioScratch.which_payload_variant = meshtastic_FromRadio_metadata_tag; fromRadioScratch.metadata = getDeviceMetadata(); - state = STATE_SEND_NODEINFO; + state = STATE_SEND_CHANNELS; break; - case STATE_SEND_NODEINFO: { - LOG_INFO("getFromRadio=STATE_SEND_NODEINFO\n"); - - if (nodeInfoForPhone.num != 0) { - LOG_INFO("nodeinfo: num=0x%x, lastseen=%u, id=%s, name=%s\n", nodeInfoForPhone.num, nodeInfoForPhone.last_heard, - nodeInfoForPhone.user.id, nodeInfoForPhone.user.long_name); - fromRadioScratch.which_payload_variant = meshtastic_FromRadio_node_info_tag; - fromRadioScratch.node_info = nodeInfoForPhone; - // Stay in current state until done sending nodeinfos - nodeInfoForPhone.num = 0; // We just consumed a nodeinfo, will need a new one next time - } else { - LOG_INFO("Done sending nodeinfos\n"); - state = STATE_SEND_CHANNELS; - // Go ahead and send that ID right now - return getFromRadio(buf); - } - break; - } - case STATE_SEND_CHANNELS: LOG_INFO("getFromRadio=STATE_SEND_CHANNELS\n"); fromRadioScratch.which_payload_variant = meshtastic_FromRadio_channel_tag; @@ -325,11 +322,30 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf) config_state++; // Advance when we have sent all of our ModuleConfig objects if (config_state > (_meshtastic_AdminMessage_ModuleConfigType_MAX + 1)) { - state = STATE_SEND_COMPLETE_ID; + // Clients sending special nonce don't want to see other nodeinfos + state = config_nonce == SPECIAL_NONCE ? STATE_SEND_COMPLETE_ID : STATE_SEND_OTHER_NODEINFOS; config_state = 0; } break; + case STATE_SEND_OTHER_NODEINFOS: { + LOG_INFO("getFromRadio=STATE_SEND_OTHER_NODEINFOS\n"); + if (nodeInfoForPhone.num != 0) { + LOG_INFO("nodeinfo: num=0x%x, lastseen=%u, id=%s, name=%s\n", nodeInfoForPhone.num, nodeInfoForPhone.last_heard, + nodeInfoForPhone.user.id, nodeInfoForPhone.user.long_name); + fromRadioScratch.which_payload_variant = meshtastic_FromRadio_node_info_tag; + fromRadioScratch.node_info = nodeInfoForPhone; + // Stay in current state until done sending nodeinfos + nodeInfoForPhone.num = 0; // We just consumed a nodeinfo, will need a new one next time + } else { + LOG_INFO("Done sending nodeinfos\n"); + state = STATE_SEND_COMPLETE_ID; + // Go ahead and send that ID right now + return getFromRadio(buf); + } + break; + } + case STATE_SEND_COMPLETE_ID: LOG_INFO("getFromRadio=STATE_SEND_COMPLETE_ID\n"); fromRadioScratch.which_payload_variant = meshtastic_FromRadio_config_complete_id_tag; @@ -422,10 +438,11 @@ bool PhoneAPI::available() case STATE_SEND_CONFIG: case STATE_SEND_MODULECONFIG: case STATE_SEND_METADATA: + case STATE_SEND_OWN_NODEINFO: case STATE_SEND_COMPLETE_ID: return true; - case STATE_SEND_NODEINFO: + case STATE_SEND_OTHER_NODEINFOS: if (nodeInfoForPhone.num == 0) { auto nextNode = nodeDB->readNextMeshNode(readIndex); if (nextNode) { diff --git a/src/mesh/PhoneAPI.h b/src/mesh/PhoneAPI.h index 450649d7b..49bf0e292 100644 --- a/src/mesh/PhoneAPI.h +++ b/src/mesh/PhoneAPI.h @@ -6,6 +6,7 @@ // Make sure that we never let our packets grow too large for one BLE packet #define MAX_TO_FROM_RADIO_SIZE 512 +#define SPECIAL_NONCE 69420 /** * Provides our protobuf based API which phone/PC clients can use to talk to our device @@ -20,13 +21,14 @@ class PhoneAPI : public Observer // FIXME, we shouldn't be inheriting from Observer, instead use CallbackObserver as a member { enum State { - STATE_SEND_NOTHING, // Initial state, don't send anything until the client starts asking for config - STATE_SEND_MY_INFO, // send our my info record - STATE_SEND_NODEINFO, // states progress in this order as the device sends to to the client - STATE_SEND_CHANNELS, // Send all channels - STATE_SEND_CONFIG, // Replacement for the old Radioconfig - STATE_SEND_MODULECONFIG, // Send Module specific config + STATE_SEND_NOTHING, // Initial state, don't send anything until the client starts asking for config + STATE_SEND_MY_INFO, // send our my info record + STATE_SEND_OWN_NODEINFO, STATE_SEND_METADATA, + STATE_SEND_CHANNELS, // Send all channels + STATE_SEND_CONFIG, // Replacement for the old Radioconfig + STATE_SEND_MODULECONFIG, // Send Module specific config + STATE_SEND_OTHER_NODEINFOS, // states progress in this order as the device sends to to the client STATE_SEND_COMPLETE_ID, STATE_SEND_PACKETS // send packets or debug strings }; From 0b48663cbcfb964ee8803f930e8152482a492d98 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Thu, 30 May 2024 08:49:01 -0500 Subject: [PATCH 03/80] Don't alloc NodeInfo replies when channel utilization is > 40% (#3991) * Don't alloc NodeInfo replies when channel utilization is > 40% * Commit * Logs --- src/modules/NodeInfoModule.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/modules/NodeInfoModule.cpp b/src/modules/NodeInfoModule.cpp index f77026708..78af7099a 100644 --- a/src/modules/NodeInfoModule.cpp +++ b/src/modules/NodeInfoModule.cpp @@ -58,10 +58,15 @@ void NodeInfoModule::sendOurNodeInfo(NodeNum dest, bool wantReplies, uint8_t cha meshtastic_MeshPacket *NodeInfoModule::allocReply() { + if (!airTime->isTxAllowedChannelUtil(false)) { + ignoreRequest = true; // Mark it as ignored for MeshModule + LOG_DEBUG("Skip sending NodeInfo due to > 40 percent channel util.\n"); + return NULL; + } uint32_t now = millis(); // If we sent our NodeInfo less than 5 min. ago, don't send it again as it may be still underway. if (lastSentToMesh && (now - lastSentToMesh) < (5 * 60 * 1000)) { - LOG_DEBUG("Sending NodeInfo will be ignored since we just sent it.\n"); + LOG_DEBUG("Skip sending NodeInfo since we just sent it less than 5 minutes ago.\n"); ignoreRequest = true; // Mark it as ignored for MeshModule return NULL; } else { From cd8a7e44a8cac6dac8c7d8ed0b6f993edc109ad6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 30 May 2024 09:08:32 -0500 Subject: [PATCH 04/80] [create-pull-request] automated change (#3992) Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com> --- protobufs | 2 +- src/mesh/generated/meshtastic/atak.pb.h | 15 ++++++++++----- src/mesh/generated/meshtastic/mesh.pb.h | 3 +++ 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/protobufs b/protobufs index b5dc871a1..9e61b8233 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit b5dc871a1bfa2cc932126a4f490d9ef078476e4c +Subproject commit 9e61b8233181715363aba2aa6c91e85a2d61fc73 diff --git a/src/mesh/generated/meshtastic/atak.pb.h b/src/mesh/generated/meshtastic/atak.pb.h index c094727ed..5fd18f963 100644 --- a/src/mesh/generated/meshtastic/atak.pb.h +++ b/src/mesh/generated/meshtastic/atak.pb.h @@ -73,6 +73,9 @@ typedef struct _meshtastic_GeoChat { /* Uid recipient of the message */ bool has_to; char to[120]; + /* Callsign of the recipient for the message */ + bool has_to_callsign; + char to_callsign[120]; } meshtastic_GeoChat; /* ATAK Group @@ -164,13 +167,13 @@ extern "C" { /* Initializer values for message structs */ #define meshtastic_TAKPacket_init_default {0, false, meshtastic_Contact_init_default, false, meshtastic_Group_init_default, false, meshtastic_Status_init_default, 0, {meshtastic_PLI_init_default}} -#define meshtastic_GeoChat_init_default {"", false, ""} +#define meshtastic_GeoChat_init_default {"", false, "", false, ""} #define meshtastic_Group_init_default {_meshtastic_MemberRole_MIN, _meshtastic_Team_MIN} #define meshtastic_Status_init_default {0} #define meshtastic_Contact_init_default {"", ""} #define meshtastic_PLI_init_default {0, 0, 0, 0, 0} #define meshtastic_TAKPacket_init_zero {0, false, meshtastic_Contact_init_zero, false, meshtastic_Group_init_zero, false, meshtastic_Status_init_zero, 0, {meshtastic_PLI_init_zero}} -#define meshtastic_GeoChat_init_zero {"", false, ""} +#define meshtastic_GeoChat_init_zero {"", false, "", false, ""} #define meshtastic_Group_init_zero {_meshtastic_MemberRole_MIN, _meshtastic_Team_MIN} #define meshtastic_Status_init_zero {0} #define meshtastic_Contact_init_zero {"", ""} @@ -179,6 +182,7 @@ extern "C" { /* Field tags (for use in manual encoding/decoding) */ #define meshtastic_GeoChat_message_tag 1 #define meshtastic_GeoChat_to_tag 2 +#define meshtastic_GeoChat_to_callsign_tag 3 #define meshtastic_Group_role_tag 1 #define meshtastic_Group_team_tag 2 #define meshtastic_Status_battery_tag 1 @@ -214,7 +218,8 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,chat,payload_variant.chat), #define meshtastic_GeoChat_FIELDLIST(X, a) \ X(a, STATIC, SINGULAR, STRING, message, 1) \ -X(a, STATIC, OPTIONAL, STRING, to, 2) +X(a, STATIC, OPTIONAL, STRING, to, 2) \ +X(a, STATIC, OPTIONAL, STRING, to_callsign, 3) #define meshtastic_GeoChat_CALLBACK NULL #define meshtastic_GeoChat_DEFAULT NULL @@ -262,11 +267,11 @@ extern const pb_msgdesc_t meshtastic_PLI_msg; /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_ATAK_PB_H_MAX_SIZE meshtastic_TAKPacket_size #define meshtastic_Contact_size 242 -#define meshtastic_GeoChat_size 323 +#define meshtastic_GeoChat_size 444 #define meshtastic_Group_size 4 #define meshtastic_PLI_size 31 #define meshtastic_Status_size 3 -#define meshtastic_TAKPacket_size 584 +#define meshtastic_TAKPacket_size 705 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h index ffc18c30b..7b544d714 100644 --- a/src/mesh/generated/meshtastic/mesh.pb.h +++ b/src/mesh/generated/meshtastic/mesh.pb.h @@ -156,6 +156,9 @@ typedef enum _meshtastic_HardwareModel { /* NRF52_PROMICRO_DIY Promicro NRF52840 with SX1262/LLCC68, SSD1306 OLED and NEO6M GPS */ meshtastic_HardwareModel_NRF52_PROMICRO_DIY = 63, + /* RadioMaster 900 Bandit Nano, https://www.radiomasterrc.com/products/bandit-nano-expresslrs-rf-module + ESP32-D0WDQ6 With SX1276/SKY66122, SSD1306 OLED and No GPS */ + meshtastic_HardwareModel_RADIOMASTER_900_BANDIT_NANO = 64, /* ------------------------------------------------------------------------------------------------------------------------------------------ Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits. ------------------------------------------------------------------------------------------------------------------------------------------ */ From f138eaa970339250dfff1b5608ce1463253312f9 Mon Sep 17 00:00:00 2001 From: Mike Date: Thu, 30 May 2024 18:59:10 +0300 Subject: [PATCH 05/80] Fix original esp32 boot init panic (#3985) Co-authored-by: Ben Meadors --- arch/esp32/esp32.ini | 1 + arch/esp32/esp32c3.ini | 1 + arch/esp32/esp32s2.ini | 1 + arch/esp32/esp32s3.ini | 1 + bin/platformio-custom.py | 16 +++++++++++++++- src/platform/esp32/iram-quirk.c | 23 +++++++++++++++++++++++ 6 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 src/platform/esp32/iram-quirk.c diff --git a/arch/esp32/esp32.ini b/arch/esp32/esp32.ini index 7e55f0934..f3eb0cbc0 100644 --- a/arch/esp32/esp32.ini +++ b/arch/esp32/esp32.ini @@ -1,6 +1,7 @@ ; Common settings for ESP targes, mixin with extends = esp32_base [esp32_base] extends = arduino_base +custom_esp32_kind = esp32 platform = platformio/espressif32@6.7.0 build_src_filter = diff --git a/arch/esp32/esp32c3.ini b/arch/esp32/esp32c3.ini index 619fdb28a..2ba3036d0 100644 --- a/arch/esp32/esp32c3.ini +++ b/arch/esp32/esp32c3.ini @@ -1,5 +1,6 @@ [esp32c3_base] extends = esp32_base +custom_esp32_kind = esp32c3 monitor_speed = 115200 monitor_filters = esp32_c3_exception_decoder diff --git a/arch/esp32/esp32s2.ini b/arch/esp32/esp32s2.ini index df66de2ed..40fdc461a 100644 --- a/arch/esp32/esp32s2.ini +++ b/arch/esp32/esp32s2.ini @@ -1,5 +1,6 @@ [esp32s2_base] extends = esp32_base +custom_esp32_kind = esp32s2 build_src_filter = ${esp32_base.build_src_filter} - - - diff --git a/arch/esp32/esp32s3.ini b/arch/esp32/esp32s3.ini index 6a1bdd3fd..1cd0e2033 100644 --- a/arch/esp32/esp32s3.ini +++ b/arch/esp32/esp32s3.ini @@ -1,5 +1,6 @@ [esp32s3_base] extends = esp32_base +custom_esp32_kind = esp32s3 monitor_speed = 115200 diff --git a/bin/platformio-custom.py b/bin/platformio-custom.py index 3382ff891..3202a1e7a 100644 --- a/bin/platformio-custom.py +++ b/bin/platformio-custom.py @@ -62,7 +62,21 @@ if platform.name == "espressif32": import esptool env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", esp32_create_combined_bin) - env.Append(LINKFLAGS=["--specs=nano.specs", "-u", "_printf_float"]) + + esp32_kind = env.GetProjectOption("custom_esp32_kind") + if esp32_kind == "esp32": + # Free up some IRAM by removing auxiliary SPI flash chip drivers. + # Wrapped stub symbols are defined in src/platform/esp32/iram-quirk.c. + env.Append( + LINKFLAGS=[ + "-Wl,--wrap=esp_flash_chip_gd", + "-Wl,--wrap=esp_flash_chip_issi", + "-Wl,--wrap=esp_flash_chip_winbond", + ] + ) + else: + # For newer ESP32 targets, using newlib nano works better. + env.Append(LINKFLAGS=["--specs=nano.specs", "-u", "_printf_float"]) Import("projenv") diff --git a/src/platform/esp32/iram-quirk.c b/src/platform/esp32/iram-quirk.c new file mode 100644 index 000000000..813842138 --- /dev/null +++ b/src/platform/esp32/iram-quirk.c @@ -0,0 +1,23 @@ +// Free up some precious space in the iram0_0_seg memory segment + +#include + +#include +#include +#include + +#define IRAM_SECTION section(".iram1.stub") + +IRAM_ATTR esp_err_t stub_probe(esp_flash_t *chip, uint32_t flash_id) +{ + return ESP_ERR_NOT_FOUND; +} + +const spi_flash_chip_t stub_flash_chip __attribute__((IRAM_SECTION)) = { + .name = "stub", + .probe = stub_probe, +}; + +extern const spi_flash_chip_t __wrap_esp_flash_chip_gd __attribute__((IRAM_SECTION, alias("stub_flash_chip"))); +extern const spi_flash_chip_t __wrap_esp_flash_chip_issi __attribute__((IRAM_SECTION, alias("stub_flash_chip"))); +extern const spi_flash_chip_t __wrap_esp_flash_chip_winbond __attribute__((IRAM_SECTION, alias("stub_flash_chip"))); From 10e3040494bc50abce8c32f96aee2e2a71d3479b Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Thu, 30 May 2024 18:49:08 -0500 Subject: [PATCH 06/80] Add support for to_callsign on GeoChats for ATAK (#3996) --- src/modules/AtakPluginModule.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/modules/AtakPluginModule.cpp b/src/modules/AtakPluginModule.cpp index b460602ef..59263415c 100644 --- a/src/modules/AtakPluginModule.cpp +++ b/src/modules/AtakPluginModule.cpp @@ -87,6 +87,14 @@ void AtakPluginModule::alterReceivedProtobuf(meshtastic_MeshPacket &mp, meshtast compressed.payload_variant.chat.to); LOG_DEBUG("Compressed chat to: %d bytes\n", length); } + + if (t->payload_variant.chat.has_to_callsign) { + compressed.payload_variant.chat.has_to_callsign = true; + length = + unishox2_compress_simple(t->payload_variant.chat.to_callsign, strlen(t->payload_variant.chat.to_callsign), + compressed.payload_variant.chat.to_callsign); + LOG_DEBUG("Compressed chat to_callsign: %d bytes\n", length); + } } mp.decoded.payload.size = pb_encode_to_bytes(mp.decoded.payload.bytes, sizeof(mp.decoded.payload.bytes), meshtastic_TAKPacket_fields, &compressed); @@ -124,6 +132,14 @@ void AtakPluginModule::alterReceivedProtobuf(meshtastic_MeshPacket &mp, meshtast uncompressed.payload_variant.chat.to); LOG_DEBUG("Decompressed chat to: %d bytes\n", length); } + + if (t->payload_variant.chat.has_to_callsign) { + uncompressed.payload_variant.chat.has_to_callsign = true; + length = + unishox2_decompress_simple(t->payload_variant.chat.to_callsign, strlen(t->payload_variant.chat.to_callsign), + uncompressed.payload_variant.chat.to_callsign); + LOG_DEBUG("Decompressed chat to_callsign: %d bytes\n", length); + } } decompressedCopy->decoded.payload.size = pb_encode_to_bytes(decompressedCopy->decoded.payload.bytes, sizeof(decompressedCopy->decoded.payload), From 8d90c496d0b8793354fb3f04ee0f634e8bfa000b Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Fri, 31 May 2024 07:14:33 -0500 Subject: [PATCH 07/80] Don't send potentially bogus timestamps with fixed location (#4001) --- src/modules/PositionModule.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modules/PositionModule.cpp b/src/modules/PositionModule.cpp index f3a70f4c5..002111171 100644 --- a/src/modules/PositionModule.cpp +++ b/src/modules/PositionModule.cpp @@ -211,11 +211,11 @@ meshtastic_MeshPacket *PositionModule::allocReply() // Strip out any time information before sending packets to other nodes - to keep the wire size small (and because other // nodes shouldn't trust it anyways) Note: we allow a device with a local GPS to include the time, so that gpsless // devices can get time. - if (getRTCQuality() < RTCQualityDevice) { + if (getRTCQuality() < RTCQualityGPS) { LOG_INFO("Stripping time %u from position send\n", p.time); p.time = 0; } else { - p.time = getValidTime(RTCQualityDevice); + p.time = getValidTime(RTCQualityGPS); LOG_INFO("Providing time to mesh %u\n", p.time); } @@ -454,4 +454,4 @@ void PositionModule::handleNewPosition() } } -#endif \ No newline at end of file +#endif From 54bccb898e4b8a1f4bdcb3670a94869ff5b9c4fb Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Fri, 31 May 2024 07:15:16 -0500 Subject: [PATCH 08/80] Run tzset() and localtime() in getTZOffset() to ensure proper timezone offset (#3999) * Run tzset() and localtime() in getTZOffset() to ensure proper timezone offset * Try #2 to fix timezone/DST --- src/gps/RTC.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/gps/RTC.cpp b/src/gps/RTC.cpp index 864b246a3..d60e3825c 100644 --- a/src/gps/RTC.cpp +++ b/src/gps/RTC.cpp @@ -222,9 +222,8 @@ bool perhapsSetRTC(RTCQuality q, struct tm &t) */ int32_t getTZOffset() { - time_t now; + time_t now = getTime(false); struct tm *gmt; - now = time(NULL); gmt = gmtime(&now); gmt->tm_isdst = -1; return (int32_t)difftime(now, mktime(gmt)); @@ -265,4 +264,4 @@ time_t gm_mktime(struct tm *tm) setenv("TZ", "UTC0", 1); } return res; -} +} \ No newline at end of file From c88278724cfaae38e1876880539b6a9b4cb6146d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 31 May 2024 07:15:41 -0500 Subject: [PATCH 09/80] [create-pull-request] automated change (#4003) Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com> --- protobufs | 2 +- src/mesh/generated/meshtastic/telemetry.pb.h | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/protobufs b/protobufs index 9e61b8233..a45a6154d 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 9e61b8233181715363aba2aa6c91e85a2d61fc73 +Subproject commit a45a6154d0721027bf63f85cfc5abd9f6fab2422 diff --git a/src/mesh/generated/meshtastic/telemetry.pb.h b/src/mesh/generated/meshtastic/telemetry.pb.h index 7748dd6b3..f0ff9bed0 100644 --- a/src/mesh/generated/meshtastic/telemetry.pb.h +++ b/src/mesh/generated/meshtastic/telemetry.pb.h @@ -57,7 +57,9 @@ typedef enum _meshtastic_TelemetrySensorType { /* Lite On LTR-390UV-01 UV Light Sensor */ meshtastic_TelemetrySensorType_LTR390UV = 21, /* AMS TSL25911FN RGB Light Sensor */ - meshtastic_TelemetrySensorType_TSL25911FN = 22 + meshtastic_TelemetrySensorType_TSL25911FN = 22, + /* AHT10 Integrated temperature and humidity sensor */ + meshtastic_TelemetrySensorType_AHT10 = 23 } meshtastic_TelemetrySensorType; /* Struct definitions */ @@ -168,8 +170,8 @@ extern "C" { /* Helper constants for enums */ #define _meshtastic_TelemetrySensorType_MIN meshtastic_TelemetrySensorType_SENSOR_UNSET -#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_TSL25911FN -#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_TSL25911FN+1)) +#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_AHT10 +#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_AHT10+1)) From b9edc7563b55fb6c9fff8a0ae00e1539f5bf803d Mon Sep 17 00:00:00 2001 From: "Aaron.Lee" <32860565+Heltec-Aaron-Lee@users.noreply.github.com> Date: Fri, 31 May 2024 23:55:05 +0800 Subject: [PATCH 10/80] Update the Heltec board battery level read accuracy. (#3955) * Update variant.h Update the Heltec board battery voltage read parameter. * Update variant.h Update the Heltec board battery voltage read parameter. * Update variant.h Update the Heltec board battery voltage read parameter. * Update variant.h Update the Heltec board battery voltage read parameter. --- variants/heltec_v3/variant.h | 2 +- variants/heltec_wireless_tracker/variant.h | 2 +- variants/heltec_wireless_tracker_V1_0/variant.h | 2 +- variants/heltec_wsl_v3/variant.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/variants/heltec_v3/variant.h b/variants/heltec_v3/variant.h index 70b122f58..0c22ea1a7 100644 --- a/variants/heltec_v3/variant.h +++ b/variants/heltec_v3/variant.h @@ -16,7 +16,7 @@ #define BATTERY_PIN 1 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage #define ADC_CHANNEL ADC1_GPIO1_CHANNEL #define ADC_ATTENUATION ADC_ATTEN_DB_2_5 // lower dB for high resistance voltage divider -#define ADC_MULTIPLIER 4.9 +#define ADC_MULTIPLIER 4.9*1.045 #define USE_SX1262 diff --git a/variants/heltec_wireless_tracker/variant.h b/variants/heltec_wireless_tracker/variant.h index 167345e1a..0f632a33c 100644 --- a/variants/heltec_wireless_tracker/variant.h +++ b/variants/heltec_wireless_tracker/variant.h @@ -33,7 +33,7 @@ #define BATTERY_PIN 1 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage #define ADC_CHANNEL ADC1_GPIO1_CHANNEL #define ADC_ATTENUATION ADC_ATTEN_DB_2_5 // lower dB for high resistance voltage divider -#define ADC_MULTIPLIER 4.9 +#define ADC_MULTIPLIER 4.9*1.045 #define ADC_CTRL 2 // active HIGH, powers the voltage divider. Only on 1.1 #define ADC_CTRL_ENABLED HIGH diff --git a/variants/heltec_wireless_tracker_V1_0/variant.h b/variants/heltec_wireless_tracker_V1_0/variant.h index 84e77a6b9..2b521f249 100644 --- a/variants/heltec_wireless_tracker_V1_0/variant.h +++ b/variants/heltec_wireless_tracker_V1_0/variant.h @@ -34,7 +34,7 @@ #define BATTERY_PIN 1 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage #define ADC_CHANNEL ADC1_GPIO1_CHANNEL #define ADC_ATTENUATION ADC_ATTEN_DB_2_5 // lower dB for high resistance voltage divider -#define ADC_MULTIPLIER 4.9 +#define ADC_MULTIPLIER 4.9*1.045 #undef GPS_RX_PIN #undef GPS_TX_PIN diff --git a/variants/heltec_wsl_v3/variant.h b/variants/heltec_wsl_v3/variant.h index 917ea7fb9..37cef09c6 100644 --- a/variants/heltec_wsl_v3/variant.h +++ b/variants/heltec_wsl_v3/variant.h @@ -11,7 +11,7 @@ #define BATTERY_PIN 1 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage #define ADC_CHANNEL ADC1_GPIO1_CHANNEL #define ADC_ATTENUATION ADC_ATTEN_DB_2_5 // lower dB for high resistance voltage divider -#define ADC_MULTIPLIER 4.9 +#define ADC_MULTIPLIER 4.9*1.045 #define USE_SX1262 From 953aa4d0915f8652b14e7734acc1e1f2ac5210fa Mon Sep 17 00:00:00 2001 From: jonagnew Date: Fri, 31 May 2024 11:55:20 -0400 Subject: [PATCH 11/80] Tracker v1.1 - fix pin 3 description in variant.h (#3990) Schematic shows the following: Pin 3 is Vext on v1.1 - HIGH enables LDO for Vext rail which goes to: GPS UC6580: GPS V_DET(8), VDD_IO(7), DCDC_IN(21), pulls up RESETN(17), D_SEL(33) and BOOT_MODE(34) through 10kR GPS LNA SW7125DE: VCC(4), pulls up SHDN(5) through 10kR OLED: VDD, LEDA (through diode) Co-authored-by: Ben Meadors --- variants/heltec_wireless_tracker/variant.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/variants/heltec_wireless_tracker/variant.h b/variants/heltec_wireless_tracker/variant.h index 0f632a33c..d496a8d6f 100644 --- a/variants/heltec_wireless_tracker/variant.h +++ b/variants/heltec_wireless_tracker/variant.h @@ -27,7 +27,11 @@ #define SCREEN_TRANSITION_FRAMERATE 3 // fps #define DISPLAY_FORCE_SMALL_FONTS -#define VEXT_ENABLE_V05 3 // active HIGH, powers the lora antenna boost + // pin 3 is Vext on v1.1 - HIGH enables LDO for Vext rail which goes to: + // GPS UC6580: GPS V_DET(8), VDD_IO(7), DCDC_IN(21), pulls up RESETN(17), D_SEL(33) and BOOT_MODE(34) through 10kR + // GPS LNA SW7125DE: VCC(4), pulls up SHDN(5) through 10kR + // LED: VDD, LEDA (through diode) +#define VEXT_ENABLE_V05 3 // active HIGH - powers the GPS, GPS LNA and OLED VDD/anode #define BUTTON_PIN 0 #define BATTERY_PIN 1 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage @@ -43,6 +47,7 @@ #define GPS_TX_PIN 34 #define PIN_GPS_RESET 35 #define PIN_GPS_PPS 36 +// #define PIN_GPS_EN 3 // Uncomment to power off the GPS with triple-click on Tracker v1.1, though we'll also lose the display. #define GPS_RESET_MODE LOW #define GPS_UC6580 From 17142f87782ad9bff0bc66e9b4937018adfb3bb1 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Fri, 31 May 2024 10:56:04 -0500 Subject: [PATCH 12/80] Add support for RadioMaster Bandit Nano (#4005) * Add support for RadioMaster Bandit Nano * Add fan to init and sleep --- src/mesh/NodeDB.cpp | 3 + src/mesh/RF95Interface.cpp | 33 ++++++-- src/mesh/RadioLibRF95.cpp | 4 + src/platform/esp32/architecture.h | 2 + .../platformio.ini | 15 ++++ .../radiomaster_900_bandit_nano/variant.h | 84 +++++++++++++++++++ 6 files changed, 136 insertions(+), 5 deletions(-) create mode 100644 variants/radiomaster_900_bandit_nano/platformio.ini create mode 100644 variants/radiomaster_900_bandit_nano/variant.h diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index b79911a3e..9473df8c5 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -292,6 +292,9 @@ void NodeDB::installDefaultConfig() meshtastic_Config_PositionConfig_PositionFlags_SPEED | meshtastic_Config_PositionConfig_PositionFlags_HEADING | meshtastic_Config_PositionConfig_PositionFlags_DOP | meshtastic_Config_PositionConfig_PositionFlags_SATINVIEW); +#ifdef RADIOMASTER_900_BANDIT_NANO + config.display.flip_screen = true; +#endif #ifdef T_WATCH_S3 config.display.screen_on_secs = 30; config.display.wake_on_tap_or_motion = true; diff --git a/src/mesh/RF95Interface.cpp b/src/mesh/RF95Interface.cpp index 8c6c349fd..5677e6eda 100644 --- a/src/mesh/RF95Interface.cpp +++ b/src/mesh/RF95Interface.cpp @@ -8,7 +8,10 @@ #include "PortduinoGlue.h" #endif -#define MAX_POWER 20 +#ifndef RF95_MAX_POWER +#define RF95_MAX_POWER 20 +#endif + // if we use 20 we are limited to 1% duty cycle or hw might overheat. For continuous operation set a limit of 17 // In theory up to 27 dBm is possible, but the modules installed in most radios can cope with a max of 20. So BIG WARNING // if you set power to something higher than 17 or 20 you might fry your board. @@ -49,8 +52,8 @@ bool RF95Interface::init() { RadioLibInterface::init(); - if (power > MAX_POWER) // This chip has lower power limits than some - power = MAX_POWER; + if (power > RF95_MAX_POWER) // This chip has lower power limits than some + power = RF95_MAX_POWER; limitPower(); @@ -61,6 +64,13 @@ bool RF95Interface::init() digitalWrite(RF95_TCXO, 1); #endif + // enable PA +#ifdef RF95_PA_EN +#if defined(RF95_PA_DAC_EN) + dacWrite(RF95_PA_EN, RF95_PA_LEVEL); +#endif +#endif + /* #define RF95_TXEN (22) // If defined, this pin should be set high prior to transmit (controls an external analog switch) #define RF95_RXEN (23) // If defined, this pin should be set high prior to receive (controls an external analog switch) @@ -71,6 +81,11 @@ bool RF95Interface::init() digitalWrite(RF95_TXEN, 0); #endif +#ifdef RF95_FAN_EN + pinMode(RF95_FAN_EN, OUTPUT); + digitalWrite(RF95_FAN_EN, 1); +#endif + #ifdef RF95_RXEN pinMode(RF95_RXEN, OUTPUT); digitalWrite(RF95_RXEN, 1); @@ -146,10 +161,14 @@ bool RF95Interface::reconfigure() if (err != RADIOLIB_ERR_NONE) RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING); - if (power > MAX_POWER) // This chip has lower power limits than some - power = MAX_POWER; + if (power > RF95_MAX_POWER) // This chip has lower power limits than some + power = RF95_MAX_POWER; +#ifdef USE_RF95_RFO + err = lora->setOutputPower(power, true); +#else err = lora->setOutputPower(power); +#endif if (err != RADIOLIB_ERR_NONE) RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING); @@ -235,5 +254,9 @@ bool RF95Interface::sleep() setStandby(); // First cancel any active receiving/sending lora->sleep(); +#ifdef RF95_FAN_EN + digitalWrite(RF95_FAN_EN, 0); +#endif + return true; } \ No newline at end of file diff --git a/src/mesh/RadioLibRF95.cpp b/src/mesh/RadioLibRF95.cpp index 1fe7869a3..a202d4f4d 100644 --- a/src/mesh/RadioLibRF95.cpp +++ b/src/mesh/RadioLibRF95.cpp @@ -42,7 +42,11 @@ int16_t RadioLibRF95::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_ state = setCodingRate(cr); RADIOLIB_ASSERT(state); +#ifdef USE_RF95_RFO + state = setOutputPower(power, true); +#else state = setOutputPower(power); +#endif RADIOLIB_ASSERT(state); state = setGain(gain); diff --git a/src/platform/esp32/architecture.h b/src/platform/esp32/architecture.h index 45d533a76..824c11bdd 100644 --- a/src/platform/esp32/architecture.h +++ b/src/platform/esp32/architecture.h @@ -145,6 +145,8 @@ #define HW_VENDOR meshtastic_HardwareModel_UNPHONE #elif defined(WIPHONE) #define HW_VENDOR meshtastic_HardwareModel_WIPHONE +#elif defined(RADIOMASTER_900_BANDIT_NANO) +#define HW_VENDOR meshtastic_HardwareModel_RADIOMASTER_900_BANDIT_NANO #endif // ----------------------------------------------------------------------------- diff --git a/variants/radiomaster_900_bandit_nano/platformio.ini b/variants/radiomaster_900_bandit_nano/platformio.ini new file mode 100644 index 000000000..d83c14de2 --- /dev/null +++ b/variants/radiomaster_900_bandit_nano/platformio.ini @@ -0,0 +1,15 @@ +[env:radiomaster_900_bandit_nano] +extends = esp32_base +board = esp32doit-devkit-v1 +board_level = extra +build_flags = + ${esp32_base.build_flags} + -DRADIOMASTER_900_BANDIT_NANO + -DVTABLES_IN_FLASH=1 + -DCONFIG_DISABLE_HAL_LOCKS=1 + -O2 + -Ivariants/radiomaster_900_bandit_nano +board_build.f_cpu = 240000000L +upload_protocol = esptool +lib_deps = + ${esp32_base.lib_deps} \ No newline at end of file diff --git a/variants/radiomaster_900_bandit_nano/variant.h b/variants/radiomaster_900_bandit_nano/variant.h new file mode 100644 index 000000000..bd6687733 --- /dev/null +++ b/variants/radiomaster_900_bandit_nano/variant.h @@ -0,0 +1,84 @@ +/* + Initial settings and work by https://github.com/uberhalit and re-work by https://github.com/gjelsoe + Unit provided by Radio Master RC + https://radiomasterrc.com/products/bandit-nano-expresslrs-rf-module with 0.96" OLED display +*/ + +/* + I2C SDA and SCL. +*/ +#define I2C_SDA 14 +#define I2C_SCL 12 + +/* + No GPS - but free solder pads are available inside the case. +*/ +#undef GPS_RX_PIN +#undef GPS_TX_PIN + +/* + Pin connections from ESP32-D0WDQ6 to SX1276. +*/ +#define LORA_DIO0 22 +#define LORA_DIO1 21 +#define LORA_SCK 18 +#define LORA_MISO 19 +#define LORA_MOSI 23 +#define LORA_CS 4 +#define LORA_RESET 5 +#define LORA_TXEN 33 + +/* + This unit has a FAN built-in. + FAN is active at 250mW on it's ExpressLRS Firmware. +*/ +#define RF95_FAN_EN 2 + +/* + LED PIN setup. +*/ +#define LED_PIN 15 + +/* + Five way button when using ADC. + 2.632V, 2.177V, 1.598V, 1.055V, 0V + + Possible ADC Values: + { UP, DOWN, LEFT, RIGHT, ENTER, IDLE } + 3227, 0 ,1961, 2668, 1290, 4095 +*/ +#define BUTTON_PIN 39 +#define BUTTON_NEED_PULLUP + +#define SCREEN_ROTATE + +/* + No External notification. +*/ +#undef EXT_NOTIFY_OUT + +/* + Remapping PIN Names. + Note, that this unit uses RFO +*/ +#define USE_RF95 +#define USE_RF95_RFO +#define RF95_CS LORA_CS +#define RF95_DIO1 LORA_DIO1 +#define RF95_TXEN LORA_TXEN +#define RF95_RESET LORA_RESET +#define RF95_MAX_POWER 12 + +/* + This module has Skyworks SKY66122 controlled by dacWrite + power rangeing from 100mW to 1000mW. + + Mapping of PA_LEVEL to Power output: GPIO26/dacWrite + 168 -> 100mW -> 2.11v + 148 -> 250mW -> 1.87v + 128 -> 500mW -> 1.63v + 90 -> 1000mW -> 1.16v +*/ +#define RF95_PA_EN 26 +#define RF95_PA_DAC_EN +#define RF95_PA_LEVEL 90 \ No newline at end of file From eddda3ca43304357b7f130afe980091176814c05 Mon Sep 17 00:00:00 2001 From: fzellini Date: Fri, 31 May 2024 18:17:53 +0200 Subject: [PATCH 13/80] added AHTx0 sensor (#3977) * added AHTx0 sensor * AHT10 definition in protobuf * AHT10 definition in protobuf * protobufs * Management of AHT20+BMP280 module * missing newline in log * missing newline in log * reverted * reverted .gitignore --------- Co-authored-by: Ben Meadors --- platformio.ini | 1 + src/configuration.h | 1 + src/detect/ScanI2C.h | 1 + src/detect/ScanI2CTwoWire.cpp | 9 +++-- src/main.cpp | 1 + .../Telemetry/EnvironmentTelemetry.cpp | 17 +++++++++ src/modules/Telemetry/Sensor/AHT10.cpp | 35 +++++++++++++++++++ src/modules/Telemetry/Sensor/AHT10.h | 17 +++++++++ 8 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 src/modules/Telemetry/Sensor/AHT10.cpp create mode 100644 src/modules/Telemetry/Sensor/AHT10.h diff --git a/platformio.ini b/platformio.ini index c6efc740d..ca41a8021 100644 --- a/platformio.ini +++ b/platformio.ini @@ -130,6 +130,7 @@ lib_deps = adafruit/Adafruit PM25 AQI Sensor@^1.0.6 adafruit/Adafruit MPU6050@^2.2.4 adafruit/Adafruit LIS3DH@^1.2.4 + adafruit/Adafruit AHTX0@^2.0.5 lewisxhe/SensorLib@^0.2.0 adafruit/Adafruit LSM6DS@^4.7.2 mprograms/QMC5883LCompass@^1.2.0 diff --git a/src/configuration.h b/src/configuration.h index 858f3167e..daaf1a720 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -128,6 +128,7 @@ along with this program. If not, see . #define LPS22HB_ADDR_ALT 0x5D #define SHT31_4x_ADDR 0x44 #define PMSA0031_ADDR 0x12 +#define AHT10_ADDR 0x38 #define RCWL9620_ADDR 0x57 #define VEML7700_ADDR 0x10 diff --git a/src/detect/ScanI2C.h b/src/detect/ScanI2C.h index 6c01b9100..67e228791 100644 --- a/src/detect/ScanI2C.h +++ b/src/detect/ScanI2C.h @@ -45,6 +45,7 @@ class ScanI2C VEML7700, RCWL9620, NCP5623, + AHT10 } DeviceType; // typedef uint8_t DeviceAddress; diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index 7828dfb58..d46497d09 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -256,7 +256,12 @@ void ScanI2CTwoWire::scanPort(I2CPort port) type = BMP_280; } break; - +#ifndef HAS_NCP5623 + case AHT10_ADDR: + LOG_INFO("AHT10 sensor found at address 0x%x\n", (uint8_t)addr.address); + type = AHT10; + break; +#endif case INA_ADDR: case INA_ADDR_ALTERNATE: case INA_ADDR_WAVESHARE_UPS: @@ -369,4 +374,4 @@ TwoWire *ScanI2CTwoWire::fetchI2CBus(ScanI2C::DeviceAddress address) const size_t ScanI2CTwoWire::countDevices() const { return foundDevices.size(); -} +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 4a9fef5d0..f0564ea36 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -534,6 +534,7 @@ void setup() SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::RCWL9620, meshtastic_TelemetrySensorType_RCWL9620) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::VEML7700, meshtastic_TelemetrySensorType_VEML7700) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::SHT4X, meshtastic_TelemetrySensorType_SHT4X) + SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::AHT10, meshtastic_TelemetrySensorType_AHT10) i2cScanner.reset(); diff --git a/src/modules/Telemetry/EnvironmentTelemetry.cpp b/src/modules/Telemetry/EnvironmentTelemetry.cpp index a3f63b0aa..6d58460f4 100644 --- a/src/modules/Telemetry/EnvironmentTelemetry.cpp +++ b/src/modules/Telemetry/EnvironmentTelemetry.cpp @@ -18,6 +18,7 @@ #include // Sensors +#include "Sensor/AHT10.h" #include "Sensor/BME280Sensor.h" #include "Sensor/BME680Sensor.h" #include "Sensor/BMP085Sensor.h" @@ -41,6 +42,7 @@ SHT31Sensor sht31Sensor; VEML7700Sensor veml7700Sensor; SHT4XSensor sht4xSensor; RCWL9620Sensor rcwl9620Sensor; +AHT10Sensor aht10Sensor; #define FAILED_STATE_SENSOR_READ_MULTIPLIER 10 #define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true @@ -105,6 +107,8 @@ int32_t EnvironmentTelemetryModule::runOnce() result = veml7700Sensor.runOnce(); if (rcwl9620Sensor.hasSensor()) result = rcwl9620Sensor.runOnce(); + if (aht10Sensor.hasSensor()) + result = aht10Sensor.runOnce(); } return result; } else { @@ -291,6 +295,19 @@ bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly) valid = valid && rcwl9620Sensor.getMetrics(&m); hasSensor = true; } + if (aht10Sensor.hasSensor()) { + if (!bmp280Sensor.hasSensor()) { + valid = valid && aht10Sensor.getMetrics(&m); + hasSensor = true; + } else { + // prefer bmp280 temp if both sensors are present, fetch only humidity + meshtastic_Telemetry m_ahtx; + LOG_INFO("AHTX0+BMP280 module detected: using temp from BMP280 and humy from AHTX0\n"); + aht10Sensor.getMetrics(&m_ahtx); + m.variant.environment_metrics.relative_humidity = m_ahtx.variant.environment_metrics.relative_humidity; + } + } + valid = valid && hasSensor; if (valid) { diff --git a/src/modules/Telemetry/Sensor/AHT10.cpp b/src/modules/Telemetry/Sensor/AHT10.cpp new file mode 100644 index 000000000..985515bb6 --- /dev/null +++ b/src/modules/Telemetry/Sensor/AHT10.cpp @@ -0,0 +1,35 @@ +#include "AHT10.h" +#include "../mesh/generated/meshtastic/telemetry.pb.h" +#include "TelemetrySensor.h" +#include "configuration.h" +#include +#include + +AHT10Sensor::AHT10Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_AHT10, "AHT10") {} + +int32_t AHT10Sensor::runOnce() +{ + LOG_INFO("Init sensor: %s\n", sensorName); + if (!hasSensor()) { + return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; + } + aht10 = Adafruit_AHTX0(); + status = aht10.begin(nodeTelemetrySensorsMap[sensorType].second, 0, nodeTelemetrySensorsMap[sensorType].first); + + return initI2CSensor(); +} + +void AHT10Sensor::setup() {} + +bool AHT10Sensor::getMetrics(meshtastic_Telemetry *measurement) +{ + LOG_DEBUG("AHT10Sensor::getMetrics\n"); + + sensors_event_t humidity, temp; + aht10.getEvent(&humidity, &temp); + + measurement->variant.environment_metrics.temperature = temp.temperature; + measurement->variant.environment_metrics.relative_humidity = humidity.relative_humidity; + + return true; +} diff --git a/src/modules/Telemetry/Sensor/AHT10.h b/src/modules/Telemetry/Sensor/AHT10.h new file mode 100644 index 000000000..b2b7b47f3 --- /dev/null +++ b/src/modules/Telemetry/Sensor/AHT10.h @@ -0,0 +1,17 @@ +#include "../mesh/generated/meshtastic/telemetry.pb.h" +#include "TelemetrySensor.h" +#include + +class AHT10Sensor : public TelemetrySensor +{ + private: + Adafruit_AHTX0 aht10; + + protected: + virtual void setup() override; + + public: + AHT10Sensor(); + virtual int32_t runOnce() override; + virtual bool getMetrics(meshtastic_Telemetry *measurement) override; +}; From 4fa2427b8cf91b0e68c2a724e57066a789bdc5de Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Fri, 31 May 2024 11:18:06 -0500 Subject: [PATCH 14/80] Trunk variants --- variants/heltec_v3/variant.h | 2 +- variants/heltec_wireless_tracker/variant.h | 13 +++++++------ variants/heltec_wireless_tracker_V1_0/variant.h | 2 +- variants/heltec_wsl_v3/variant.h | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/variants/heltec_v3/variant.h b/variants/heltec_v3/variant.h index 0c22ea1a7..2417b873d 100644 --- a/variants/heltec_v3/variant.h +++ b/variants/heltec_v3/variant.h @@ -16,7 +16,7 @@ #define BATTERY_PIN 1 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage #define ADC_CHANNEL ADC1_GPIO1_CHANNEL #define ADC_ATTENUATION ADC_ATTEN_DB_2_5 // lower dB for high resistance voltage divider -#define ADC_MULTIPLIER 4.9*1.045 +#define ADC_MULTIPLIER 4.9 * 1.045 #define USE_SX1262 diff --git a/variants/heltec_wireless_tracker/variant.h b/variants/heltec_wireless_tracker/variant.h index d496a8d6f..f0ee0631d 100644 --- a/variants/heltec_wireless_tracker/variant.h +++ b/variants/heltec_wireless_tracker/variant.h @@ -27,17 +27,17 @@ #define SCREEN_TRANSITION_FRAMERATE 3 // fps #define DISPLAY_FORCE_SMALL_FONTS - // pin 3 is Vext on v1.1 - HIGH enables LDO for Vext rail which goes to: - // GPS UC6580: GPS V_DET(8), VDD_IO(7), DCDC_IN(21), pulls up RESETN(17), D_SEL(33) and BOOT_MODE(34) through 10kR - // GPS LNA SW7125DE: VCC(4), pulls up SHDN(5) through 10kR - // LED: VDD, LEDA (through diode) +// pin 3 is Vext on v1.1 - HIGH enables LDO for Vext rail which goes to: +// GPS UC6580: GPS V_DET(8), VDD_IO(7), DCDC_IN(21), pulls up RESETN(17), D_SEL(33) and BOOT_MODE(34) through 10kR +// GPS LNA SW7125DE: VCC(4), pulls up SHDN(5) through 10kR +// LED: VDD, LEDA (through diode) #define VEXT_ENABLE_V05 3 // active HIGH - powers the GPS, GPS LNA and OLED VDD/anode #define BUTTON_PIN 0 #define BATTERY_PIN 1 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage #define ADC_CHANNEL ADC1_GPIO1_CHANNEL #define ADC_ATTENUATION ADC_ATTEN_DB_2_5 // lower dB for high resistance voltage divider -#define ADC_MULTIPLIER 4.9*1.045 +#define ADC_MULTIPLIER 4.9 * 1.045 #define ADC_CTRL 2 // active HIGH, powers the voltage divider. Only on 1.1 #define ADC_CTRL_ENABLED HIGH @@ -47,7 +47,8 @@ #define GPS_TX_PIN 34 #define PIN_GPS_RESET 35 #define PIN_GPS_PPS 36 -// #define PIN_GPS_EN 3 // Uncomment to power off the GPS with triple-click on Tracker v1.1, though we'll also lose the display. +// #define PIN_GPS_EN 3 // Uncomment to power off the GPS with triple-click on Tracker v1.1, though we'll also lose the +// display. #define GPS_RESET_MODE LOW #define GPS_UC6580 diff --git a/variants/heltec_wireless_tracker_V1_0/variant.h b/variants/heltec_wireless_tracker_V1_0/variant.h index 2b521f249..1b4751a57 100644 --- a/variants/heltec_wireless_tracker_V1_0/variant.h +++ b/variants/heltec_wireless_tracker_V1_0/variant.h @@ -34,7 +34,7 @@ #define BATTERY_PIN 1 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage #define ADC_CHANNEL ADC1_GPIO1_CHANNEL #define ADC_ATTENUATION ADC_ATTEN_DB_2_5 // lower dB for high resistance voltage divider -#define ADC_MULTIPLIER 4.9*1.045 +#define ADC_MULTIPLIER 4.9 * 1.045 #undef GPS_RX_PIN #undef GPS_TX_PIN diff --git a/variants/heltec_wsl_v3/variant.h b/variants/heltec_wsl_v3/variant.h index 37cef09c6..75cea538d 100644 --- a/variants/heltec_wsl_v3/variant.h +++ b/variants/heltec_wsl_v3/variant.h @@ -11,7 +11,7 @@ #define BATTERY_PIN 1 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage #define ADC_CHANNEL ADC1_GPIO1_CHANNEL #define ADC_ATTENUATION ADC_ATTEN_DB_2_5 // lower dB for high resistance voltage divider -#define ADC_MULTIPLIER 4.9*1.045 +#define ADC_MULTIPLIER 4.9 * 1.045 #define USE_SX1262 From ffff2a03fc0a96cf90c12cc59a564d9a34dcc9a0 Mon Sep 17 00:00:00 2001 From: fzellini Date: Fri, 31 May 2024 20:05:40 +0200 Subject: [PATCH 15/80] dragino trackerd (#4002) * added AHTx0 sensor * AHT10 definition in protobuf * AHT10 definition in protobuf * protobufs * Management of AHT20+BMP280 module * missing newline in log * missing newline in log * dragino trackerd support * dragino trackerd support * revert back .gitmodules * reverted gitignore * merged telemetry.pb.h * merged telemetry.pb.h * removed extra script, now bin version works * reverted --------- Co-authored-by: Ben Meadors --- variants/trackerd/variant.h | 42 ++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/variants/trackerd/variant.h b/variants/trackerd/variant.h index bd8017d8c..c4dfb9e93 100644 --- a/variants/trackerd/variant.h +++ b/variants/trackerd/variant.h @@ -20,16 +20,34 @@ #define LORA_DIO1 33 #define LORA_DIO2 32 // Not really used -#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage +#undef BAT_MEASURE_ADC_UNIT +#define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage +#define ADC_MULTIPLIER 1.34 // tracked resistance divider is 100k+470k, so it can not fillfull well on esp32 adc +#define ADC_CHANNEL ADC1_GPIO35_CHANNEL +#define ADC_ATTENUATION ADC_ATTEN_DB_12 // lower dB for high resistance voltage divider -// Battery -// The battery sense is hooked to pin A0 (4) -// it is defined in the anlaolgue pin section of this file -// and has 12 bit resolution -// #define BATTERY_SENSE_SAMPLES 15 // Set the number of samples, It has an effect of increasing sensitivity. -#define BATTERY_SENSE_RESOLUTION_BITS 12 -#define BATTERY_SENSE_RESOLUTION 4096.0 -#undef AREF_VOLTAGE -#define AREF_VOLTAGE 3.0 -#define VBAT_AR_INTERNAL AR_INTERNAL_3_0 -#define ADC_MULTIPLIER (2.0F) \ No newline at end of file +#undef GPS_RX_PIN +#undef GPS_TX_PIN +#undef PIN_GPS_PPS + +#define PIN_GPS_EN 12 +#define GPS_EN_ACTIVE 1 + +#define GPS_TX_PIN 10 +#define GPS_RX_PIN 9 + +#define PIN_GPS_RESET 25 +// #define PIN_GPS_REINIT 25 +#define GPS_RESET_MODE 1 + +#define GPS_L76K + +#undef PIN_LED1 +#undef PIN_LED2 +#undef PIN_LED3 + +#define PIN_LED1 13 +#define PIN_LED2 15 +#define PIN_LED3 2 + +#define ledOff(pin) pinMode(pin, INPUT) \ No newline at end of file From 2740a56944d6647e53320a7e235b61ae0207a143 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Sat, 1 Jun 2024 02:46:42 +0200 Subject: [PATCH 16/80] tryfix: init change for BME680 (#3965) --- src/modules/Telemetry/Sensor/BME680Sensor.cpp | 2 +- src/modules/Telemetry/Sensor/BME680Sensor.h | 4 +- .../Sensor/bme680_iaq_33v_3s_4d/bsec_iaq.c | 86 ------------------- .../Sensor/bme680_iaq_33v_3s_4d/bsec_iaq.h | 7 -- 4 files changed, 4 insertions(+), 95 deletions(-) delete mode 100644 src/modules/Telemetry/Sensor/bme680_iaq_33v_3s_4d/bsec_iaq.c delete mode 100644 src/modules/Telemetry/Sensor/bme680_iaq_33v_3s_4d/bsec_iaq.h diff --git a/src/modules/Telemetry/Sensor/BME680Sensor.cpp b/src/modules/Telemetry/Sensor/BME680Sensor.cpp index f2c3804f4..71da39043 100644 --- a/src/modules/Telemetry/Sensor/BME680Sensor.cpp +++ b/src/modules/Telemetry/Sensor/BME680Sensor.cpp @@ -28,7 +28,7 @@ int32_t BME680Sensor::runOnce() if (bme680.status == BSEC_OK) { status = 1; - if (!bme680.setConfig(bsec_config_iaq)) { + if (!bme680.setConfig(bsec_config)) { checkStatus("setConfig"); status = 0; } diff --git a/src/modules/Telemetry/Sensor/BME680Sensor.h b/src/modules/Telemetry/Sensor/BME680Sensor.h index 351db50ab..a5d2b5a48 100644 --- a/src/modules/Telemetry/Sensor/BME680Sensor.h +++ b/src/modules/Telemetry/Sensor/BME680Sensor.h @@ -8,7 +8,9 @@ #define STATE_SAVE_PERIOD UINT32_C(360 * 60 * 1000) // That's 6 hours worth of millis() -#include "bme680_iaq_33v_3s_4d/bsec_iaq.h" +const uint8_t bsec_config[] = { +#include "config/bme680/bme680_iaq_33v_3s_4d/bsec_iaq.txt" +}; class BME680Sensor : public TelemetrySensor { diff --git a/src/modules/Telemetry/Sensor/bme680_iaq_33v_3s_4d/bsec_iaq.c b/src/modules/Telemetry/Sensor/bme680_iaq_33v_3s_4d/bsec_iaq.c deleted file mode 100644 index 0b5328306..000000000 --- a/src/modules/Telemetry/Sensor/bme680_iaq_33v_3s_4d/bsec_iaq.c +++ /dev/null @@ -1,86 +0,0 @@ -#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR - -#include "bsec_iaq.h" - -const uint8_t bsec_config_iaq[1974] = { - 0, 0, 4, 2, 189, 1, 0, 0, 0, 0, 0, 0, 158, 7, 0, 0, 176, 0, 1, 0, 0, 192, 168, 71, 64, - 49, 119, 76, 0, 0, 97, 69, 0, 0, 97, 69, 137, 65, 0, 191, 205, 204, 204, 190, 0, 0, 64, 191, 225, 122, - 148, 190, 10, 0, 3, 0, 0, 0, 96, 64, 23, 183, 209, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 205, 204, 204, 189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 128, 63, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 128, 63, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 128, 63, 82, 73, 157, 188, 95, 41, 203, 61, 118, 224, - 108, 63, 155, 230, 125, 63, 191, 14, 124, 63, 0, 0, 160, 65, 0, 0, 32, 66, 0, 0, 160, 65, 0, 0, 32, - 66, 0, 0, 32, 66, 0, 0, 160, 65, 0, 0, 32, 66, 0, 0, 160, 65, 8, 0, 2, 0, 236, 81, 133, 66, - 16, 0, 3, 0, 10, 215, 163, 60, 10, 215, 35, 59, 10, 215, 35, 59, 13, 0, 5, 0, 0, 0, 0, 0, 100, - 35, 41, 29, 86, 88, 0, 9, 0, 229, 208, 34, 62, 0, 0, 0, 0, 0, 0, 0, 0, 218, 27, 156, 62, 225, - 11, 67, 64, 0, 0, 160, 64, 0, 0, 0, 0, 0, 0, 0, 0, 94, 75, 72, 189, 93, 254, 159, 64, 66, 62, - 160, 191, 0, 0, 0, 0, 0, 0, 0, 0, 33, 31, 180, 190, 138, 176, 97, 64, 65, 241, 99, 190, 0, 0, 0, - 0, 0, 0, 0, 0, 167, 121, 71, 61, 165, 189, 41, 192, 184, 30, 189, 64, 12, 0, 10, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 13, 5, 11, 0, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, - 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, - 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, - 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, - 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, - 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, - 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, - 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, - 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, - 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, - 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, - 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, - 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, - 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, - 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, - 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, - 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, - 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, - 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, - 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, - 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, - 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, - 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, - 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, - 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, - 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, - 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, - 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, - 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, - 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, - 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, - 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, - 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, - 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, - 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, - 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, - 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, - 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, - 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, - 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, - 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, - 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, - 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, - 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 10, 10, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, - 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, - 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 0, 88, 1, 254, - 0, 2, 1, 5, 48, 117, 100, 0, 44, 1, 112, 23, 151, 7, 132, 3, 197, 0, 92, 4, 144, 1, 64, 1, 64, - 1, 144, 1, 48, 117, 48, 117, 48, 117, 48, 117, 100, 0, 100, 0, 100, 0, 48, 117, 48, 117, 48, 117, 100, 0, - 100, 0, 48, 117, 48, 117, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 100, 0, 100, 0, 100, 0, 100, 0, 48, - 117, 48, 117, 48, 117, 100, 0, 100, 0, 100, 0, 48, 117, 48, 117, 100, 0, 100, 0, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, - 1, 44, 1, 44, 1, 44, 1, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 112, 23, 112, 23, 112, 23, 112, 23, - 8, 7, 8, 7, 8, 7, 8, 7, 112, 23, 112, 23, 112, 23, 112, 23, 112, 23, 112, 23, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 112, 23, 112, 23, 112, 23, 112, 23, 255, 255, 255, 255, - 220, 5, 220, 5, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 220, 5, 220, 5, 220, 5, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 44, 1, 0, 5, 10, 5, - 0, 2, 0, 10, 0, 30, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 64, 1, 100, 0, 100, 0, - 100, 0, 200, 0, 200, 0, 200, 0, 64, 1, 64, 1, 64, 1, 10, 0, 0, 0, 0, 0, 21, 122, 0, 0}; - -#endif \ No newline at end of file diff --git a/src/modules/Telemetry/Sensor/bme680_iaq_33v_3s_4d/bsec_iaq.h b/src/modules/Telemetry/Sensor/bme680_iaq_33v_3s_4d/bsec_iaq.h deleted file mode 100644 index d693f1e6a..000000000 --- a/src/modules/Telemetry/Sensor/bme680_iaq_33v_3s_4d/bsec_iaq.h +++ /dev/null @@ -1,7 +0,0 @@ -#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR - -#include - -extern const uint8_t bsec_config_iaq[1974]; - -#endif \ No newline at end of file From 9a855c0b6f5647144a38f1bbc13770d07c4e3fff Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 1 Jun 2024 07:46:01 -0500 Subject: [PATCH 17/80] [create-pull-request] automated change (#4011) Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com> --- version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.properties b/version.properties index aa4d2c207..700044e6f 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 2 minor = 3 -build = 11 +build = 12 From 6ce2fdc1c886a519442749a1db1c2fe0c469b2cb Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Sat, 1 Jun 2024 20:21:39 -0500 Subject: [PATCH 18/80] Add TSL2591 sensor support (#4014) --- platformio.ini | 3 +- src/configuration.h | 1 + src/detect/ScanI2C.h | 3 +- src/detect/ScanI2CTwoWire.cpp | 1 + src/main.cpp | 1 + .../Telemetry/EnvironmentTelemetry.cpp | 10 ++++- .../Telemetry/Sensor/TSL2591Sensor.cpp | 38 +++++++++++++++++++ src/modules/Telemetry/Sensor/TSL2591Sensor.h | 17 +++++++++ 8 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 src/modules/Telemetry/Sensor/TSL2591Sensor.cpp create mode 100644 src/modules/Telemetry/Sensor/TSL2591Sensor.h diff --git a/platformio.ini b/platformio.ini index ca41a8021..f4306c2ea 100644 --- a/platformio.ini +++ b/platformio.ini @@ -135,4 +135,5 @@ lib_deps = adafruit/Adafruit LSM6DS@^4.7.2 mprograms/QMC5883LCompass@^1.2.0 adafruit/Adafruit VEML7700 Library@^2.1.6 - adafruit/Adafruit SHT4x Library@^1.0.4 \ No newline at end of file + adafruit/Adafruit SHT4x Library@^1.0.4 + adafruit/Adafruit TSL2591 Library@^1.4.5 \ No newline at end of file diff --git a/src/configuration.h b/src/configuration.h index daaf1a720..2d0095e22 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -131,6 +131,7 @@ along with this program. If not, see . #define AHT10_ADDR 0x38 #define RCWL9620_ADDR 0x57 #define VEML7700_ADDR 0x10 +#define TSL25911_ADDR 0x29 // ----------------------------------------------------------------------------- // ACCELEROMETER diff --git a/src/detect/ScanI2C.h b/src/detect/ScanI2C.h index 67e228791..a2ccb18a8 100644 --- a/src/detect/ScanI2C.h +++ b/src/detect/ScanI2C.h @@ -45,7 +45,8 @@ class ScanI2C VEML7700, RCWL9620, NCP5623, - AHT10 + TSL2591, + AHT10, } DeviceType; // typedef uint8_t DeviceAddress; diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index d46497d09..d2a6e7848 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -342,6 +342,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port) SCAN_SIMPLE_CASE(LSM6DS3_ADDR, LSM6DS3, "LSM6DS3 accelerometer found at address 0x%x\n", (uint8_t)addr.address); SCAN_SIMPLE_CASE(TCA9555_ADDR, TCA9555, "TCA9555 I2C expander found\n"); SCAN_SIMPLE_CASE(VEML7700_ADDR, VEML7700, "VEML7700 light sensor found\n"); + SCAN_SIMPLE_CASE(TSL25911_ADDR, TSL2591, "TSL2591 light sensor found\n"); default: LOG_INFO("Device found at address 0x%x was not able to be enumerated\n", addr.address); diff --git a/src/main.cpp b/src/main.cpp index f0564ea36..d9b4d84ab 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -533,6 +533,7 @@ void setup() SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::PMSA0031, meshtastic_TelemetrySensorType_PMSA003I) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::RCWL9620, meshtastic_TelemetrySensorType_RCWL9620) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::VEML7700, meshtastic_TelemetrySensorType_VEML7700) + SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::TSL2591, meshtastic_TelemetrySensorType_TSL25911FN) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::SHT4X, meshtastic_TelemetrySensorType_SHT4X) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::AHT10, meshtastic_TelemetrySensorType_AHT10) diff --git a/src/modules/Telemetry/EnvironmentTelemetry.cpp b/src/modules/Telemetry/EnvironmentTelemetry.cpp index 6d58460f4..5ecfe7328 100644 --- a/src/modules/Telemetry/EnvironmentTelemetry.cpp +++ b/src/modules/Telemetry/EnvironmentTelemetry.cpp @@ -29,6 +29,7 @@ #include "Sensor/SHT31Sensor.h" #include "Sensor/SHT4XSensor.h" #include "Sensor/SHTC3Sensor.h" +#include "Sensor/TSL2591Sensor.h" #include "Sensor/VEML7700Sensor.h" BMP085Sensor bmp085Sensor; @@ -40,6 +41,7 @@ SHTC3Sensor shtc3Sensor; LPS22HBSensor lps22hbSensor; SHT31Sensor sht31Sensor; VEML7700Sensor veml7700Sensor; +TSL2591Sensor tsl2591Sensor; SHT4XSensor sht4xSensor; RCWL9620Sensor rcwl9620Sensor; AHT10Sensor aht10Sensor; @@ -65,7 +67,7 @@ int32_t EnvironmentTelemetryModule::runOnce() */ // moduleConfig.telemetry.environment_measurement_enabled = 1; - // moduleConfig.telemetry.environment_screen_enabled = 1; + // moduleConfig.telemetry.environment_screen_enabled = 1; // moduleConfig.telemetry.environment_update_interval = 45; if (!(moduleConfig.telemetry.environment_measurement_enabled || moduleConfig.telemetry.environment_screen_enabled)) { @@ -105,6 +107,8 @@ int32_t EnvironmentTelemetryModule::runOnce() result = ina260Sensor.runOnce(); if (veml7700Sensor.hasSensor()) result = veml7700Sensor.runOnce(); + if (tsl2591Sensor.hasSensor()) + result = tsl2591Sensor.runOnce(); if (rcwl9620Sensor.hasSensor()) result = rcwl9620Sensor.runOnce(); if (aht10Sensor.hasSensor()) @@ -291,6 +295,10 @@ bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly) valid = valid && veml7700Sensor.getMetrics(&m); hasSensor = true; } + if (tsl2591Sensor.hasSensor()) { + valid = valid && tsl2591Sensor.getMetrics(&m); + hasSensor = true; + } if (rcwl9620Sensor.hasSensor()) { valid = valid && rcwl9620Sensor.getMetrics(&m); hasSensor = true; diff --git a/src/modules/Telemetry/Sensor/TSL2591Sensor.cpp b/src/modules/Telemetry/Sensor/TSL2591Sensor.cpp new file mode 100644 index 000000000..0a3f5d685 --- /dev/null +++ b/src/modules/Telemetry/Sensor/TSL2591Sensor.cpp @@ -0,0 +1,38 @@ +#include "TSL2591Sensor.h" +#include "../mesh/generated/meshtastic/telemetry.pb.h" +#include "TelemetrySensor.h" +#include "configuration.h" +#include +#include + +TSL2591Sensor::TSL2591Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_TSL25911FN, "TSL2591") {} + +int32_t TSL2591Sensor::runOnce() +{ + LOG_INFO("Init sensor: %s\n", sensorName); + if (!hasSensor()) { + return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; + } + status = tsl.begin(nodeTelemetrySensorsMap[sensorType].second); + + return initI2CSensor(); +} + +void TSL2591Sensor::setup() +{ + tsl.setGain(TSL2591_GAIN_MED); // 25x gain + tsl.setTiming(TSL2591_INTEGRATIONTIME_300MS); +} + +bool TSL2591Sensor::getMetrics(meshtastic_Telemetry *measurement) +{ + uint32_t lum = tsl.getFullLuminosity(); + uint16_t ir, full; + ir = lum >> 16; + full = lum & 0xFFFF; + + measurement->variant.environment_metrics.lux = tsl.calculateLux(full, ir); + LOG_INFO("Lux: %f\n", measurement->variant.environment_metrics.lux); + + return true; +} \ No newline at end of file diff --git a/src/modules/Telemetry/Sensor/TSL2591Sensor.h b/src/modules/Telemetry/Sensor/TSL2591Sensor.h new file mode 100644 index 000000000..a24d53975 --- /dev/null +++ b/src/modules/Telemetry/Sensor/TSL2591Sensor.h @@ -0,0 +1,17 @@ +#include "../mesh/generated/meshtastic/telemetry.pb.h" +#include "TelemetrySensor.h" +#include + +class TSL2591Sensor : public TelemetrySensor +{ + private: + Adafruit_TSL2591 tsl; + + protected: + virtual void setup() override; + + public: + TSL2591Sensor(); + virtual int32_t runOnce() override; + virtual bool getMetrics(meshtastic_Telemetry *measurement) override; +}; \ No newline at end of file From 2723ae6e9be95b7e924e940efe04cac393af6a44 Mon Sep 17 00:00:00 2001 From: Manuel <71137295+mverch67@users.noreply.github.com> Date: Sun, 2 Jun 2024 14:38:20 +0200 Subject: [PATCH 19/80] fix crash during reset nodedb (#4017) --- src/mesh/NodeDB.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 9473df8c5..cf576e94f 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -444,9 +444,9 @@ void NodeDB::installDefaultChannels() void NodeDB::resetNodes() { + clearLocalPosition(); numMeshNodes = 1; std::fill(devicestate.node_db_lite.begin() + 1, devicestate.node_db_lite.end(), meshtastic_NodeInfoLite()); - clearLocalPosition(); saveDeviceStateToDisk(); if (neighborInfoModule && moduleConfig.neighbor_info.enabled) neighborInfoModule->resetNeighbors(); From 97a5abbc82c8b55edd396202bc7977a2868f5380 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Sun, 2 Jun 2024 07:39:08 -0500 Subject: [PATCH 20/80] TI OPT3001 light sensor support (#4015) * TI OPT3001 light sensor support * Added register interrogation to deconflict with SHT sensors on same address --- platformio.ini | 3 +- src/configuration.h | 2 + src/detect/ScanI2C.h | 1 + src/detect/ScanI2CTwoWire.cpp | 4 ++ src/main.cpp | 1 + .../Telemetry/EnvironmentTelemetry.cpp | 8 ++++ .../Telemetry/Sensor/OPT3001Sensor.cpp | 44 +++++++++++++++++++ src/modules/Telemetry/Sensor/OPT3001Sensor.h | 17 +++++++ 8 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 src/modules/Telemetry/Sensor/OPT3001Sensor.cpp create mode 100644 src/modules/Telemetry/Sensor/OPT3001Sensor.h diff --git a/platformio.ini b/platformio.ini index f4306c2ea..791c31a9b 100644 --- a/platformio.ini +++ b/platformio.ini @@ -136,4 +136,5 @@ lib_deps = mprograms/QMC5883LCompass@^1.2.0 adafruit/Adafruit VEML7700 Library@^2.1.6 adafruit/Adafruit SHT4x Library@^1.0.4 - adafruit/Adafruit TSL2591 Library@^1.4.5 \ No newline at end of file + adafruit/Adafruit TSL2591 Library@^1.4.5 + ClosedCube OPT3001@^1.1.2 \ No newline at end of file diff --git a/src/configuration.h b/src/configuration.h index 2d0095e22..b102746b3 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -132,6 +132,8 @@ along with this program. If not, see . #define RCWL9620_ADDR 0x57 #define VEML7700_ADDR 0x10 #define TSL25911_ADDR 0x29 +#define OPT3001_ADDRESS 0x45 +#define OPT3001_ADDRESS_ALT 0x44 // ----------------------------------------------------------------------------- // ACCELEROMETER diff --git a/src/detect/ScanI2C.h b/src/detect/ScanI2C.h index a2ccb18a8..917335a14 100644 --- a/src/detect/ScanI2C.h +++ b/src/detect/ScanI2C.h @@ -46,6 +46,7 @@ class ScanI2C RCWL9620, NCP5623, TSL2591, + OPT3001, AHT10, } DeviceType; diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index d2a6e7848..4597a70ca 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -302,6 +302,9 @@ void ScanI2CTwoWire::scanPort(I2CPort port) if (registerValue == 0x11a2) { type = SHT4X; LOG_INFO("SHT4X sensor found\n"); + } else if (getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x7E), 2) == 0x5449) { + type = OPT3001; + LOG_INFO("OPT3001 light sensor found\n"); } else { type = SHT31; LOG_INFO("SHT31 sensor found\n"); @@ -343,6 +346,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port) SCAN_SIMPLE_CASE(TCA9555_ADDR, TCA9555, "TCA9555 I2C expander found\n"); SCAN_SIMPLE_CASE(VEML7700_ADDR, VEML7700, "VEML7700 light sensor found\n"); SCAN_SIMPLE_CASE(TSL25911_ADDR, TSL2591, "TSL2591 light sensor found\n"); + SCAN_SIMPLE_CASE(OPT3001_ADDRESS, OPT3001, "OPT3001 light sensor found\n"); default: LOG_INFO("Device found at address 0x%x was not able to be enumerated\n", addr.address); diff --git a/src/main.cpp b/src/main.cpp index d9b4d84ab..8d870feba 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -534,6 +534,7 @@ void setup() SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::RCWL9620, meshtastic_TelemetrySensorType_RCWL9620) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::VEML7700, meshtastic_TelemetrySensorType_VEML7700) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::TSL2591, meshtastic_TelemetrySensorType_TSL25911FN) + SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::OPT3001, meshtastic_TelemetrySensorType_OPT3001) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::SHT4X, meshtastic_TelemetrySensorType_SHT4X) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::AHT10, meshtastic_TelemetrySensorType_AHT10) diff --git a/src/modules/Telemetry/EnvironmentTelemetry.cpp b/src/modules/Telemetry/EnvironmentTelemetry.cpp index 5ecfe7328..1d45d3ee9 100644 --- a/src/modules/Telemetry/EnvironmentTelemetry.cpp +++ b/src/modules/Telemetry/EnvironmentTelemetry.cpp @@ -25,6 +25,7 @@ #include "Sensor/BMP280Sensor.h" #include "Sensor/LPS22HBSensor.h" #include "Sensor/MCP9808Sensor.h" +#include "Sensor/OPT3001Sensor.h" #include "Sensor/RCWL9620Sensor.h" #include "Sensor/SHT31Sensor.h" #include "Sensor/SHT4XSensor.h" @@ -42,6 +43,7 @@ LPS22HBSensor lps22hbSensor; SHT31Sensor sht31Sensor; VEML7700Sensor veml7700Sensor; TSL2591Sensor tsl2591Sensor; +OPT3001Sensor opt3001Sensor; SHT4XSensor sht4xSensor; RCWL9620Sensor rcwl9620Sensor; AHT10Sensor aht10Sensor; @@ -109,6 +111,8 @@ int32_t EnvironmentTelemetryModule::runOnce() result = veml7700Sensor.runOnce(); if (tsl2591Sensor.hasSensor()) result = tsl2591Sensor.runOnce(); + if (opt3001Sensor.hasSensor()) + result = opt3001Sensor.runOnce(); if (rcwl9620Sensor.hasSensor()) result = rcwl9620Sensor.runOnce(); if (aht10Sensor.hasSensor()) @@ -299,6 +303,10 @@ bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly) valid = valid && tsl2591Sensor.getMetrics(&m); hasSensor = true; } + if (opt3001Sensor.hasSensor()) { + valid = valid && opt3001Sensor.getMetrics(&m); + hasSensor = true; + } if (rcwl9620Sensor.hasSensor()) { valid = valid && rcwl9620Sensor.getMetrics(&m); hasSensor = true; diff --git a/src/modules/Telemetry/Sensor/OPT3001Sensor.cpp b/src/modules/Telemetry/Sensor/OPT3001Sensor.cpp new file mode 100644 index 000000000..0d76e2897 --- /dev/null +++ b/src/modules/Telemetry/Sensor/OPT3001Sensor.cpp @@ -0,0 +1,44 @@ +#include "OPT3001Sensor.h" +#include "../mesh/generated/meshtastic/telemetry.pb.h" +#include "TelemetrySensor.h" +#include "configuration.h" +#include + +OPT3001Sensor::OPT3001Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_OPT3001, "OPT3001") {} + +int32_t OPT3001Sensor::runOnce() +{ + LOG_INFO("Init sensor: %s\n", sensorName); + if (!hasSensor()) { + return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; + } + auto errorCode = opt3001.begin(nodeTelemetrySensorsMap[sensorType].first); + status = errorCode == NO_ERROR; + + return initI2CSensor(); +} + +void OPT3001Sensor::setup() +{ + OPT3001_Config newConfig; + + newConfig.RangeNumber = B1100; + newConfig.ConvertionTime = B0; + newConfig.Latch = B1; + newConfig.ModeOfConversionOperation = B11; + + OPT3001_ErrorCode errorConfig = opt3001.writeConfig(newConfig); + if (errorConfig != NO_ERROR) { + LOG_ERROR("OPT3001 configuration error #%d", errorConfig); + } +} + +bool OPT3001Sensor::getMetrics(meshtastic_Telemetry *measurement) +{ + OPT3001 result = opt3001.readResult(); + + measurement->variant.environment_metrics.lux = result.lux; + LOG_INFO("Lux: %f\n", measurement->variant.environment_metrics.lux); + + return true; +} \ No newline at end of file diff --git a/src/modules/Telemetry/Sensor/OPT3001Sensor.h b/src/modules/Telemetry/Sensor/OPT3001Sensor.h new file mode 100644 index 000000000..4a8deef21 --- /dev/null +++ b/src/modules/Telemetry/Sensor/OPT3001Sensor.h @@ -0,0 +1,17 @@ +#include "../mesh/generated/meshtastic/telemetry.pb.h" +#include "TelemetrySensor.h" +#include + +class OPT3001Sensor : public TelemetrySensor +{ + private: + ClosedCube_OPT3001 opt3001; + + protected: + virtual void setup() override; + + public: + OPT3001Sensor(); + virtual int32_t runOnce() override; + virtual bool getMetrics(meshtastic_Telemetry *measurement) override; +}; \ No newline at end of file From 06c635eca0b489d90c82286eea679a0e190ead16 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Sun, 2 Jun 2024 09:38:28 -0500 Subject: [PATCH 21/80] MLX90632 IR temperature sensor support (#4019) --- platformio.ini | 3 +- src/configuration.h | 5 ++- src/detect/ScanI2C.h | 1 + src/detect/ScanI2CTwoWire.cpp | 3 +- src/main.cpp | 1 + .../Telemetry/EnvironmentTelemetry.cpp | 8 ++++ .../Telemetry/Sensor/MLX90632Sensor.cpp | 40 +++++++++++++++++++ src/modules/Telemetry/Sensor/MLX90632Sensor.h | 23 +++++++++++ 8 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 src/modules/Telemetry/Sensor/MLX90632Sensor.cpp create mode 100644 src/modules/Telemetry/Sensor/MLX90632Sensor.h diff --git a/platformio.ini b/platformio.ini index 791c31a9b..968a37d9b 100644 --- a/platformio.ini +++ b/platformio.ini @@ -137,4 +137,5 @@ lib_deps = adafruit/Adafruit VEML7700 Library@^2.1.6 adafruit/Adafruit SHT4x Library@^1.0.4 adafruit/Adafruit TSL2591 Library@^1.4.5 - ClosedCube OPT3001@^1.1.2 \ No newline at end of file + ClosedCube OPT3001@^1.1.2 + emotibit/EmotiBit MLX90632@^1.0.8 \ No newline at end of file diff --git a/src/configuration.h b/src/configuration.h index b102746b3..744406f18 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -132,8 +132,9 @@ along with this program. If not, see . #define RCWL9620_ADDR 0x57 #define VEML7700_ADDR 0x10 #define TSL25911_ADDR 0x29 -#define OPT3001_ADDRESS 0x45 -#define OPT3001_ADDRESS_ALT 0x44 +#define OPT3001_ADDR 0x45 +#define OPT3001_ADDR_ALT 0x44 +#define MLX90632_ADDR 0x3A // ----------------------------------------------------------------------------- // ACCELEROMETER diff --git a/src/detect/ScanI2C.h b/src/detect/ScanI2C.h index 917335a14..a90d9218a 100644 --- a/src/detect/ScanI2C.h +++ b/src/detect/ScanI2C.h @@ -47,6 +47,7 @@ class ScanI2C NCP5623, TSL2591, OPT3001, + MLX90632, AHT10, } DeviceType; diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index 4597a70ca..3aeb8560e 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -346,7 +346,8 @@ void ScanI2CTwoWire::scanPort(I2CPort port) SCAN_SIMPLE_CASE(TCA9555_ADDR, TCA9555, "TCA9555 I2C expander found\n"); SCAN_SIMPLE_CASE(VEML7700_ADDR, VEML7700, "VEML7700 light sensor found\n"); SCAN_SIMPLE_CASE(TSL25911_ADDR, TSL2591, "TSL2591 light sensor found\n"); - SCAN_SIMPLE_CASE(OPT3001_ADDRESS, OPT3001, "OPT3001 light sensor found\n"); + SCAN_SIMPLE_CASE(OPT3001_ADDR, OPT3001, "OPT3001 light sensor found\n"); + SCAN_SIMPLE_CASE(MLX90632_ADDR, MLX90632, "MLX90632 IR temp sensor found\n"); default: LOG_INFO("Device found at address 0x%x was not able to be enumerated\n", addr.address); diff --git a/src/main.cpp b/src/main.cpp index 8d870feba..3c1893690 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -535,6 +535,7 @@ void setup() SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::VEML7700, meshtastic_TelemetrySensorType_VEML7700) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::TSL2591, meshtastic_TelemetrySensorType_TSL25911FN) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::OPT3001, meshtastic_TelemetrySensorType_OPT3001) + SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::MLX90632, meshtastic_TelemetrySensorType_MLX90632) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::SHT4X, meshtastic_TelemetrySensorType_SHT4X) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::AHT10, meshtastic_TelemetrySensorType_AHT10) diff --git a/src/modules/Telemetry/EnvironmentTelemetry.cpp b/src/modules/Telemetry/EnvironmentTelemetry.cpp index 1d45d3ee9..9032389c5 100644 --- a/src/modules/Telemetry/EnvironmentTelemetry.cpp +++ b/src/modules/Telemetry/EnvironmentTelemetry.cpp @@ -25,6 +25,7 @@ #include "Sensor/BMP280Sensor.h" #include "Sensor/LPS22HBSensor.h" #include "Sensor/MCP9808Sensor.h" +#include "Sensor/MLX90632Sensor.h" #include "Sensor/OPT3001Sensor.h" #include "Sensor/RCWL9620Sensor.h" #include "Sensor/SHT31Sensor.h" @@ -47,6 +48,7 @@ OPT3001Sensor opt3001Sensor; SHT4XSensor sht4xSensor; RCWL9620Sensor rcwl9620Sensor; AHT10Sensor aht10Sensor; +MLX90632Sensor mlx90632Sensor; #define FAILED_STATE_SENSOR_READ_MULTIPLIER 10 #define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true @@ -117,6 +119,8 @@ int32_t EnvironmentTelemetryModule::runOnce() result = rcwl9620Sensor.runOnce(); if (aht10Sensor.hasSensor()) result = aht10Sensor.runOnce(); + if (mlx90632Sensor.hasSensor()) + result = mlx90632Sensor.runOnce(); } return result; } else { @@ -307,6 +311,10 @@ bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly) valid = valid && opt3001Sensor.getMetrics(&m); hasSensor = true; } + if (mlx90632Sensor.hasSensor()) { + valid = valid && mlx90632Sensor.getMetrics(&m); + hasSensor = true; + } if (rcwl9620Sensor.hasSensor()) { valid = valid && rcwl9620Sensor.getMetrics(&m); hasSensor = true; diff --git a/src/modules/Telemetry/Sensor/MLX90632Sensor.cpp b/src/modules/Telemetry/Sensor/MLX90632Sensor.cpp new file mode 100644 index 000000000..4c459c365 --- /dev/null +++ b/src/modules/Telemetry/Sensor/MLX90632Sensor.cpp @@ -0,0 +1,40 @@ +#include "configuration.h" + +#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR + +#include "../mesh/generated/meshtastic/telemetry.pb.h" +#include "MLX90632Sensor.h" +#include "TelemetrySensor.h" + +MLX90632Sensor::MLX90632Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_MLX90632, "MLX90632") {} + +int32_t MLX90632Sensor::runOnce() +{ + LOG_INFO("Init sensor: %s\n", sensorName); + if (!hasSensor()) { + return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; + } + + MLX90632::status returnError; + if (mlx.begin(nodeTelemetrySensorsMap[sensorType].first, *nodeTelemetrySensorsMap[sensorType].second, returnError) == + true) // MLX90632 init + { + LOG_DEBUG("MLX90632 Init Succeed\n"); + status = true; + } else { + LOG_ERROR("MLX90632 Init Failed\n"); + status = false; + } + return initI2CSensor(); +} + +void MLX90632Sensor::setup() {} + +bool MLX90632Sensor::getMetrics(meshtastic_Telemetry *measurement) +{ + measurement->variant.environment_metrics.temperature = mlx.getObjectTemp(); // Get the object temperature in Fahrenheit + + return true; +} + +#endif \ No newline at end of file diff --git a/src/modules/Telemetry/Sensor/MLX90632Sensor.h b/src/modules/Telemetry/Sensor/MLX90632Sensor.h new file mode 100644 index 000000000..7b36c44cd --- /dev/null +++ b/src/modules/Telemetry/Sensor/MLX90632Sensor.h @@ -0,0 +1,23 @@ +#include "configuration.h" + +#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR + +#include "../mesh/generated/meshtastic/telemetry.pb.h" +#include "TelemetrySensor.h" +#include + +class MLX90632Sensor : public TelemetrySensor +{ + private: + MLX90632 mlx = MLX90632(); + + protected: + virtual void setup() override; + + public: + MLX90632Sensor(); + virtual int32_t runOnce() override; + virtual bool getMetrics(meshtastic_Telemetry *measurement) override; +}; + +#endif \ No newline at end of file From b551c8b59222ef7010ab1aad454a77d0767456fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Mon, 3 Jun 2024 14:00:58 +0200 Subject: [PATCH 22/80] update Radiolib to 6.6.0 --- platformio.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index 968a37d9b..e8eff024d 100644 --- a/platformio.ini +++ b/platformio.ini @@ -74,7 +74,7 @@ build_flags = -Wno-missing-field-initializers monitor_speed = 115200 lib_deps = - jgromes/RadioLib@~6.5.0 + jgromes/RadioLib@~6.6.0 https://github.com/meshtastic/esp8266-oled-ssd1306.git#ee628ee6c9588d4c56c9e3da35f0fc9448ad54a8 ; ESP8266_SSD1306 mathertel/OneButton@^2.5.0 ; OneButton library for non-blocking button debounce https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159 @@ -138,4 +138,4 @@ lib_deps = adafruit/Adafruit SHT4x Library@^1.0.4 adafruit/Adafruit TSL2591 Library@^1.4.5 ClosedCube OPT3001@^1.1.2 - emotibit/EmotiBit MLX90632@^1.0.8 \ No newline at end of file + emotibit/EmotiBit MLX90632@^1.0.8 From 79333c85a3372243a89f41266de7d7123894afd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Mon, 3 Jun 2024 16:34:19 +0200 Subject: [PATCH 23/80] tryfix bme some more --- src/modules/Telemetry/Sensor/BME680Sensor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/Telemetry/Sensor/BME680Sensor.cpp b/src/modules/Telemetry/Sensor/BME680Sensor.cpp index 71da39043..411cbbf69 100644 --- a/src/modules/Telemetry/Sensor/BME680Sensor.cpp +++ b/src/modules/Telemetry/Sensor/BME680Sensor.cpp @@ -57,7 +57,7 @@ bool BME680Sensor::getMetrics(meshtastic_Telemetry *measurement) measurement->variant.environment_metrics.temperature = bme680.getData(BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE).signal; measurement->variant.environment_metrics.relative_humidity = bme680.getData(BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY).signal; - measurement->variant.environment_metrics.barometric_pressure = bme680.getData(BSEC_OUTPUT_RAW_PRESSURE).signal / 100.0F; + measurement->variant.environment_metrics.barometric_pressure = bme680.getData(BSEC_OUTPUT_RAW_PRESSURE).signal; measurement->variant.environment_metrics.gas_resistance = bme680.getData(BSEC_OUTPUT_RAW_GAS).signal / 1000.0; // Check if we need to save state to filesystem (every STATE_SAVE_PERIOD ms) measurement->variant.environment_metrics.iaq = bme680.getData(BSEC_OUTPUT_IAQ).signal; From 7cbfe7aa541014cf882aa71ebe34c2fb7a78518a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 15:59:39 -0500 Subject: [PATCH 24/80] [create-pull-request] automated change (#4029) Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com> --- protobufs | 2 +- src/mesh/generated/meshtastic/telemetry.pb.h | 33 +++++++++++++++----- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/protobufs b/protobufs index a45a6154d..bfbf4a65e 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit a45a6154d0721027bf63f85cfc5abd9f6fab2422 +Subproject commit bfbf4a65e220581f45c5ed949c659953ac4d080f diff --git a/src/mesh/generated/meshtastic/telemetry.pb.h b/src/mesh/generated/meshtastic/telemetry.pb.h index f0ff9bed0..02b0bdd6d 100644 --- a/src/mesh/generated/meshtastic/telemetry.pb.h +++ b/src/mesh/generated/meshtastic/telemetry.pb.h @@ -59,7 +59,9 @@ typedef enum _meshtastic_TelemetrySensorType { /* AMS TSL25911FN RGB Light Sensor */ meshtastic_TelemetrySensorType_TSL25911FN = 22, /* AHT10 Integrated temperature and humidity sensor */ - meshtastic_TelemetrySensorType_AHT10 = 23 + meshtastic_TelemetrySensorType_AHT10 = 23, + /* DFRobot Lark Weather station (temperature, humidity, pressure, wind speed and direction) */ + meshtastic_TelemetrySensorType_DFROBOT_LARK = 24 } meshtastic_TelemetrySensorType; /* Struct definitions */ @@ -100,6 +102,15 @@ typedef struct _meshtastic_EnvironmentMetrics { float lux; /* VEML7700 high accuracy white light(irradiance) not calibrated digital 16-bit resolution sensor. */ float white_lux; + /* Infrared lux */ + float ir_lux; + /* Ultraviolet lux */ + float uv_lux; + /* Wind direction in degrees + 0 degrees = North, 90 = East, etc... */ + uint16_t wind_direction; + /* Wind speed in m/s */ + float wind_speed; } meshtastic_EnvironmentMetrics; /* Power Metrics (voltage / current / etc) */ @@ -170,8 +181,8 @@ extern "C" { /* Helper constants for enums */ #define _meshtastic_TelemetrySensorType_MIN meshtastic_TelemetrySensorType_SENSOR_UNSET -#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_AHT10 -#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_AHT10+1)) +#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_DFROBOT_LARK +#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_DFROBOT_LARK+1)) @@ -181,12 +192,12 @@ extern "C" { /* Initializer values for message structs */ #define meshtastic_DeviceMetrics_init_default {0, 0, 0, 0, 0} -#define meshtastic_EnvironmentMetrics_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +#define meshtastic_EnvironmentMetrics_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_PowerMetrics_init_default {0, 0, 0, 0, 0, 0} #define meshtastic_AirQualityMetrics_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_Telemetry_init_default {0, 0, {meshtastic_DeviceMetrics_init_default}} #define meshtastic_DeviceMetrics_init_zero {0, 0, 0, 0, 0} -#define meshtastic_EnvironmentMetrics_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +#define meshtastic_EnvironmentMetrics_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_PowerMetrics_init_zero {0, 0, 0, 0, 0, 0} #define meshtastic_AirQualityMetrics_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_Telemetry_init_zero {0, 0, {meshtastic_DeviceMetrics_init_zero}} @@ -207,6 +218,10 @@ extern "C" { #define meshtastic_EnvironmentMetrics_distance_tag 8 #define meshtastic_EnvironmentMetrics_lux_tag 9 #define meshtastic_EnvironmentMetrics_white_lux_tag 10 +#define meshtastic_EnvironmentMetrics_ir_lux_tag 11 +#define meshtastic_EnvironmentMetrics_uv_lux_tag 12 +#define meshtastic_EnvironmentMetrics_wind_direction_tag 13 +#define meshtastic_EnvironmentMetrics_wind_speed_tag 14 #define meshtastic_PowerMetrics_ch1_voltage_tag 1 #define meshtastic_PowerMetrics_ch1_current_tag 2 #define meshtastic_PowerMetrics_ch2_voltage_tag 3 @@ -251,7 +266,11 @@ X(a, STATIC, SINGULAR, FLOAT, current, 6) \ X(a, STATIC, SINGULAR, UINT32, iaq, 7) \ X(a, STATIC, SINGULAR, FLOAT, distance, 8) \ X(a, STATIC, SINGULAR, FLOAT, lux, 9) \ -X(a, STATIC, SINGULAR, FLOAT, white_lux, 10) +X(a, STATIC, SINGULAR, FLOAT, white_lux, 10) \ +X(a, STATIC, SINGULAR, FLOAT, ir_lux, 11) \ +X(a, STATIC, SINGULAR, FLOAT, uv_lux, 12) \ +X(a, STATIC, SINGULAR, UINT32, wind_direction, 13) \ +X(a, STATIC, SINGULAR, FLOAT, wind_speed, 14) #define meshtastic_EnvironmentMetrics_CALLBACK NULL #define meshtastic_EnvironmentMetrics_DEFAULT NULL @@ -311,7 +330,7 @@ extern const pb_msgdesc_t meshtastic_Telemetry_msg; #define MESHTASTIC_MESHTASTIC_TELEMETRY_PB_H_MAX_SIZE meshtastic_Telemetry_size #define meshtastic_AirQualityMetrics_size 72 #define meshtastic_DeviceMetrics_size 27 -#define meshtastic_EnvironmentMetrics_size 49 +#define meshtastic_EnvironmentMetrics_size 68 #define meshtastic_PowerMetrics_size 30 #define meshtastic_Telemetry_size 79 From b43c7c0f23690a966c899bb91463861db9b54365 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Mon, 3 Jun 2024 23:04:40 +0200 Subject: [PATCH 25/80] LR1110 support (#3013) * DOES NOT WORK * trunk * DOES NOT WORK * trunk * DOES NOT WORK * trunk * WIP: LR11x0 non functional interface code. Please don't expect a working firmware out of this! I don't know what i am doing! :-) * trunk fmt * use canon toolchain * update and fix radiolib dependency * Switch Radiolib back to GIT checkout * enable tcxo and fix startReceive * progress * Correct midjudgement on scope of build defines. * - enable peripheral power rail during startup init - fix portduino builds * add tracker pinout variant * update to radiolib 6.6.0 API (aka: godmode is not for mere mortals) * tracker is not so 'extra' any more --------- Co-authored-by: Ben Meadors --- boards/wio-sdk-wm1110.json | 58 ++++ boards/wio-tracker-wm1110.json | 58 ++++ src/detect/LoRaRadioType.h | 13 +- src/main.cpp | 28 ++ src/mesh/InterfacesTemplates.cpp | 4 + src/mesh/LR1110Interface.cpp | 9 + src/mesh/LR1110Interface.h | 13 + src/mesh/LR1120Interface.cpp | 9 + src/mesh/LR1120Interface.h | 13 + src/mesh/LR11x0Interface.cpp | 299 +++++++++++++++++++++ src/mesh/LR11x0Interface.h | 71 +++++ src/platform/nrf52/architecture.h | 2 + variants/wio-sdk-wm1110/platformio.ini | 15 ++ variants/wio-sdk-wm1110/variant.cpp | 45 ++++ variants/wio-sdk-wm1110/variant.h | 111 ++++++++ variants/wio-tracker-wm1110/platformio.ini | 14 + variants/wio-tracker-wm1110/variant.cpp | 45 ++++ variants/wio-tracker-wm1110/variant.h | 111 ++++++++ 18 files changed, 917 insertions(+), 1 deletion(-) create mode 100644 boards/wio-sdk-wm1110.json create mode 100644 boards/wio-tracker-wm1110.json create mode 100644 src/mesh/LR1110Interface.cpp create mode 100644 src/mesh/LR1110Interface.h create mode 100644 src/mesh/LR1120Interface.cpp create mode 100644 src/mesh/LR1120Interface.h create mode 100644 src/mesh/LR11x0Interface.cpp create mode 100644 src/mesh/LR11x0Interface.h create mode 100644 variants/wio-sdk-wm1110/platformio.ini create mode 100644 variants/wio-sdk-wm1110/variant.cpp create mode 100644 variants/wio-sdk-wm1110/variant.h create mode 100644 variants/wio-tracker-wm1110/platformio.ini create mode 100644 variants/wio-tracker-wm1110/variant.cpp create mode 100644 variants/wio-tracker-wm1110/variant.h diff --git a/boards/wio-sdk-wm1110.json b/boards/wio-sdk-wm1110.json new file mode 100644 index 000000000..029c9c085 --- /dev/null +++ b/boards/wio-sdk-wm1110.json @@ -0,0 +1,58 @@ +{ + "build": { + "arduino": { + "ldscript": "nrf52840_s140_v6.ld" + }, + "core": "nRF5", + "cpu": "cortex-m4", + "extra_flags": "-DARDUINO_WIO_WM1110 -DNRF52840_XXAA", + "f_cpu": "64000000L", + "hwids": [ + ["0x239A", "0x8029"], + ["0x239A", "0x0029"], + ["0x239A", "0x002A"], + ["0x239A", "0x802A"] + ], + "usb_product": "WIO-BOOT", + "mcu": "nrf52840", + "variant": "Seeed_WIO_WM1110", + "bsp": { + "name": "adafruit" + }, + "softdevice": { + "sd_flags": "-DS140", + "sd_name": "s140", + "sd_version": "6.1.1", + "sd_fwid": "0x00B6" + }, + "bootloader": { + "settings_addr": "0xFF000" + } + }, + "connectivity": ["bluetooth"], + "debug": { + "jlink_device": "nRF52840_xxAA", + "svd_path": "nrf52840.svd" + }, + "frameworks": ["arduino"], + "name": "Seeed WIO WM1110", + "upload": { + "maximum_ram_size": 248832, + "maximum_size": 815104, + "speed": 115200, + "protocol": "nrfutil", + "protocols": [ + "jlink", + "nrfjprog", + "nrfutil", + "stlink", + "cmsis-dap", + "blackmagic" + ], + "use_1200bps_touch": true, + "require_upload_port": true, + "wait_for_upload_port": true + }, + "url": "https://www.seeedstudio.com/Wio-WM1110-Dev-Kit-p-5677.html", + "vendor": "Seeed Studio" +} diff --git a/boards/wio-tracker-wm1110.json b/boards/wio-tracker-wm1110.json new file mode 100644 index 000000000..029c9c085 --- /dev/null +++ b/boards/wio-tracker-wm1110.json @@ -0,0 +1,58 @@ +{ + "build": { + "arduino": { + "ldscript": "nrf52840_s140_v6.ld" + }, + "core": "nRF5", + "cpu": "cortex-m4", + "extra_flags": "-DARDUINO_WIO_WM1110 -DNRF52840_XXAA", + "f_cpu": "64000000L", + "hwids": [ + ["0x239A", "0x8029"], + ["0x239A", "0x0029"], + ["0x239A", "0x002A"], + ["0x239A", "0x802A"] + ], + "usb_product": "WIO-BOOT", + "mcu": "nrf52840", + "variant": "Seeed_WIO_WM1110", + "bsp": { + "name": "adafruit" + }, + "softdevice": { + "sd_flags": "-DS140", + "sd_name": "s140", + "sd_version": "6.1.1", + "sd_fwid": "0x00B6" + }, + "bootloader": { + "settings_addr": "0xFF000" + } + }, + "connectivity": ["bluetooth"], + "debug": { + "jlink_device": "nRF52840_xxAA", + "svd_path": "nrf52840.svd" + }, + "frameworks": ["arduino"], + "name": "Seeed WIO WM1110", + "upload": { + "maximum_ram_size": 248832, + "maximum_size": 815104, + "speed": 115200, + "protocol": "nrfutil", + "protocols": [ + "jlink", + "nrfjprog", + "nrfutil", + "stlink", + "cmsis-dap", + "blackmagic" + ], + "use_1200bps_touch": true, + "require_upload_port": true, + "wait_for_upload_port": true + }, + "url": "https://www.seeedstudio.com/Wio-WM1110-Dev-Kit-p-5677.html", + "vendor": "Seeed Studio" +} diff --git a/src/detect/LoRaRadioType.h b/src/detect/LoRaRadioType.h index eadd92e64..3975153b5 100644 --- a/src/detect/LoRaRadioType.h +++ b/src/detect/LoRaRadioType.h @@ -1,5 +1,16 @@ #pragma once -enum LoRaRadioType { NO_RADIO, STM32WLx_RADIO, SIM_RADIO, RF95_RADIO, SX1262_RADIO, SX1268_RADIO, LLCC68_RADIO, SX1280_RADIO }; +enum LoRaRadioType { + NO_RADIO, + STM32WLx_RADIO, + SIM_RADIO, + RF95_RADIO, + SX1262_RADIO, + SX1268_RADIO, + LLCC68_RADIO, + SX1280_RADIO, + LR1110_RADIO, + LR1120_RADIO +}; extern LoRaRadioType radioType; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 3c1893690..52de93e83 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -65,6 +65,8 @@ NRF52Bluetooth *nrf52Bluetooth; #endif #include "LLCC68Interface.h" +#include "LR1110Interface.h" +#include "LR1120Interface.h" #include "RF95Interface.h" #include "SX1262Interface.h" #include "SX1268Interface.h" @@ -882,6 +884,32 @@ void setup() } #endif +#if defined(USE_LR1110) + if (!rIf) { + rIf = new LR1110Interface(RadioLibHAL, LR1110_SPI_NSS_PIN, LR1110_IRQ_PIN, LR1110_NRESER_PIN, LR1110_BUSY_PIN); + if (!rIf->init()) { + LOG_WARN("Failed to find LR1110 radio\n"); + delete rIf; + rIf = NULL; + } else { + LOG_INFO("LR1110 Radio init succeeded, using LR1110 radio\n"); + } + } +#endif + +#if defined(USE_LR1120) + if (!rIf) { + rIf = new LR1120Interface(RadioLibHAL, LR1120_SPI_NSS_PIN, LR1120_IRQ_PIN, LR1120_NRESER_PIN, LR1120_BUSY_PIN); + if (!rIf->init()) { + LOG_WARN("Failed to find LR1120 radio\n"); + delete rIf; + rIf = NULL; + } else { + LOG_INFO("LR1120 Radio init succeeded, using LR1120 radio\n"); + } + } +#endif + #if defined(USE_SX1280) if (!rIf) { rIf = new SX1280Interface(RadioLibHAL, SX128X_CS, SX128X_DIO1, SX128X_RESET, SX128X_BUSY); diff --git a/src/mesh/InterfacesTemplates.cpp b/src/mesh/InterfacesTemplates.cpp index c732829e9..f2cac8028 100644 --- a/src/mesh/InterfacesTemplates.cpp +++ b/src/mesh/InterfacesTemplates.cpp @@ -1,3 +1,5 @@ +#include "LR11x0Interface.cpp" +#include "LR11x0Interface.h" #include "SX126xInterface.cpp" #include "SX126xInterface.h" #include "SX128xInterface.cpp" @@ -10,6 +12,8 @@ template class SX126xInterface; template class SX126xInterface; template class SX126xInterface; template class SX128xInterface; +template class LR11x0Interface; +template class LR11x0Interface; #ifdef ARCH_STM32WL template class SX126xInterface; #endif diff --git a/src/mesh/LR1110Interface.cpp b/src/mesh/LR1110Interface.cpp new file mode 100644 index 000000000..c000bd838 --- /dev/null +++ b/src/mesh/LR1110Interface.cpp @@ -0,0 +1,9 @@ +#include "LR1110Interface.h" +#include "configuration.h" +#include "error.h" + +LR1110Interface::LR1110Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, + RADIOLIB_PIN_TYPE busy) + : LR11x0Interface(hal, cs, irq, rst, busy) +{ +} \ No newline at end of file diff --git a/src/mesh/LR1110Interface.h b/src/mesh/LR1110Interface.h new file mode 100644 index 000000000..79e7c36ca --- /dev/null +++ b/src/mesh/LR1110Interface.h @@ -0,0 +1,13 @@ +#pragma once + +#include "LR11x0Interface.h" + +/** + * Our adapter for LR1110 radios + */ +class LR1110Interface : public LR11x0Interface +{ + public: + LR1110Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, + RADIOLIB_PIN_TYPE busy); +}; \ No newline at end of file diff --git a/src/mesh/LR1120Interface.cpp b/src/mesh/LR1120Interface.cpp new file mode 100644 index 000000000..94f3568f7 --- /dev/null +++ b/src/mesh/LR1120Interface.cpp @@ -0,0 +1,9 @@ +#include "LR1120Interface.h" +#include "configuration.h" +#include "error.h" + +LR1120Interface::LR1120Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, + RADIOLIB_PIN_TYPE busy) + : LR11x0Interface(hal, cs, irq, rst, busy) +{ +} \ No newline at end of file diff --git a/src/mesh/LR1120Interface.h b/src/mesh/LR1120Interface.h new file mode 100644 index 000000000..fc59293ec --- /dev/null +++ b/src/mesh/LR1120Interface.h @@ -0,0 +1,13 @@ +#pragma once + +#include "LR11x0Interface.h" + +/** + * Our adapter for LR1120 wideband radios + */ +class LR1120Interface : public LR11x0Interface +{ + public: + LR1120Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, + RADIOLIB_PIN_TYPE busy); +}; \ No newline at end of file diff --git a/src/mesh/LR11x0Interface.cpp b/src/mesh/LR11x0Interface.cpp new file mode 100644 index 000000000..bffca0c44 --- /dev/null +++ b/src/mesh/LR11x0Interface.cpp @@ -0,0 +1,299 @@ +#include "LR11x0Interface.h" +#include "configuration.h" +#include "error.h" +#include "mesh/NodeDB.h" +#ifdef ARCH_PORTDUINO +#include "PortduinoGlue.h" +#endif + +// Particular boards might define a different max power based on what their hardware can do, default to max power output if not +// specified (may be dangerous if using external PA and LR11x0 power config forgotten) +#ifndef LR11X0_MAX_POWER +#define LR11X0_MAX_POWER 22 +#endif + +template +LR11x0Interface::LR11x0Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, + RADIOLIB_PIN_TYPE busy) + : RadioLibInterface(hal, cs, irq, rst, busy, &lora), lora(&module) +{ + LOG_WARN("LR11x0Interface(cs=%d, irq=%d, rst=%d, busy=%d)\n", cs, irq, rst, busy); +} + +/// Initialise the Driver transport hardware and software. +/// Make sure the Driver is properly configured before calling init(). +/// \return true if initialisation succeeded. +template bool LR11x0Interface::init() +{ +#ifdef LR11X0_POWER_EN + pinMode(LR11X0_POWER_EN, OUTPUT); + digitalWrite(LR11X0_POWER_EN, HIGH); +#endif + +// FIXME: correct logic to default to not using TCXO if no voltage is specified for LR11x0_DIO3_TCXO_VOLTAGE +#if !defined(LR11X0_DIO3_TCXO_VOLTAGE) + float tcxoVoltage = + 0; // "TCXO reference voltage to be set on DIO3. Defaults to 1.6 V, set to 0 to skip." per + // https://github.com/jgromes/RadioLib/blob/690a050ebb46e6097c5d00c371e961c1caa3b52e/src/modules/LR11x0/LR11x0.h#L471C26-L471C104 + // (DIO3 is free to be used as an IRQ) + LOG_DEBUG("LR11X0_DIO3_TCXO_VOLTAGE not defined, not using DIO3 as TCXO reference voltage\n"); +#else + float tcxoVoltage = LR11X0_DIO3_TCXO_VOLTAGE; + LOG_DEBUG("LR11X0_DIO3_TCXO_VOLTAGE defined, using DIO3 as TCXO reference voltage at %f V\n", LR11X0_DIO3_TCXO_VOLTAGE); + // (DIO3 is not free to be used as an IRQ) +#endif + + RadioLibInterface::init(); + + if (power > LR11X0_MAX_POWER) // Clamp power to maximum defined level + power = LR11X0_MAX_POWER; + + limitPower(); + + // set RF switch configuration for Wio WM1110 + // Wio WM1110 uses DIO5 and DIO6 for RF switching + // NOTE: other boards may be different. If you are + // using a different board, you may need to wrap + // this in a conditional. + + static const uint32_t rfswitch_dio_pins[] = {RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, RADIOLIB_NC, RADIOLIB_NC, + RADIOLIB_NC}; + + static const Module::RfSwitchMode_t rfswitch_table[] = { + // mode DIO5 DIO6 + {LR11x0::MODE_STBY, {LOW, LOW}}, {LR11x0::MODE_RX, {HIGH, LOW}}, + {LR11x0::MODE_TX, {HIGH, HIGH}}, {LR11x0::MODE_TX_HP, {LOW, HIGH}}, + {LR11x0::MODE_TX_HF, {LOW, LOW}}, {LR11x0::MODE_GNSS, {LOW, LOW}}, + {LR11x0::MODE_WIFI, {LOW, LOW}}, END_OF_MODE_TABLE, + }; + +// We need to do this before begin() call +#ifdef LR11X0_DIO_AS_RF_SWITCH + LOG_DEBUG("Setting DIO RF switch\n"); + bool dioAsRfSwitch = true; +#elif defined(ARCH_PORTDUINO) + bool dioAsRfSwitch = false; + if (settingsMap[dio2_as_rf_switch]) { + LOG_DEBUG("Setting DIO RF switch\n"); + dioAsRfSwitch = true; + } +#else + bool dioAsRfSwitch = false; +#endif + + if (dioAsRfSwitch) + lora.setRfSwitchTable(rfswitch_dio_pins, rfswitch_table); + + int res = lora.begin(getFreq(), bw, sf, cr, syncWord, power, preambleLength, tcxoVoltage); + // \todo Display actual typename of the adapter, not just `LR11x0` + LOG_INFO("LR11x0 init result %d\n", res); + if (res == RADIOLIB_ERR_CHIP_NOT_FOUND) + return false; + + LOG_INFO("Frequency set to %f\n", getFreq()); + LOG_INFO("Bandwidth set to %f\n", bw); + LOG_INFO("Power output set to %d\n", power); + + if (res == RADIOLIB_ERR_NONE) + res = lora.setCRC(2); + + // FIXME: May want to set depending on a definition, currently all LR1110 variant files use the DC-DC regulator option + if (res == RADIOLIB_ERR_NONE) + res = lora.setRegulatorDCDC(); + + if (res == RADIOLIB_ERR_NONE) { + if (config.lora.sx126x_rx_boosted_gain) { // the name is unfortunate but historically accurate + res = lora.setRxBoostedGainMode(true); + LOG_INFO("Set RX gain to boosted mode; result: %d\n", res); + } else { + res = lora.setRxBoostedGainMode(false); + LOG_INFO("Set RX gain to power saving mode (boosted mode off); result: %d\n", res); + } + } + + if (res == RADIOLIB_ERR_NONE) + startReceive(); // start receiving + + return res == RADIOLIB_ERR_NONE; +} + +template bool LR11x0Interface::reconfigure() +{ + RadioLibInterface::reconfigure(); + + // set mode to standby + setStandby(); + + // configure publicly accessible settings + int err = lora.setSpreadingFactor(sf); + if (err != RADIOLIB_ERR_NONE) + RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING); + + err = lora.setBandwidth(bw); + if (err != RADIOLIB_ERR_NONE) + RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING); + + err = lora.setCodingRate(cr); + if (err != RADIOLIB_ERR_NONE) + RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING); + + // Hmm - seems to lower SNR when the signal levels are high. Leaving off for now... + // TODO: Confirm gain registers are okay now + // err = lora.setRxGain(true); + // assert(err == RADIOLIB_ERR_NONE); + + err = lora.setSyncWord(syncWord); + assert(err == RADIOLIB_ERR_NONE); + + err = lora.setPreambleLength(preambleLength); + assert(err == RADIOLIB_ERR_NONE); + + err = lora.setFrequency(getFreq()); + if (err != RADIOLIB_ERR_NONE) + RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_INVALID_RADIO_SETTING); + + if (power > LR11X0_MAX_POWER) // This chip has lower power limits than some + power = LR11X0_MAX_POWER; + + err = lora.setOutputPower(power); + assert(err == RADIOLIB_ERR_NONE); + + startReceive(); // restart receiving + + return RADIOLIB_ERR_NONE; +} + +template void INTERRUPT_ATTR LR11x0Interface::disableInterrupt() +{ + lora.clearIrqAction(); +} + +template void LR11x0Interface::setStandby() +{ + checkNotification(); // handle any pending interrupts before we force standby + + int err = lora.standby(); + + if (err != RADIOLIB_ERR_NONE) { + LOG_DEBUG("LR11x0 standby failed with error %d\n", err); + } + + assert(err == RADIOLIB_ERR_NONE); + + isReceiving = false; // If we were receiving, not any more + activeReceiveStart = 0; + disableInterrupt(); + completeSending(); // If we were sending, not anymore +} + +/** + * Add SNR data to received messages + */ +template void LR11x0Interface::addReceiveMetadata(meshtastic_MeshPacket *mp) +{ + // LOG_DEBUG("PacketStatus %x\n", lora.getPacketStatus()); + mp->rx_snr = lora.getSNR(); + mp->rx_rssi = lround(lora.getRSSI()); +} + +/** We override to turn on transmitter power as needed. + */ +template void LR11x0Interface::configHardwareForSend() +{ + RadioLibInterface::configHardwareForSend(); +} + +// For power draw measurements, helpful to force radio to stay sleeping +// #define SLEEP_ONLY + +template void LR11x0Interface::startReceive() +{ +#ifdef SLEEP_ONLY + sleep(); +#else + + setStandby(); + + lora.setPreambleLength(preambleLength); // Solve RX ack fail after direct message sent. Not sure why this is needed. + + // We use a 16 bit preamble so this should save some power by letting radio sit in standby mostly. + // Furthermore, we need the PREAMBLE_DETECTED and HEADER_VALID IRQ flag to detect whether we are actively receiving + int err = lora.startReceive( + RADIOLIB_LR11X0_RX_TIMEOUT_INF, RADIOLIB_LR11X0_IRQ_RX_DONE, + 0); // only RX_DONE IRQ is needed, we'll check for PREAMBLE_DETECTED and HEADER_VALID in isActivelyReceiving + assert(err == RADIOLIB_ERR_NONE); + + isReceiving = true; + + // Must be done AFTER, starting transmit, because startTransmit clears (possibly stale) interrupt pending register bits + enableInterrupt(isrRxLevel0); +#endif +} + +/** Is the channel currently active? */ +template bool LR11x0Interface::isChannelActive() +{ + // check if we can detect a LoRa preamble on the current channel + int16_t result; + + setStandby(); + result = lora.scanChannel(); + if (result == RADIOLIB_LORA_DETECTED) + return true; + + assert(result != RADIOLIB_ERR_WRONG_MODEM); + + return false; +} + +/** Could we send right now (i.e. either not actively receiving or transmitting)? */ +template bool LR11x0Interface::isActivelyReceiving() +{ + // The IRQ status will be cleared when we start our read operation. Check if we've started a header, but haven't yet + // received and handled the interrupt for reading the packet/handling errors. + + uint16_t irq = lora.getIrqStatus(); + bool detected = (irq & (RADIOLIB_LR11X0_IRQ_SYNC_WORD_HEADER_VALID | RADIOLIB_LR11X0_IRQ_PREAMBLE_DETECTED)); + // Handle false detections + if (detected) { + uint32_t now = millis(); + if (!activeReceiveStart) { + activeReceiveStart = now; + } else if ((now - activeReceiveStart > 2 * preambleTimeMsec) && !(irq & RADIOLIB_LR11X0_IRQ_SYNC_WORD_HEADER_VALID)) { + // The HEADER_VALID flag should be set by now if it was really a packet, so ignore PREAMBLE_DETECTED flag + activeReceiveStart = 0; + LOG_DEBUG("Ignore false preamble detection.\n"); + return false; + } else if (now - activeReceiveStart > maxPacketTimeMsec) { + // We should have gotten an RX_DONE IRQ by now if it was really a packet, so ignore HEADER_VALID flag + activeReceiveStart = 0; + LOG_DEBUG("Ignore false header detection.\n"); + return false; + } + } + + // if (detected) LOG_DEBUG("rx detected\n"); + return detected; +} + +template bool LR11x0Interface::sleep() +{ + // Not keeping config is busted - next time nrf52 board boots lora sending fails tcxo related? - see datasheet + // \todo Display actual typename of the adapter, not just `LR11x0` + LOG_DEBUG("LR11x0 entering sleep mode (FIXME, don't keep config)\n"); + setStandby(); // Stop any pending operations + + // turn off TCXO if it was powered + // FIXME - this isn't correct + // lora.setTCXO(0); + + // put chipset into sleep mode (we've already disabled interrupts by now) + bool keepConfig = true; + lora.sleep(keepConfig, 0); // Note: we do not keep the config, full reinit will be needed + +#ifdef LR11X0_POWER_EN + digitalWrite(LR11X0_POWER_EN, LOW); +#endif + + return true; +} \ No newline at end of file diff --git a/src/mesh/LR11x0Interface.h b/src/mesh/LR11x0Interface.h new file mode 100644 index 000000000..11a389d25 --- /dev/null +++ b/src/mesh/LR11x0Interface.h @@ -0,0 +1,71 @@ +#pragma once + +#include "RadioLibInterface.h" + +/** + * \brief Adapter for LR11x0 radio family. Implements common logic for child classes. + * \tparam T RadioLib module type for LR11x0: SX1262, SX1268. + */ +template class LR11x0Interface : public RadioLibInterface +{ + public: + LR11x0Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, + RADIOLIB_PIN_TYPE busy); + + /// Initialise the Driver transport hardware and software. + /// Make sure the Driver is properly configured before calling init(). + /// \return true if initialisation succeeded. + virtual bool init() override; + + /// Apply any radio provisioning changes + /// Make sure the Driver is properly configured before calling init(). + /// \return true if initialisation succeeded. + virtual bool reconfigure() override; + + /// Prepare hardware for sleep. Call this _only_ for deep sleep, not needed for light sleep. + virtual bool sleep() override; + + bool isIRQPending() override { return lora.getIrqStatus() != 0; } + + protected: + /** + * Specific module instance + */ + T lora; + + /** + * Glue functions called from ISR land + */ + virtual void disableInterrupt() override; + + /** + * Enable a particular ISR callback glue function + */ + virtual void enableInterrupt(void (*callback)()) { lora.setIrqAction(callback); } + + /** can we detect a LoRa preamble on the current channel? */ + virtual bool isChannelActive() override; + + /** are we actively receiving a packet (only called during receiving state) */ + virtual bool isActivelyReceiving() override; + + /** + * Start waiting to receive a message + */ + virtual void startReceive() override; + + /** + * We override to turn on transmitter power as needed. + */ + virtual void configHardwareForSend() override; + + /** + * Add SNR data to received messages + */ + virtual void addReceiveMetadata(meshtastic_MeshPacket *mp) override; + + virtual void setStandby() override; + + private: + uint32_t activeReceiveStart = 0; +}; diff --git a/src/platform/nrf52/architecture.h b/src/platform/nrf52/architecture.h index 68bd87801..b91c57c5e 100644 --- a/src/platform/nrf52/architecture.h +++ b/src/platform/nrf52/architecture.h @@ -56,6 +56,8 @@ #define HW_VENDOR meshtastic_HardwareModel_TWC_MESH_V4 #elif defined(NRF52_PROMICRO_DIY) #define HW_VENDOR meshtastic_HardwareModel_NRF52_PROMICRO_DIY +#elif defined(WIO_WM1110) +#define HW_VENDOR meshtastic_HardwareModel_PRIVATE_HW #elif defined(PRIVATE_HW) || defined(FEATHER_DIY) #define HW_VENDOR meshtastic_HardwareModel_PRIVATE_HW #else diff --git a/variants/wio-sdk-wm1110/platformio.ini b/variants/wio-sdk-wm1110/platformio.ini new file mode 100644 index 000000000..8b1433dd1 --- /dev/null +++ b/variants/wio-sdk-wm1110/platformio.ini @@ -0,0 +1,15 @@ +; The very slick RAK wireless RAK 4631 / 4630 board - Unified firmware for 5005/19003, with or without OLED RAK 1921 +[env:wio-sdk-wm1110] +extends = nrf52840_base +board = wio-sdk-wm1110 +board_level = extra +; platform = https://github.com/maxgerhardt/platform-nordicnrf52#cac6fcf943a41accd2aeb4f3659ae297a73f422e +build_flags = ${nrf52840_base.build_flags} -Ivariants/wio-sdk-wm1110 -DWIO_WM1110 + -L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m4/fpv4-sp-d16-hard" + -DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely. +build_src_filter = ${nrf52_base.build_src_filter} +<../variants/wio-sdk-wm1110> +lib_deps = + ${nrf52840_base.lib_deps} +debug_tool = jlink +; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm) +upload_protocol = jlink \ No newline at end of file diff --git a/variants/wio-sdk-wm1110/variant.cpp b/variants/wio-sdk-wm1110/variant.cpp new file mode 100644 index 000000000..5a3587982 --- /dev/null +++ b/variants/wio-sdk-wm1110/variant.cpp @@ -0,0 +1,45 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + Copyright (c) 2016 Sandeep Mistry All right reserved. + Copyright (c) 2018, Adafruit Industries (adafruit.com) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "variant.h" +#include "nrf.h" +#include "wiring_constants.h" +#include "wiring_digital.h" + +const uint32_t g_ADigitalPinMap[] = { + // P0 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + + // P1 + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47}; + +void initVariant() +{ + // LED1 & LED2 + pinMode(PIN_LED1, OUTPUT); + ledOff(PIN_LED1); + + pinMode(PIN_LED2, OUTPUT); + ledOff(PIN_LED2); + + // 3V3 Power Rail + pinMode(PIN_3V3_EN, OUTPUT); + digitalWrite(PIN_3V3_EN, HIGH); +} \ No newline at end of file diff --git a/variants/wio-sdk-wm1110/variant.h b/variants/wio-sdk-wm1110/variant.h new file mode 100644 index 000000000..f027b469f --- /dev/null +++ b/variants/wio-sdk-wm1110/variant.h @@ -0,0 +1,111 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + Copyright (c) 2016 Sandeep Mistry All right reserved. + Copyright (c) 2018, Adafruit Industries (adafruit.com) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _VARIANT_WIO_SDK_WM1110_ +#define _VARIANT_WIO_SDK_WM1110_ + +/** Master clock frequency */ +#define VARIANT_MCK (64000000ul) + +#define USE_LFXO // Board uses 32khz crystal for LF +// define USE_LFRC // Board uses RC for LF + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +// Number of pins defined in PinDescription array +#define PINS_COUNT (48) +#define NUM_DIGITAL_PINS (48) +#define NUM_ANALOG_INPUTS (6) +#define NUM_ANALOG_OUTPUTS (0) + +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_3V3_EN (0 + 7) // P0.7, Power to Sensors + +#define PIN_WIRE_SDA (0 + 27) // P0.27 +#define PIN_WIRE_SCL (0 + 26) // P0.26 + +#define PIN_LED1 (0 + 13) // P0.13 +#define PIN_LED2 (0 + 14) // P0.14 + +#define LED_BUILTIN PIN_LED1 + +#define LED_GREEN PIN_LED1 +#define LED_BLUE PIN_LED2 // Actually red + +#define LED_STATE_ON 1 // State when LED is lit + +#define BUTTON_PIN (0 + 23) // P0.23 + +/* + * Serial interfaces + */ +#define PIN_SERIAL1_RX (0 + 22) // P0.22 +#define PIN_SERIAL1_TX (0 + 24) // P0.24 + +#define PIN_SERIAL2_RX (0 + 6) // P0.06 +#define PIN_SERIAL2_TX (0 + 8) // P0.08 + +#define SPI_INTERFACES_COUNT 1 + +#define PIN_SPI_MISO (32 + 15) // P1.15 47 +#define PIN_SPI_MOSI (32 + 14) // P1.14 46 +#define PIN_SPI_SCK (32 + 13) // P1.13 45 +#define PIN_SPI_NSS (32 + 12) // P1.12 44 + +#define LORA_RESET (32 + 10) // P1.10 42 // RST +#define LORA_DIO1 (32 + 8) // P1.08 40 // IRQ +#define LORA_DIO2 (32 + 11) // P1.11 43 // BUSY +#define LORA_SCK PIN_SPI_SCK +#define LORA_MISO PIN_SPI_MISO +#define LORA_MOSI PIN_SPI_MOSI +#define LORA_CS PIN_SPI_NSS + +// supported modules list +#define USE_LR1110 + +#define LR1110_IRQ_PIN LORA_DIO1 +#define LR1110_NRESER_PIN LORA_RESET +#define LR1110_BUSY_PIN LORA_DIO2 +#define LR1110_SPI_NSS_PIN LORA_CS +#define LR1110_SPI_SCK_PIN LORA_SCK +#define LR1110_SPI_MOSI_PIN LORA_MOSI +#define LR1110_SPI_MISO_PIN LORA_MISO + +#define LR11X0_DIO3_TCXO_VOLTAGE 1.6 +#define LR11X0_DIO_AS_RF_SWITCH + +#define LR1110_GNSS_ANT_PIN (32 + 5) // P1.05 37 + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#endif // _VARIANT_WIO_SDK_WM1110_ diff --git a/variants/wio-tracker-wm1110/platformio.ini b/variants/wio-tracker-wm1110/platformio.ini new file mode 100644 index 000000000..cba1b8741 --- /dev/null +++ b/variants/wio-tracker-wm1110/platformio.ini @@ -0,0 +1,14 @@ +; The very slick RAK wireless RAK 4631 / 4630 board - Unified firmware for 5005/19003, with or without OLED RAK 1921 +[env:wio-tracker-wm1110] +extends = nrf52840_base +board = wio-tracker-wm1110 +; platform = https://github.com/maxgerhardt/platform-nordicnrf52#cac6fcf943a41accd2aeb4f3659ae297a73f422e +build_flags = ${nrf52840_base.build_flags} -Ivariants/wio-tracker-wm1110 -DWIO_WM1110 + -L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m4/fpv4-sp-d16-hard" + -DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely. +build_src_filter = ${nrf52_base.build_src_filter} +<../variants/wio-tracker-wm1110> +lib_deps = + ${nrf52840_base.lib_deps} +debug_tool = jlink +; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm) +;upload_protocol = jlink \ No newline at end of file diff --git a/variants/wio-tracker-wm1110/variant.cpp b/variants/wio-tracker-wm1110/variant.cpp new file mode 100644 index 000000000..5a3587982 --- /dev/null +++ b/variants/wio-tracker-wm1110/variant.cpp @@ -0,0 +1,45 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + Copyright (c) 2016 Sandeep Mistry All right reserved. + Copyright (c) 2018, Adafruit Industries (adafruit.com) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "variant.h" +#include "nrf.h" +#include "wiring_constants.h" +#include "wiring_digital.h" + +const uint32_t g_ADigitalPinMap[] = { + // P0 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + + // P1 + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47}; + +void initVariant() +{ + // LED1 & LED2 + pinMode(PIN_LED1, OUTPUT); + ledOff(PIN_LED1); + + pinMode(PIN_LED2, OUTPUT); + ledOff(PIN_LED2); + + // 3V3 Power Rail + pinMode(PIN_3V3_EN, OUTPUT); + digitalWrite(PIN_3V3_EN, HIGH); +} \ No newline at end of file diff --git a/variants/wio-tracker-wm1110/variant.h b/variants/wio-tracker-wm1110/variant.h new file mode 100644 index 000000000..e929332e6 --- /dev/null +++ b/variants/wio-tracker-wm1110/variant.h @@ -0,0 +1,111 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + Copyright (c) 2016 Sandeep Mistry All right reserved. + Copyright (c) 2018, Adafruit Industries (adafruit.com) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _VARIANT_WIO_TRACKER_WM1110_ +#define _VARIANT_WIO_TRACKER_WM1110_ + +/** Master clock frequency */ +#define VARIANT_MCK (64000000ul) + +#define USE_LFXO // Board uses 32khz crystal for LF +// define USE_LFRC // Board uses RC for LF + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +// Number of pins defined in PinDescription array +#define PINS_COUNT (48) +#define NUM_DIGITAL_PINS (48) +#define NUM_ANALOG_INPUTS (6) +#define NUM_ANALOG_OUTPUTS (0) + +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_3V3_EN (32 + 1) // P1.01, Power to Sensors + +#define PIN_WIRE_SDA (0 + 5) // P0.05 +#define PIN_WIRE_SCL (0 + 4) // P0.04 + +#define PIN_LED1 (0 + 6) // P0.06 +#define PIN_LED2 (PINS_COUNT) // P0.14 + +#define LED_BUILTIN PIN_LED1 + +#define LED_GREEN PIN_LED1 +#define LED_BLUE PIN_LED2 + +#define LED_STATE_ON 0 + +#define BUTTON_PIN (32 + 2) // P1.02 + +/* + * Serial interfaces + */ +#define PIN_SERIAL1_RX (0 + 24) // P0.24 +#define PIN_SERIAL1_TX (0 + 25) // P0.25 + +#define PIN_SERIAL2_RX (0 + 6) // P0.06 +#define PIN_SERIAL2_TX (0 + 8) // P0.08 + +#define SPI_INTERFACES_COUNT 1 + +#define PIN_SPI_MISO (32 + 15) // P1.15 47 +#define PIN_SPI_MOSI (32 + 14) // P1.14 46 +#define PIN_SPI_SCK (32 + 13) // P1.13 45 +#define PIN_SPI_NSS (32 + 12) // P1.12 44 + +#define LORA_RESET (0 + 18) // P0.18 18 // RST +#define LORA_DIO1 (0 + 2) // P0.02 2 // IRQ +#define LORA_DIO2 (32 + 11) // P1.11 43 // BUSY +#define LORA_SCK PIN_SPI_SCK +#define LORA_MISO PIN_SPI_MISO +#define LORA_MOSI PIN_SPI_MOSI +#define LORA_CS PIN_SPI_NSS + +// supported modules list +#define USE_LR1110 + +#define LR1110_IRQ_PIN LORA_DIO1 +#define LR1110_NRESER_PIN LORA_RESET +#define LR1110_BUSY_PIN LORA_DIO2 +#define LR1110_SPI_NSS_PIN LORA_CS +#define LR1110_SPI_SCK_PIN LORA_SCK +#define LR1110_SPI_MOSI_PIN LORA_MOSI +#define LR1110_SPI_MISO_PIN LORA_MISO + +#define LR11X0_DIO3_TCXO_VOLTAGE 1.6 +#define LR11X0_DIO_AS_RF_SWITCH + +#define LR1110_GNSS_ANT_PIN (32 + 5) // P1.05 37 + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#endif // _VARIANT_WIO_TRACKER_WM1110_ From a218c6fb4d42abc867bac2e588ae274462c658b0 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Mon, 3 Jun 2024 21:50:28 -0500 Subject: [PATCH 26/80] DFRobot Lark weather station support (#4032) * DF Robot Lark weather station support * Missed it * I am a man of const char sorrow... * Strang * Use our fork --- platformio.ini | 2 + src/configuration.h | 1 + src/detect/ScanI2C.h | 1 + src/detect/ScanI2CTwoWire.cpp | 5 +- src/gps/GeoCoord.cpp | 88 +++++++++++++++++++ src/gps/GeoCoord.h | 2 + src/main.cpp | 1 + .../Telemetry/EnvironmentTelemetry.cpp | 17 +++- .../Telemetry/Sensor/DFRobotLarkSensor.cpp | 53 +++++++++++ .../Telemetry/Sensor/DFRobotLarkSensor.h | 24 +++++ 10 files changed, 191 insertions(+), 3 deletions(-) create mode 100644 src/modules/Telemetry/Sensor/DFRobotLarkSensor.cpp create mode 100644 src/modules/Telemetry/Sensor/DFRobotLarkSensor.h diff --git a/platformio.ini b/platformio.ini index e8eff024d..85bce3279 100644 --- a/platformio.ini +++ b/platformio.ini @@ -139,3 +139,5 @@ lib_deps = adafruit/Adafruit TSL2591 Library@^1.4.5 ClosedCube OPT3001@^1.1.2 emotibit/EmotiBit MLX90632@^1.0.8 + dfrobot/DFRobot_RTU@^1.0.3 + https://github.com/meshtastic/DFRobot_LarkWeatherStation#0e884fc86b7a0b602c7ff3d26b893b997f15c6ac \ No newline at end of file diff --git a/src/configuration.h b/src/configuration.h index 744406f18..462210cf2 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -135,6 +135,7 @@ along with this program. If not, see . #define OPT3001_ADDR 0x45 #define OPT3001_ADDR_ALT 0x44 #define MLX90632_ADDR 0x3A +#define DFROBOT_LARK_ADDR 0x42 // ----------------------------------------------------------------------------- // ACCELEROMETER diff --git a/src/detect/ScanI2C.h b/src/detect/ScanI2C.h index a90d9218a..13dd66763 100644 --- a/src/detect/ScanI2C.h +++ b/src/detect/ScanI2C.h @@ -49,6 +49,7 @@ class ScanI2C OPT3001, MLX90632, AHT10, + DFROBOT_LARK, } DeviceType; // typedef uint8_t DeviceAddress; diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index 3aeb8560e..86099ad19 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -281,8 +281,9 @@ void ScanI2CTwoWire::scanPort(I2CPort port) if (registerValue == 0x5449) { LOG_INFO("INA3221 sensor found at address 0x%x\n", (uint8_t)addr.address); type = INA3221; - } else { // Unknown device - LOG_INFO("No INA3221 found at address 0x%x\n", (uint8_t)addr.address); + } else { + LOG_INFO("DFRobot Lark weather station found at address 0x%x\n", (uint8_t)addr.address); + type = DFROBOT_LARK; } break; case MCP9808_ADDR: diff --git a/src/gps/GeoCoord.cpp b/src/gps/GeoCoord.cpp index cb4e69ff2..2224bd281 100644 --- a/src/gps/GeoCoord.cpp +++ b/src/gps/GeoCoord.cpp @@ -486,3 +486,91 @@ std::shared_ptr GeoCoord::pointAtDistance(double bearing, double range return std::make_shared(double(lat), double(lon), this->getAltitude()); } + +/** + * Convert bearing to degrees + * @param bearing + * The bearing in string format + * @return Bearing in degrees + */ +uint GeoCoord::bearingToDegrees(const char *bearing) +{ + if (strcmp(bearing, "N") == 0) + return 0; + else if (strcmp(bearing, "NNE") == 0) + return 22; + else if (strcmp(bearing, "NE") == 0) + return 45; + else if (strcmp(bearing, "ENE") == 0) + return 67; + else if (strcmp(bearing, "E") == 0) + return 90; + else if (strcmp(bearing, "ESE") == 0) + return 112; + else if (strcmp(bearing, "SE") == 0) + return 135; + else if (strcmp(bearing, "SSE") == 0) + return 157; + else if (strcmp(bearing, "S") == 0) + return 180; + else if (strcmp(bearing, "SSW") == 0) + return 202; + else if (strcmp(bearing, "SW") == 0) + return 225; + else if (strcmp(bearing, "WSW") == 0) + return 247; + else if (strcmp(bearing, "W") == 0) + return 270; + else if (strcmp(bearing, "WNW") == 0) + return 292; + else if (strcmp(bearing, "NW") == 0) + return 315; + else if (strcmp(bearing, "NNW") == 0) + return 337; + else + return 0; +} + +/** + * Convert bearing to string + * @param degrees + * The bearing in degrees + * @return Bearing in string format + */ +const char *GeoCoord::degreesToBearing(uint degrees) +{ + if (degrees >= 348 || degrees < 11) + return "N"; + else if (degrees >= 11 && degrees < 34) + return "NNE"; + else if (degrees >= 34 && degrees < 56) + return "NE"; + else if (degrees >= 56 && degrees < 79) + return "ENE"; + else if (degrees >= 79 && degrees < 101) + return "E"; + else if (degrees >= 101 && degrees < 124) + return "ESE"; + else if (degrees >= 124 && degrees < 146) + return "SE"; + else if (degrees >= 146 && degrees < 169) + return "SSE"; + else if (degrees >= 169 && degrees < 191) + return "S"; + else if (degrees >= 191 && degrees < 214) + return "SSW"; + else if (degrees >= 214 && degrees < 236) + return "SW"; + else if (degrees >= 236 && degrees < 259) + return "WSW"; + else if (degrees >= 259 && degrees < 281) + return "W"; + else if (degrees >= 281 && degrees < 304) + return "WNW"; + else if (degrees >= 304 && degrees < 326) + return "NW"; + else if (degrees >= 326 && degrees < 348) + return "NNW"; + else + return "N"; +} diff --git a/src/gps/GeoCoord.h b/src/gps/GeoCoord.h index e811035db..b02d12afb 100644 --- a/src/gps/GeoCoord.h +++ b/src/gps/GeoCoord.h @@ -117,6 +117,8 @@ class GeoCoord static float bearing(double lat1, double lon1, double lat2, double lon2); static float rangeRadiansToMeters(double range_radians); static float rangeMetersToRadians(double range_meters); + static uint bearingToDegrees(const char *bearing); + static const char *degreesToBearing(uint degrees); // Point to point conversions int32_t distanceTo(const GeoCoord &pointB); diff --git a/src/main.cpp b/src/main.cpp index 52de93e83..6797c8375 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -540,6 +540,7 @@ void setup() SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::MLX90632, meshtastic_TelemetrySensorType_MLX90632) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::SHT4X, meshtastic_TelemetrySensorType_SHT4X) SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::AHT10, meshtastic_TelemetrySensorType_AHT10) + SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::DFROBOT_LARK, meshtastic_TelemetrySensorType_DFROBOT_LARK) i2cScanner.reset(); diff --git a/src/modules/Telemetry/EnvironmentTelemetry.cpp b/src/modules/Telemetry/EnvironmentTelemetry.cpp index 9032389c5..8972a8e3f 100644 --- a/src/modules/Telemetry/EnvironmentTelemetry.cpp +++ b/src/modules/Telemetry/EnvironmentTelemetry.cpp @@ -23,6 +23,7 @@ #include "Sensor/BME680Sensor.h" #include "Sensor/BMP085Sensor.h" #include "Sensor/BMP280Sensor.h" +#include "Sensor/DFRobotLarkSensor.h" #include "Sensor/LPS22HBSensor.h" #include "Sensor/MCP9808Sensor.h" #include "Sensor/MLX90632Sensor.h" @@ -49,6 +50,7 @@ SHT4XSensor sht4xSensor; RCWL9620Sensor rcwl9620Sensor; AHT10Sensor aht10Sensor; MLX90632Sensor mlx90632Sensor; +DFRobotLarkSensor dfRobotLarkSensor; #define FAILED_STATE_SENSOR_READ_MULTIPLIER 10 #define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true @@ -72,7 +74,7 @@ int32_t EnvironmentTelemetryModule::runOnce() // moduleConfig.telemetry.environment_measurement_enabled = 1; // moduleConfig.telemetry.environment_screen_enabled = 1; - // moduleConfig.telemetry.environment_update_interval = 45; + // moduleConfig.telemetry.environment_update_interval = 15; if (!(moduleConfig.telemetry.environment_measurement_enabled || moduleConfig.telemetry.environment_screen_enabled)) { // If this module is not enabled, and the user doesn't want the display screen don't waste any OSThread time on it @@ -87,6 +89,8 @@ int32_t EnvironmentTelemetryModule::runOnce() LOG_INFO("Environment Telemetry: Initializing\n"); // it's possible to have this module enabled, only for displaying values on the screen. // therefore, we should only enable the sensor loop if measurement is also enabled + if (dfRobotLarkSensor.hasSensor()) + result = dfRobotLarkSensor.runOnce(); if (bmp085Sensor.hasSensor()) result = bmp085Sensor.runOnce(); if (bmp280Sensor.hasSensor()) @@ -240,6 +244,10 @@ bool EnvironmentTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPac t->variant.environment_metrics.temperature); LOG_INFO("(Received from %s): voltage=%f, IAQ=%d, distance=%f, lux=%f\n", sender, t->variant.environment_metrics.voltage, t->variant.environment_metrics.iaq, t->variant.environment_metrics.distance, t->variant.environment_metrics.lux); + + LOG_INFO("(Received from %s): wind speed=%fm/s, direction=%d degrees\n", sender, + t->variant.environment_metrics.wind_speed, t->variant.environment_metrics.wind_direction); + #endif // release previous packet before occupying a new spot if (lastMeasurementPacket != nullptr) @@ -259,6 +267,10 @@ bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly) m.time = getTime(); m.which_variant = meshtastic_Telemetry_environment_metrics_tag; + if (dfRobotLarkSensor.hasSensor()) { + valid = valid && dfRobotLarkSensor.getMetrics(&m); + hasSensor = true; + } if (sht31Sensor.hasSensor()) { valid = valid && sht31Sensor.getMetrics(&m); hasSensor = true; @@ -342,6 +354,9 @@ bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly) LOG_INFO("(Sending): voltage=%f, IAQ=%d, distance=%f, lux=%f\n", m.variant.environment_metrics.voltage, m.variant.environment_metrics.iaq, m.variant.environment_metrics.distance, m.variant.environment_metrics.lux); + LOG_INFO("(Sending): wind speed=%fm/s, direction=%d degrees\n", m.variant.environment_metrics.wind_speed, + m.variant.environment_metrics.wind_direction); + sensor_read_error_count = 0; meshtastic_MeshPacket *p = allocDataProtobuf(m); diff --git a/src/modules/Telemetry/Sensor/DFRobotLarkSensor.cpp b/src/modules/Telemetry/Sensor/DFRobotLarkSensor.cpp new file mode 100644 index 000000000..830552023 --- /dev/null +++ b/src/modules/Telemetry/Sensor/DFRobotLarkSensor.cpp @@ -0,0 +1,53 @@ +#include "configuration.h" + +#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR + +#include "../mesh/generated/meshtastic/telemetry.pb.h" +#include "DFRobotLarkSensor.h" +#include "TelemetrySensor.h" +#include "gps/GeoCoord.h" +#include +#include + +DFRobotLarkSensor::DFRobotLarkSensor() : TelemetrySensor(meshtastic_TelemetrySensorType_DFROBOT_LARK, "DFROBOT_LARK") {} + +int32_t DFRobotLarkSensor::runOnce() +{ + LOG_INFO("Init sensor: %s\n", sensorName); + if (!hasSensor()) { + return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; + } + + lark = DFRobot_LarkWeatherStation_I2C(nodeTelemetrySensorsMap[sensorType].first, nodeTelemetrySensorsMap[sensorType].second); + + if (lark.begin() == 0) // DFRobotLarkSensor init + { + LOG_DEBUG("DFRobotLarkSensor Init Succeed\n"); + status = true; + } else { + LOG_ERROR("DFRobotLarkSensor Init Failed\n"); + status = false; + } + return initI2CSensor(); +} + +void DFRobotLarkSensor::setup() {} + +bool DFRobotLarkSensor::getMetrics(meshtastic_Telemetry *measurement) +{ + measurement->variant.environment_metrics.temperature = lark.getValue("Temp").toFloat(); + measurement->variant.environment_metrics.relative_humidity = lark.getValue("Humi").toFloat(); + measurement->variant.environment_metrics.wind_speed = lark.getValue("Speed").toFloat(); + measurement->variant.environment_metrics.wind_direction = GeoCoord::bearingToDegrees(lark.getValue("Dir").c_str()); + measurement->variant.environment_metrics.barometric_pressure = lark.getValue("Pressure").toFloat(); + + LOG_INFO("Temperature: %f\n", measurement->variant.environment_metrics.temperature); + LOG_INFO("Humidity: %f\n", measurement->variant.environment_metrics.relative_humidity); + LOG_INFO("Wind Speed: %f\n", measurement->variant.environment_metrics.wind_speed); + LOG_INFO("Wind Direction: %d\n", measurement->variant.environment_metrics.wind_direction); + LOG_INFO("Barometric Pressure: %f\n", measurement->variant.environment_metrics.barometric_pressure); + + return true; +} + +#endif \ No newline at end of file diff --git a/src/modules/Telemetry/Sensor/DFRobotLarkSensor.h b/src/modules/Telemetry/Sensor/DFRobotLarkSensor.h new file mode 100644 index 000000000..b26d690b1 --- /dev/null +++ b/src/modules/Telemetry/Sensor/DFRobotLarkSensor.h @@ -0,0 +1,24 @@ +#include "configuration.h" + +#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR + +#include "../mesh/generated/meshtastic/telemetry.pb.h" +#include "TelemetrySensor.h" +#include +#include + +class DFRobotLarkSensor : public TelemetrySensor +{ + private: + DFRobot_LarkWeatherStation_I2C lark = DFRobot_LarkWeatherStation_I2C(); + + protected: + virtual void setup() override; + + public: + DFRobotLarkSensor(); + virtual int32_t runOnce() override; + virtual bool getMetrics(meshtastic_Telemetry *measurement) override; +}; + +#endif \ No newline at end of file From 9632e4c405069cfccf23b4cf274af14c169c6ea0 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Tue, 4 Jun 2024 07:04:25 -0500 Subject: [PATCH 27/80] Add missing excludes to environmental sensors (#4033) * DF Robot Lark weather station support * Missed it * I am a man of const char sorrow... * Strang * Use our fork * Add excludes --- src/modules/Telemetry/Sensor/AHT10.cpp | 12 +++++++++--- src/modules/Telemetry/Sensor/AHT10.h | 6 ++++++ src/modules/Telemetry/Sensor/TSL2591Sensor.cpp | 13 +++++++++---- src/modules/Telemetry/Sensor/TSL2591Sensor.h | 7 ++++++- src/modules/Telemetry/Sensor/VEML7700Sensor.cpp | 11 ++++++++--- src/modules/Telemetry/Sensor/VEML7700Sensor.h | 7 ++++++- 6 files changed, 44 insertions(+), 12 deletions(-) diff --git a/src/modules/Telemetry/Sensor/AHT10.cpp b/src/modules/Telemetry/Sensor/AHT10.cpp index 985515bb6..a5212b39b 100644 --- a/src/modules/Telemetry/Sensor/AHT10.cpp +++ b/src/modules/Telemetry/Sensor/AHT10.cpp @@ -1,7 +1,11 @@ -#include "AHT10.h" -#include "../mesh/generated/meshtastic/telemetry.pb.h" -#include "TelemetrySensor.h" #include "configuration.h" + +#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR + +#include "../mesh/generated/meshtastic/telemetry.pb.h" +#include "AHT10.h" +#include "TelemetrySensor.h" + #include #include @@ -33,3 +37,5 @@ bool AHT10Sensor::getMetrics(meshtastic_Telemetry *measurement) return true; } + +#endif \ No newline at end of file diff --git a/src/modules/Telemetry/Sensor/AHT10.h b/src/modules/Telemetry/Sensor/AHT10.h index b2b7b47f3..d9a133402 100644 --- a/src/modules/Telemetry/Sensor/AHT10.h +++ b/src/modules/Telemetry/Sensor/AHT10.h @@ -1,3 +1,7 @@ +#include "configuration.h" + +#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR + #include "../mesh/generated/meshtastic/telemetry.pb.h" #include "TelemetrySensor.h" #include @@ -15,3 +19,5 @@ class AHT10Sensor : public TelemetrySensor virtual int32_t runOnce() override; virtual bool getMetrics(meshtastic_Telemetry *measurement) override; }; + +#endif \ No newline at end of file diff --git a/src/modules/Telemetry/Sensor/TSL2591Sensor.cpp b/src/modules/Telemetry/Sensor/TSL2591Sensor.cpp index 0a3f5d685..d20e48dce 100644 --- a/src/modules/Telemetry/Sensor/TSL2591Sensor.cpp +++ b/src/modules/Telemetry/Sensor/TSL2591Sensor.cpp @@ -1,7 +1,10 @@ -#include "TSL2591Sensor.h" -#include "../mesh/generated/meshtastic/telemetry.pb.h" -#include "TelemetrySensor.h" #include "configuration.h" + +#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR + +#include "../mesh/generated/meshtastic/telemetry.pb.h" +#include "TSL2591Sensor.h" +#include "TelemetrySensor.h" #include #include @@ -35,4 +38,6 @@ bool TSL2591Sensor::getMetrics(meshtastic_Telemetry *measurement) LOG_INFO("Lux: %f\n", measurement->variant.environment_metrics.lux); return true; -} \ No newline at end of file +} + +#endif \ No newline at end of file diff --git a/src/modules/Telemetry/Sensor/TSL2591Sensor.h b/src/modules/Telemetry/Sensor/TSL2591Sensor.h index a24d53975..27bebdfe5 100644 --- a/src/modules/Telemetry/Sensor/TSL2591Sensor.h +++ b/src/modules/Telemetry/Sensor/TSL2591Sensor.h @@ -1,3 +1,7 @@ +#include "configuration.h" + +#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR + #include "../mesh/generated/meshtastic/telemetry.pb.h" #include "TelemetrySensor.h" #include @@ -14,4 +18,5 @@ class TSL2591Sensor : public TelemetrySensor TSL2591Sensor(); virtual int32_t runOnce() override; virtual bool getMetrics(meshtastic_Telemetry *measurement) override; -}; \ No newline at end of file +}; +#endif \ No newline at end of file diff --git a/src/modules/Telemetry/Sensor/VEML7700Sensor.cpp b/src/modules/Telemetry/Sensor/VEML7700Sensor.cpp index 1abe8339f..cbeaf4c2e 100644 --- a/src/modules/Telemetry/Sensor/VEML7700Sensor.cpp +++ b/src/modules/Telemetry/Sensor/VEML7700Sensor.cpp @@ -1,7 +1,11 @@ -#include "VEML7700Sensor.h" +#include "configuration.h" + +#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR + #include "../mesh/generated/meshtastic/telemetry.pb.h" #include "TelemetrySensor.h" -#include "configuration.h" +#include "VEML7700Sensor.h" + #include #include @@ -57,4 +61,5 @@ bool VEML7700Sensor::getMetrics(meshtastic_Telemetry *measurement) measurement->variant.environment_metrics.lux); return true; -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/src/modules/Telemetry/Sensor/VEML7700Sensor.h b/src/modules/Telemetry/Sensor/VEML7700Sensor.h index 9c7a584d9..97e57334c 100644 --- a/src/modules/Telemetry/Sensor/VEML7700Sensor.h +++ b/src/modules/Telemetry/Sensor/VEML7700Sensor.h @@ -1,3 +1,7 @@ +#include "configuration.h" + +#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR + #include "../mesh/generated/meshtastic/telemetry.pb.h" #include "TelemetrySensor.h" #include @@ -19,4 +23,5 @@ class VEML7700Sensor : public TelemetrySensor VEML7700Sensor(); virtual int32_t runOnce() override; virtual bool getMetrics(meshtastic_Telemetry *measurement) override; -}; \ No newline at end of file +}; +#endif \ No newline at end of file From 181f03cb9538fea30cf00ff155dc5298881190f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 4 Jun 2024 15:14:27 +0200 Subject: [PATCH 28/80] tryfix random values (#4034) --- src/modules/Telemetry/AirQualityTelemetry.cpp | 2 +- src/modules/Telemetry/DeviceTelemetry.cpp | 2 +- src/modules/Telemetry/EnvironmentTelemetry.cpp | 4 ++-- src/modules/Telemetry/PowerTelemetry.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/modules/Telemetry/AirQualityTelemetry.cpp b/src/modules/Telemetry/AirQualityTelemetry.cpp index e4f31ff9f..4f5fbcd13 100644 --- a/src/modules/Telemetry/AirQualityTelemetry.cpp +++ b/src/modules/Telemetry/AirQualityTelemetry.cpp @@ -92,7 +92,7 @@ bool AirQualityTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly) return false; } - meshtastic_Telemetry m; + meshtastic_Telemetry m = meshtastic_Telemetry_init_zero; m.time = getTime(); m.which_variant = meshtastic_Telemetry_air_quality_metrics_tag; m.variant.air_quality_metrics.pm10_standard = data.pm10_standard; diff --git a/src/modules/Telemetry/DeviceTelemetry.cpp b/src/modules/Telemetry/DeviceTelemetry.cpp index 002ce62a9..b64e8d113 100644 --- a/src/modules/Telemetry/DeviceTelemetry.cpp +++ b/src/modules/Telemetry/DeviceTelemetry.cpp @@ -64,7 +64,7 @@ meshtastic_MeshPacket *DeviceTelemetryModule::allocReply() meshtastic_Telemetry DeviceTelemetryModule::getDeviceTelemetry() { - meshtastic_Telemetry t; + meshtastic_Telemetry t = meshtastic_Telemetry_init_zero; t.time = getTime(); t.which_variant = meshtastic_Telemetry_device_metrics_tag; diff --git a/src/modules/Telemetry/EnvironmentTelemetry.cpp b/src/modules/Telemetry/EnvironmentTelemetry.cpp index 8972a8e3f..46b8a1ad8 100644 --- a/src/modules/Telemetry/EnvironmentTelemetry.cpp +++ b/src/modules/Telemetry/EnvironmentTelemetry.cpp @@ -261,7 +261,7 @@ bool EnvironmentTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPac bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly) { - meshtastic_Telemetry m; + meshtastic_Telemetry m = meshtastic_Telemetry_init_zero; bool valid = true; bool hasSensor = false; m.time = getTime(); @@ -337,7 +337,7 @@ bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly) hasSensor = true; } else { // prefer bmp280 temp if both sensors are present, fetch only humidity - meshtastic_Telemetry m_ahtx; + meshtastic_Telemetry m_ahtx = meshtastic_Telemetry_init_zero; LOG_INFO("AHTX0+BMP280 module detected: using temp from BMP280 and humy from AHTX0\n"); aht10Sensor.getMetrics(&m_ahtx); m.variant.environment_metrics.relative_humidity = m_ahtx.variant.environment_metrics.relative_humidity; diff --git a/src/modules/Telemetry/PowerTelemetry.cpp b/src/modules/Telemetry/PowerTelemetry.cpp index e61a4e629..826de8a4a 100644 --- a/src/modules/Telemetry/PowerTelemetry.cpp +++ b/src/modules/Telemetry/PowerTelemetry.cpp @@ -165,7 +165,7 @@ bool PowerTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPacket &m bool PowerTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly) { - meshtastic_Telemetry m; + meshtastic_Telemetry m = meshtastic_Telemetry_init_zero; bool valid = false; m.time = getTime(); m.which_variant = meshtastic_Telemetry_power_metrics_tag; From 67b67a481f2756568feaa876006103fb8ba4dede Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 4 Jun 2024 08:34:38 -0500 Subject: [PATCH 29/80] [create-pull-request] automated change (#4035) --- protobufs | 2 +- src/mesh/generated/meshtastic/mesh.pb.cpp | 9 +++ src/mesh/generated/meshtastic/mesh.pb.h | 83 +++++++++++++++++++++++ 3 files changed, 93 insertions(+), 1 deletion(-) diff --git a/protobufs b/protobufs index bfbf4a65e..a641c5ce4 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit bfbf4a65e220581f45c5ed949c659953ac4d080f +Subproject commit a641c5ce4fca158d18ca3cffc92ac7a10f9b6a04 diff --git a/src/mesh/generated/meshtastic/mesh.pb.cpp b/src/mesh/generated/meshtastic/mesh.pb.cpp index 4907affc6..46d59d609 100644 --- a/src/mesh/generated/meshtastic/mesh.pb.cpp +++ b/src/mesh/generated/meshtastic/mesh.pb.cpp @@ -66,6 +66,15 @@ PB_BIND(meshtastic_Heartbeat, meshtastic_Heartbeat, AUTO) PB_BIND(meshtastic_NodeRemoteHardwarePin, meshtastic_NodeRemoteHardwarePin, AUTO) +PB_BIND(meshtastic_ChunkedPayload, meshtastic_ChunkedPayload, AUTO) + + +PB_BIND(meshtastic_resend_chunks, meshtastic_resend_chunks, AUTO) + + +PB_BIND(meshtastic_ChunkedPayloadResponse, meshtastic_ChunkedPayloadResponse, AUTO) + + diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h index 7b544d714..ad97cb80f 100644 --- a/src/mesh/generated/meshtastic/mesh.pb.h +++ b/src/mesh/generated/meshtastic/mesh.pb.h @@ -65,6 +65,8 @@ typedef enum _meshtastic_HardwareModel { meshtastic_HardwareModel_LORA_TYPE = 19, /* wiphone https://www.wiphone.io/ */ meshtastic_HardwareModel_WIPHONE = 20, + /* WIO Tracker WM1110 family from Seeed Studio. Includes wio-1110-tracker and wio-1110-sdk */ + meshtastic_HardwareModel_WIO_WM1110 = 21, /* B&Q Consulting Station Edition G1: https://uniteng.com/wiki/doku.php?id=meshtastic:station */ meshtastic_HardwareModel_STATION_G1 = 25, /* RAK11310 (RP2040 + SX1262) */ @@ -853,6 +855,38 @@ typedef struct _meshtastic_NodeRemoteHardwarePin { meshtastic_RemoteHardwarePin pin; } meshtastic_NodeRemoteHardwarePin; +typedef PB_BYTES_ARRAY_T(228) meshtastic_ChunkedPayload_payload_chunk_t; +typedef struct _meshtastic_ChunkedPayload { + /* The ID of the entire payload */ + uint32_t payload_id; + /* The total number of chunks in the payload */ + uint16_t chunk_count; + /* The current chunk index in the total */ + uint16_t chunk_index; + /* The binary data of the current chunk */ + meshtastic_ChunkedPayload_payload_chunk_t payload_chunk; +} meshtastic_ChunkedPayload; + +/* Wrapper message for broken repeated oneof support */ +typedef struct _meshtastic_resend_chunks { + pb_callback_t chunks; +} meshtastic_resend_chunks; + +/* Responses to a ChunkedPayload request */ +typedef struct _meshtastic_ChunkedPayloadResponse { + /* The ID of the entire payload */ + uint32_t payload_id; + pb_size_t which_payload_variant; + union { + /* Request to transfer chunked payload */ + bool request_transfer; + /* Accept the transfer chunked payload */ + bool accept_transfer; + /* Request missing indexes in the chunked payload */ + meshtastic_resend_chunks resend_chunks; + } payload_variant; +} meshtastic_ChunkedPayloadResponse; + #ifdef __cplusplus extern "C" { @@ -928,6 +962,9 @@ extern "C" { + + + /* Initializer values for message structs */ #define meshtastic_Position_init_default {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN, _meshtastic_Position_AltSource_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_User_init_default {"", "", "", {0}, _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN} @@ -949,6 +986,9 @@ extern "C" { #define meshtastic_DeviceMetadata_init_default {"", 0, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_Role_MIN, 0, _meshtastic_HardwareModel_MIN, 0} #define meshtastic_Heartbeat_init_default {0} #define meshtastic_NodeRemoteHardwarePin_init_default {0, false, meshtastic_RemoteHardwarePin_init_default} +#define meshtastic_ChunkedPayload_init_default {0, 0, 0, {0, {0}}} +#define meshtastic_resend_chunks_init_default {{{NULL}, NULL}} +#define meshtastic_ChunkedPayloadResponse_init_default {0, 0, {0}} #define meshtastic_Position_init_zero {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN, _meshtastic_Position_AltSource_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_User_init_zero {"", "", "", {0}, _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN} #define meshtastic_RouteDiscovery_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}} @@ -969,6 +1009,9 @@ extern "C" { #define meshtastic_DeviceMetadata_init_zero {"", 0, 0, 0, 0, 0, _meshtastic_Config_DeviceConfig_Role_MIN, 0, _meshtastic_HardwareModel_MIN, 0} #define meshtastic_Heartbeat_init_zero {0} #define meshtastic_NodeRemoteHardwarePin_init_zero {0, false, meshtastic_RemoteHardwarePin_init_zero} +#define meshtastic_ChunkedPayload_init_zero {0, 0, 0, {0, {0}}} +#define meshtastic_resend_chunks_init_zero {{{NULL}, NULL}} +#define meshtastic_ChunkedPayloadResponse_init_zero {0, 0, {0}} /* Field tags (for use in manual encoding/decoding) */ #define meshtastic_Position_latitude_i_tag 1 @@ -1103,6 +1146,15 @@ extern "C" { #define meshtastic_ToRadio_heartbeat_tag 7 #define meshtastic_NodeRemoteHardwarePin_node_num_tag 1 #define meshtastic_NodeRemoteHardwarePin_pin_tag 2 +#define meshtastic_ChunkedPayload_payload_id_tag 1 +#define meshtastic_ChunkedPayload_chunk_count_tag 2 +#define meshtastic_ChunkedPayload_chunk_index_tag 3 +#define meshtastic_ChunkedPayload_payload_chunk_tag 4 +#define meshtastic_resend_chunks_chunks_tag 1 +#define meshtastic_ChunkedPayloadResponse_payload_id_tag 1 +#define meshtastic_ChunkedPayloadResponse_request_transfer_tag 2 +#define meshtastic_ChunkedPayloadResponse_accept_transfer_tag 3 +#define meshtastic_ChunkedPayloadResponse_resend_chunks_tag 4 /* Struct field encoding specification for nanopb */ #define meshtastic_Position_FIELDLIST(X, a) \ @@ -1341,6 +1393,28 @@ X(a, STATIC, OPTIONAL, MESSAGE, pin, 2) #define meshtastic_NodeRemoteHardwarePin_DEFAULT NULL #define meshtastic_NodeRemoteHardwarePin_pin_MSGTYPE meshtastic_RemoteHardwarePin +#define meshtastic_ChunkedPayload_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UINT32, payload_id, 1) \ +X(a, STATIC, SINGULAR, UINT32, chunk_count, 2) \ +X(a, STATIC, SINGULAR, UINT32, chunk_index, 3) \ +X(a, STATIC, SINGULAR, BYTES, payload_chunk, 4) +#define meshtastic_ChunkedPayload_CALLBACK NULL +#define meshtastic_ChunkedPayload_DEFAULT NULL + +#define meshtastic_resend_chunks_FIELDLIST(X, a) \ +X(a, CALLBACK, REPEATED, UINT32, chunks, 1) +#define meshtastic_resend_chunks_CALLBACK pb_default_field_callback +#define meshtastic_resend_chunks_DEFAULT NULL + +#define meshtastic_ChunkedPayloadResponse_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UINT32, payload_id, 1) \ +X(a, STATIC, ONEOF, BOOL, (payload_variant,request_transfer,payload_variant.request_transfer), 2) \ +X(a, STATIC, ONEOF, BOOL, (payload_variant,accept_transfer,payload_variant.accept_transfer), 3) \ +X(a, STATIC, ONEOF, MESSAGE, (payload_variant,resend_chunks,payload_variant.resend_chunks), 4) +#define meshtastic_ChunkedPayloadResponse_CALLBACK NULL +#define meshtastic_ChunkedPayloadResponse_DEFAULT NULL +#define meshtastic_ChunkedPayloadResponse_payload_variant_resend_chunks_MSGTYPE meshtastic_resend_chunks + extern const pb_msgdesc_t meshtastic_Position_msg; extern const pb_msgdesc_t meshtastic_User_msg; extern const pb_msgdesc_t meshtastic_RouteDiscovery_msg; @@ -1361,6 +1435,9 @@ extern const pb_msgdesc_t meshtastic_Neighbor_msg; extern const pb_msgdesc_t meshtastic_DeviceMetadata_msg; extern const pb_msgdesc_t meshtastic_Heartbeat_msg; extern const pb_msgdesc_t meshtastic_NodeRemoteHardwarePin_msg; +extern const pb_msgdesc_t meshtastic_ChunkedPayload_msg; +extern const pb_msgdesc_t meshtastic_resend_chunks_msg; +extern const pb_msgdesc_t meshtastic_ChunkedPayloadResponse_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define meshtastic_Position_fields &meshtastic_Position_msg @@ -1383,9 +1460,15 @@ extern const pb_msgdesc_t meshtastic_NodeRemoteHardwarePin_msg; #define meshtastic_DeviceMetadata_fields &meshtastic_DeviceMetadata_msg #define meshtastic_Heartbeat_fields &meshtastic_Heartbeat_msg #define meshtastic_NodeRemoteHardwarePin_fields &meshtastic_NodeRemoteHardwarePin_msg +#define meshtastic_ChunkedPayload_fields &meshtastic_ChunkedPayload_msg +#define meshtastic_resend_chunks_fields &meshtastic_resend_chunks_msg +#define meshtastic_ChunkedPayloadResponse_fields &meshtastic_ChunkedPayloadResponse_msg /* Maximum encoded size of messages (where known) */ +/* meshtastic_resend_chunks_size depends on runtime parameters */ +/* meshtastic_ChunkedPayloadResponse_size depends on runtime parameters */ #define MESHTASTIC_MESHTASTIC_MESH_PB_H_MAX_SIZE meshtastic_FromRadio_size +#define meshtastic_ChunkedPayload_size 245 #define meshtastic_Compressed_size 243 #define meshtastic_Data_size 270 #define meshtastic_DeviceMetadata_size 46 From c37316e7237c50f8442de3b6ead35ed3605c5688 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 4 Jun 2024 15:44:48 +0200 Subject: [PATCH 30/80] use correct hardware tag for tracker and sdk (#4036) --- src/platform/nrf52/architecture.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/nrf52/architecture.h b/src/platform/nrf52/architecture.h index b91c57c5e..18a4d75f5 100644 --- a/src/platform/nrf52/architecture.h +++ b/src/platform/nrf52/architecture.h @@ -57,7 +57,7 @@ #elif defined(NRF52_PROMICRO_DIY) #define HW_VENDOR meshtastic_HardwareModel_NRF52_PROMICRO_DIY #elif defined(WIO_WM1110) -#define HW_VENDOR meshtastic_HardwareModel_PRIVATE_HW +#define HW_VENDOR meshtastic_HardwareModel_WIO_WM1110 #elif defined(PRIVATE_HW) || defined(FEATHER_DIY) #define HW_VENDOR meshtastic_HardwareModel_PRIVATE_HW #else From d0ca616c19028ae4609744d15f5fd340430265e5 Mon Sep 17 00:00:00 2001 From: jcyrio <50239349+jcyrio@users.noreply.github.com> Date: Tue, 4 Jun 2024 14:02:43 -0700 Subject: [PATCH 31/80] typo: 'our our' to 'of our' (#4037) --- src/graphics/Screen.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 15e69b1ed..1c9484f62 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -2071,7 +2071,7 @@ void Screen::setFrames() LOG_DEBUG("Total frame count: %d\n", totalFrameCount); #endif - // We don't show the node info our our node (if we have it yet - we should) + // We don't show the node info of our node (if we have it yet - we should) size_t numMeshNodes = nodeDB->getNumMeshNodes(); if (numMeshNodes > 0) numMeshNodes--; @@ -2708,4 +2708,4 @@ int Screen::handleInputEvent(const InputEvent *event) } // namespace graphics #else graphics::Screen::Screen(ScanI2C::DeviceAddress, meshtastic_Config_DisplayConfig_OledType, OLEDDISPLAY_GEOMETRY) {} -#endif // HAS_SCREEN +#endif // HAS_SCREEN \ No newline at end of file From fbc8f6c03b563a7673250fbdd942fe03c152e252 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Wed, 5 Jun 2024 15:08:23 +0200 Subject: [PATCH 32/80] package x86_64 meshtasticd --- .github/workflows/main_matrix.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index a768e5fd9..d2338c959 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -142,6 +142,7 @@ jobs: path: | release/device-*.sh release/device-*.bat + release/meshtasticd_linux* - name: Docker login if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }} @@ -217,7 +218,7 @@ jobs: id: version - name: Move files up - run: mv -b -t ./ ./release/meshtasticd_linux_aarch64 ./release/meshtasticd_linux_armv7l ./bin/config-dist.yaml + run: mv -b -t ./ ./release/meshtasticd_linux_* ./bin/config-dist.yaml - name: Repackage in single firmware zip uses: actions/upload-artifact@v4 From 2cc5598f8992074d7ebf5602719d174473afb525 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Wed, 5 Jun 2024 16:27:46 +0200 Subject: [PATCH 33/80] Try building a deb for native --- .github/workflows/package_amd64.yml | 78 +++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 .github/workflows/package_amd64.yml diff --git a/.github/workflows/package_amd64.yml b/.github/workflows/package_amd64.yml new file mode 100644 index 000000000..ae7bf3242 --- /dev/null +++ b/.github/workflows/package_amd64.yml @@ -0,0 +1,78 @@ +name: Package Native + +on: + workflow_call: + workflow_dispatch: + +permissions: + contents: write + packages: write + +jobs: + build-native: + uses: ./.github/workflows/build_native.yml + + package-native: + runs-on: ubuntu-latest + needs: build-native + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + submodules: recursive + ref: ${{github.event.pull_request.head.ref}} + repository: ${{github.event.pull_request.head.repo.full_name}} + + - name: Pull web ui + uses: dsaltares/fetch-gh-release-asset@master + with: + repo: meshtastic/web + file: build.tar + target: build.tar + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Get release version string + run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT + id: version + + - name: Download artifacts + uses: actions/download-artifact@v4 + with: + name: firmware-native-${{ steps.version.outputs.version }}.zip + merge-multiple: true + + - name: Display structure of downloaded files + run: ls -R + + - name: build .debpkg + run: | + mkdir -p .debpkg/DEBIAN + mkdir -p .debpkg/usr/share/doc/meshtasticd/web + mkdir -p .debpkg/usr/sbin + mkdir -p .debpkg/etc/meshtasticd + mkdir -p .debpkg/usr/lib/systemd/system/ + tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web + gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz + cp release/meshtasticd_linux_x86_64 .debpkg/usr/sbin/meshtasticd + cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml + chmod +x .debpkg/usr/sbin/meshtasticd + cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service + echo "/etc/meshtasticd/config.yaml" > .debpkg/DEBIAN/conffiles + chmod +x .debpkg/DEBIAN/conffiles + + - uses: jiro4989/build-deb-action@v3 + with: + package: meshtasticd + package_root: .debpkg + maintainer: Jonathan Bennett + version: ${{ steps.version.outputs.version }} # refs/tags/v*.*.* + arch: amd64 + depends: libyaml-cpp0.7, openssl, libulfius2.7 + desc: Native Linux Meshtastic binary. + + - uses: actions/upload-artifact@v4 + with: + name: meshtasticd_${{ steps.version.outputs.version }}_amd64.deb + overwrite: true + path: | + ./*.deb From d8775d94e371ecf24f41f9fe700fcc48218ec51b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Wed, 5 Jun 2024 16:29:40 +0200 Subject: [PATCH 34/80] try harder dude --- .github/workflows/main_matrix.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index d2338c959..ade018e1b 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -109,6 +109,9 @@ jobs: package-raspbian-armv7l: uses: ./.github/workflows/package_raspbian_armv7l.yml + package-native: + uses: ./.github/workflows/package_amd64.yml + build-native: runs-on: ubuntu-latest steps: From 14b7c5b6efd73c6da7361f323360a6d2e7679980 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Wed, 5 Jun 2024 16:34:30 +0200 Subject: [PATCH 35/80] Create build_native.yml --- .github/workflows/build_native.yml | 51 ++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 .github/workflows/build_native.yml diff --git a/.github/workflows/build_native.yml b/.github/workflows/build_native.yml new file mode 100644 index 000000000..7c6cf6738 --- /dev/null +++ b/.github/workflows/build_native.yml @@ -0,0 +1,51 @@ +name: Build Native + +on: workflow_call + +permissions: + contents: write + packages: write + +jobs: + build-native: + runs-on: ubuntu-latest + steps: + - name: Install libbluetooth + shell: bash + run: | + apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev + + - name: Checkout code + uses: actions/checkout@v4 + with: + submodules: recursive + ref: ${{github.event.pull_request.head.ref}} + repository: ${{github.event.pull_request.head.repo.full_name}} + + - name: Upgrade python tools + shell: bash + run: | + python -m pip install --upgrade pip + pip install -U platformio adafruit-nrfutil + pip install -U meshtastic --pre + + - name: Upgrade platformio + shell: bash + run: | + pio upgrade + + - name: Build Native + run: bin/build-native.sh + + - name: Get release version string + run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT + id: version + + - name: Store binaries as an artifact + uses: actions/upload-artifact@v4 + with: + name: firmware-native-${{ steps.version.outputs.version }}.zip + overwrite: true + path: | + release/meshtasticd_linux_x86_64 + bin/config-dist.yaml From f1906c38f1aa7b1e22f3e897453b774583d6895c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Wed, 5 Jun 2024 16:37:12 +0200 Subject: [PATCH 36/80] sudo make me a sandwich --- .github/workflows/build_native.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_native.yml b/.github/workflows/build_native.yml index 7c6cf6738..d8d57a672 100644 --- a/.github/workflows/build_native.yml +++ b/.github/workflows/build_native.yml @@ -13,7 +13,7 @@ jobs: - name: Install libbluetooth shell: bash run: | - apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev + sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev - name: Checkout code uses: actions/checkout@v4 From fb3c1412314cb607425cb562157c6e4ede8301b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Wed, 5 Jun 2024 17:04:22 +0200 Subject: [PATCH 37/80] update package index --- .github/workflows/build_native.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build_native.yml b/.github/workflows/build_native.yml index d8d57a672..257bc4176 100644 --- a/.github/workflows/build_native.yml +++ b/.github/workflows/build_native.yml @@ -13,6 +13,7 @@ jobs: - name: Install libbluetooth shell: bash run: | + sudo apt-get update sudo apt-get install -y libbluetooth-dev libgpiod-dev libyaml-cpp-dev openssl libssl-dev libulfius-dev liborcania-dev - name: Checkout code From 7874ebc568c45e3413e6acd611b79f2948e88219 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Wed, 5 Jun 2024 17:24:55 +0200 Subject: [PATCH 38/80] Update package_amd64.yml --- .github/workflows/package_amd64.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/package_amd64.yml b/.github/workflows/package_amd64.yml index ae7bf3242..7a5efd154 100644 --- a/.github/workflows/package_amd64.yml +++ b/.github/workflows/package_amd64.yml @@ -53,7 +53,7 @@ jobs: mkdir -p .debpkg/usr/lib/systemd/system/ tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz - cp release/meshtasticd_linux_x86_64 .debpkg/usr/sbin/meshtasticd + cp meshtasticd_linux_x86_64 .debpkg/usr/sbin/meshtasticd cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml chmod +x .debpkg/usr/sbin/meshtasticd cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service From 96b286cd48d1a8c738ddc6ce5db9be81618cf21e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Wed, 5 Jun 2024 17:50:58 +0200 Subject: [PATCH 39/80] release x86_64 deb --- .github/workflows/main_matrix.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index ade018e1b..800c18b89 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -385,6 +385,16 @@ jobs: asset_name: meshtasticd_${{ steps.version.outputs.version }}_armhf.deb asset_content_type: application/vnd.debian.binary-package + - name: Add raspbian amd64 .deb + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ github.token }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./output/meshtasticd_${{ steps.version.outputs.version }}_amd64.deb + asset_name: meshtasticd_${{ steps.version.outputs.version }}_amd64.deb + asset_content_type: application/vnd.debian.binary-package + - name: Bump version.properties run: >- bin/bump_version.py From d82d9f5ef12aa2db54d7b0ead3b445c3253347f5 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Wed, 5 Jun 2024 23:31:33 +0200 Subject: [PATCH 40/80] fix dead link in EU_868 documentation See https://discord.com/channels/867578229534359593/871553168369148024/1248026118276255745. --- src/mesh/RadioInterface.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index cc6ccca07..eb86f4267 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -31,18 +31,18 @@ const RegionInfo regions[] = { RDEF(EU_433, 433.0f, 434.0f, 10, 0, 12, true, false, false), /* - https://www.thethingsnetwork.org/docs/lorawan/duty-cycle/ - https://www.thethingsnetwork.org/docs/lorawan/regional-parameters/ - https://www.legislation.gov.uk/uksi/1999/930/schedule/6/part/III/made/data.xht?view=snippet&wrap=true + https://www.thethingsnetwork.org/docs/lorawan/duty-cycle/ + https://www.thethingsnetwork.org/docs/lorawan/regional-parameters/ + https://www.legislation.gov.uk/uksi/1999/930/schedule/6/part/III/made/data.xht?view=snippet&wrap=true - audio_permitted = false per regulation + audio_permitted = false per regulation - Special Note: - The link above describes LoRaWAN's band plan, stating a power limit of 16 dBm. This is their own suggested specification, - we do not need to follow it. The European Union regulations clearly state that the power limit for this frequency range is - 500 mW, or 27 dBm. It also states that we can use interference avoidance and spectrum access techniques to avoid a duty - cycle. (Please refer to section 4.21 in the following document) - https://ec.europa.eu/growth/tools-databases/tris/index.cfm/ro/search/?trisaction=search.detail&year=2021&num=528&dLang=EN + Special Note: + The link above describes LoRaWAN's band plan, stating a power limit of 16 dBm. This is their own suggested specification, + we do not need to follow it. The European Union regulations clearly state that the power limit for this frequency range is + 500 mW, or 27 dBm. It also states that we can use interference avoidance and spectrum access techniques (such as LBT + + AFA) to avoid a duty cycle. (Please refer to line P page 22 of this document.) + https://www.etsi.org/deliver/etsi_en/300200_300299/30022002/03.01.01_60/en_30022002v030101p.pdf */ RDEF(EU_868, 869.4f, 869.65f, 10, 0, 27, false, false, false), From 646b25278614ade57fd0190cfd2196dd98761832 Mon Sep 17 00:00:00 2001 From: Talie5in Date: Thu, 6 Jun 2024 22:19:40 +0930 Subject: [PATCH 41/80] Include PositionModule if EXCLUDE_GPS defined (requied by AdminModule) --- src/modules/AdminModule.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index c9416a9b5..3c51be7c7 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -26,6 +26,11 @@ #if !MESHTASTIC_EXCLUDE_GPS #include "GPS.h" #endif + +#if MESHTASTIC_EXCLUDE_GPS +#include "modules/PositionModule.h" +#endif + #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR #include "AccelerometerThread.h" #endif From 1f9f885acaa969aca912d4ffe234b3d715edf4da Mon Sep 17 00:00:00 2001 From: Talie5in Date: Thu, 6 Jun 2024 22:31:10 +0930 Subject: [PATCH 42/80] If EXCUDE_MQTT Defined, skip reconnecting MQTT in WiFiAPClient and dont check status of is_mqtt_connected --- src/mesh/wifi/WiFiAPClient.cpp | 2 ++ src/modules/AdminModule.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/mesh/wifi/WiFiAPClient.cpp b/src/mesh/wifi/WiFiAPClient.cpp index a259d161b..ffb16bd3e 100644 --- a/src/mesh/wifi/WiFiAPClient.cpp +++ b/src/mesh/wifi/WiFiAPClient.cpp @@ -108,8 +108,10 @@ static void onNetworkConnected() } // FIXME this is kinda yucky, instead we should just have an observable for 'wifireconnected' +#ifndef MESHTASTIC_EXCLUDE_MQTT if (mqtt) mqtt->reconnect(); +#endif } static int32_t reconnectWiFi() diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index 3c51be7c7..091586462 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -756,7 +756,9 @@ void AdminModule::handleGetDeviceConnectionStatus(const meshtastic_MeshPacket &r if (conn.wifi.status.is_connected) { conn.wifi.rssi = WiFi.RSSI(); conn.wifi.status.ip_address = WiFi.localIP(); +#ifndef MESHTASTIC_EXCLUDE_MQTT conn.wifi.status.is_mqtt_connected = mqtt && mqtt->isConnectedDirectly(); +#endif conn.wifi.status.is_syslog_connected = false; // FIXME wire this up } #endif From a5c96a29d54fc1d224c48da26ade21508e5e54eb Mon Sep 17 00:00:00 2001 From: Talie5in Date: Thu, 6 Jun 2024 22:52:11 +0930 Subject: [PATCH 43/80] Fix missing IFNDEF and IFDEF in main-esp32.cpp when EXCLUDE_WIFI is defined. Moved IFDEF HAS_NETWORK to beginning of MQTT:runOnce (to catch when EXCLUDE_WIFI is defined) --- src/mqtt/MQTT.cpp | 3 +- src/platform/esp32/main-esp32.cpp | 247 +++++++++++++++--------------- 2 files changed, 128 insertions(+), 122 deletions(-) diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index 2e367420a..f3eda6d7c 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -396,6 +396,7 @@ bool MQTT::wantsLink() const int32_t MQTT::runOnce() { +#ifdef HAS_NETWORKING if (!moduleConfig.mqtt.enabled || !(moduleConfig.mqtt.map_reporting_enabled || channels.anyMqttEnabled())) return disable(); @@ -408,7 +409,7 @@ int32_t MQTT::runOnce() publishQueuedMessages(); return 200; } -#ifdef HAS_NETWORKING + else if (!pubSub.loop()) { if (!wantConnection) return 5000; // If we don't want connection now, check again in 5 secs diff --git a/src/platform/esp32/main-esp32.cpp b/src/platform/esp32/main-esp32.cpp index 57f466594..3d5eb059c 100644 --- a/src/platform/esp32/main-esp32.cpp +++ b/src/platform/esp32/main-esp32.cpp @@ -24,121 +24,126 @@ #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !MESHTASTIC_EXCLUDE_BLUETOOTH void setBluetoothEnable(bool enable) { +#ifndef MESHTASTIC_EXCLUDE_WIFI if (!isWifiAvailable() && config.bluetooth.enabled == true) { - if (!nimbleBluetooth) { - nimbleBluetooth = new NimbleBluetooth(); +#endif +#ifdef MESHTASTIC_EXCLUDE_WIFI + if (config.bluetooth.enabled == true) { +#endif + if (!nimbleBluetooth) { + nimbleBluetooth = new NimbleBluetooth(); + } + if (enable && !nimbleBluetooth->isActive()) { + nimbleBluetooth->setup(); + } + // For ESP32, no way to recover from bluetooth shutdown without reboot + // BLE advertising automatically stops when MCU enters light-sleep(?) + // For deep-sleep, shutdown hardware with nimbleBluetooth->deinit(). Requires reboot to reverse } - if (enable && !nimbleBluetooth->isActive()) { - nimbleBluetooth->setup(); - } - // For ESP32, no way to recover from bluetooth shutdown without reboot - // BLE advertising automatically stops when MCU enters light-sleep(?) - // For deep-sleep, shutdown hardware with nimbleBluetooth->deinit(). Requires reboot to reverse } -} #else void setBluetoothEnable(bool enable) {} void updateBatteryLevel(uint8_t level) {} #endif -void getMacAddr(uint8_t *dmac) -{ - assert(esp_efuse_mac_get_default(dmac) == ESP_OK); -} + void getMacAddr(uint8_t * dmac) + { + assert(esp_efuse_mac_get_default(dmac) == ESP_OK); + } #ifdef HAS_32768HZ #define CALIBRATE_ONE(cali_clk) calibrate_one(cali_clk, #cali_clk) -static uint32_t calibrate_one(rtc_cal_sel_t cal_clk, const char *name) -{ - const uint32_t cal_count = 1000; - // const float factor = (1 << 19) * 1000.0f; unused var? - uint32_t cali_val; - for (int i = 0; i < 5; ++i) { - cali_val = rtc_clk_cal(cal_clk, cal_count); + static uint32_t calibrate_one(rtc_cal_sel_t cal_clk, const char *name) + { + const uint32_t cal_count = 1000; + // const float factor = (1 << 19) * 1000.0f; unused var? + uint32_t cali_val; + for (int i = 0; i < 5; ++i) { + cali_val = rtc_clk_cal(cal_clk, cal_count); + } + return cali_val; } - return cali_val; -} -void enableSlowCLK() -{ - rtc_clk_32k_enable(true); + void enableSlowCLK() + { + rtc_clk_32k_enable(true); - CALIBRATE_ONE(RTC_CAL_RTC_MUX); - uint32_t cal_32k = CALIBRATE_ONE(RTC_CAL_32K_XTAL); + CALIBRATE_ONE(RTC_CAL_RTC_MUX); + uint32_t cal_32k = CALIBRATE_ONE(RTC_CAL_32K_XTAL); - if (cal_32k == 0) { - LOG_DEBUG("32K XTAL OSC has not started up\n"); - } else { - rtc_clk_slow_freq_set(RTC_SLOW_FREQ_32K_XTAL); - LOG_DEBUG("Switching RTC Source to 32.768Khz succeeded, using 32K XTAL\n"); + if (cal_32k == 0) { + LOG_DEBUG("32K XTAL OSC has not started up\n"); + } else { + rtc_clk_slow_freq_set(RTC_SLOW_FREQ_32K_XTAL); + LOG_DEBUG("Switching RTC Source to 32.768Khz succeeded, using 32K XTAL\n"); + CALIBRATE_ONE(RTC_CAL_RTC_MUX); + CALIBRATE_ONE(RTC_CAL_32K_XTAL); + } CALIBRATE_ONE(RTC_CAL_RTC_MUX); CALIBRATE_ONE(RTC_CAL_32K_XTAL); + if (rtc_clk_slow_freq_get() != RTC_SLOW_FREQ_32K_XTAL) { + LOG_WARN("Failed to switch 32K XTAL RTC source to 32.768Khz !!! \n"); + return; + } } - CALIBRATE_ONE(RTC_CAL_RTC_MUX); - CALIBRATE_ONE(RTC_CAL_32K_XTAL); - if (rtc_clk_slow_freq_get() != RTC_SLOW_FREQ_32K_XTAL) { - LOG_WARN("Failed to switch 32K XTAL RTC source to 32.768Khz !!! \n"); - return; - } -} #endif -void esp32Setup() -{ - uint32_t seed = esp_random(); - LOG_DEBUG("Setting random seed %u\n", seed); + void esp32Setup() + { + uint32_t seed = esp_random(); + LOG_DEBUG("Setting random seed %u\n", seed); - LOG_DEBUG("Total heap: %d\n", ESP.getHeapSize()); - LOG_DEBUG("Free heap: %d\n", ESP.getFreeHeap()); - LOG_DEBUG("Total PSRAM: %d\n", ESP.getPsramSize()); - LOG_DEBUG("Free PSRAM: %d\n", ESP.getFreePsram()); + LOG_DEBUG("Total heap: %d\n", ESP.getHeapSize()); + LOG_DEBUG("Free heap: %d\n", ESP.getFreeHeap()); + LOG_DEBUG("Total PSRAM: %d\n", ESP.getPsramSize()); + LOG_DEBUG("Free PSRAM: %d\n", ESP.getFreePsram()); - nvs_stats_t nvs_stats; - auto res = nvs_get_stats(NULL, &nvs_stats); - assert(res == ESP_OK); - LOG_DEBUG("NVS: UsedEntries %d, FreeEntries %d, AllEntries %d, NameSpaces %d\n", nvs_stats.used_entries, - nvs_stats.free_entries, nvs_stats.total_entries, nvs_stats.namespace_count); + nvs_stats_t nvs_stats; + auto res = nvs_get_stats(NULL, &nvs_stats); + assert(res == ESP_OK); + LOG_DEBUG("NVS: UsedEntries %d, FreeEntries %d, AllEntries %d, NameSpaces %d\n", nvs_stats.used_entries, + nvs_stats.free_entries, nvs_stats.total_entries, nvs_stats.namespace_count); - LOG_DEBUG("Setup Preferences in Flash Storage\n"); + LOG_DEBUG("Setup Preferences in Flash Storage\n"); - // Create object to store our persistent data - Preferences preferences; - preferences.begin("meshtastic", false); + // Create object to store our persistent data + Preferences preferences; + preferences.begin("meshtastic", false); - uint32_t rebootCounter = preferences.getUInt("rebootCounter", 0); - rebootCounter++; - preferences.putUInt("rebootCounter", rebootCounter); - preferences.end(); - LOG_DEBUG("Number of Device Reboots: %d\n", rebootCounter); + uint32_t rebootCounter = preferences.getUInt("rebootCounter", 0); + rebootCounter++; + preferences.putUInt("rebootCounter", rebootCounter); + preferences.end(); + LOG_DEBUG("Number of Device Reboots: %d\n", rebootCounter); #if !MESHTASTIC_EXCLUDE_BLUETOOTH - String BLEOTA = BleOta::getOtaAppVersion(); - if (BLEOTA.isEmpty()) { - LOG_DEBUG("No OTA firmware available\n"); - } else { - LOG_DEBUG("OTA firmware version %s\n", BLEOTA.c_str()); - } + String BLEOTA = BleOta::getOtaAppVersion(); + if (BLEOTA.isEmpty()) { + LOG_DEBUG("No OTA firmware available\n"); + } else { + LOG_DEBUG("OTA firmware version %s\n", BLEOTA.c_str()); + } #else LOG_DEBUG("No OTA firmware available\n"); #endif - // enableModemSleep(); + // enableModemSleep(); // Since we are turning on watchdogs rather late in the release schedule, we really don't want to catch any // false positives. The wait-to-sleep timeout for shutting down radios is 30 secs, so pick 45 for now. // #define APP_WATCHDOG_SECS 45 #define APP_WATCHDOG_SECS 90 - res = esp_task_wdt_init(APP_WATCHDOG_SECS, true); - assert(res == ESP_OK); + res = esp_task_wdt_init(APP_WATCHDOG_SECS, true); + assert(res == ESP_OK); - res = esp_task_wdt_add(NULL); - assert(res == ESP_OK); + res = esp_task_wdt_add(NULL); + assert(res == ESP_OK); #ifdef HAS_32768HZ - enableSlowCLK(); + enableSlowCLK(); #endif -} + } #if 0 // Turn off for now @@ -160,76 +165,76 @@ uint32_t axpDebugRead() Periodic axpDebugOutput(axpDebugRead); #endif -/// loop code specific to ESP32 targets -void esp32Loop() -{ - esp_task_wdt_reset(); // service our app level watchdog + /// loop code specific to ESP32 targets + void esp32Loop() + { + esp_task_wdt_reset(); // service our app level watchdog - // for debug printing - // radio.radioIf.canSleep(); -} + // for debug printing + // radio.radioIf.canSleep(); + } -void cpuDeepSleep(uint32_t msecToWake) -{ - /* - Some ESP32 IOs have internal pullups or pulldowns, which are enabled by default. - If an external circuit drives this pin in deep sleep mode, current consumption may - increase due to current flowing through these pullups and pulldowns. + void cpuDeepSleep(uint32_t msecToWake) + { + /* + Some ESP32 IOs have internal pullups or pulldowns, which are enabled by default. + If an external circuit drives this pin in deep sleep mode, current consumption may + increase due to current flowing through these pullups and pulldowns. - To isolate a pin, preventing extra current draw, call rtc_gpio_isolate() function. - For example, on ESP32-WROVER module, GPIO12 is pulled up externally. - GPIO12 also has an internal pulldown in the ESP32 chip. This means that in deep sleep, - some current will flow through these external and internal resistors, increasing deep - sleep current above the minimal possible value. + To isolate a pin, preventing extra current draw, call rtc_gpio_isolate() function. + For example, on ESP32-WROVER module, GPIO12 is pulled up externally. + GPIO12 also has an internal pulldown in the ESP32 chip. This means that in deep sleep, + some current will flow through these external and internal resistors, increasing deep + sleep current above the minimal possible value. - Note: we don't isolate pins that are used for the LORA, LED, i2c, or ST7735 Display for the Chatter2, spi or the wake - button(s), maybe we should not include any other GPIOs... - */ + Note: we don't isolate pins that are used for the LORA, LED, i2c, or ST7735 Display for the Chatter2, spi or the wake + button(s), maybe we should not include any other GPIOs... + */ #if SOC_RTCIO_HOLD_SUPPORTED - static const uint8_t rtcGpios[] = {/* 0, */ 2, - /* 4, */ + static const uint8_t rtcGpios[] = {/* 0, */ 2, + /* 4, */ #ifndef USE_JTAG - 13, - /* 14, */ /* 15, */ + 13, + /* 14, */ /* 15, */ #endif - /* 25, */ /* 26, */ /* 27, */ - /* 32, */ /* 33, */ 34, 35, - /* 36, */ 37 - /* 38, 39 */}; + /* 25, */ /* 26, */ /* 27, */ + /* 32, */ /* 33, */ 34, 35, + /* 36, */ 37 + /* 38, 39 */}; - for (int i = 0; i < sizeof(rtcGpios); i++) - rtc_gpio_isolate((gpio_num_t)rtcGpios[i]); + for (int i = 0; i < sizeof(rtcGpios); i++) + rtc_gpio_isolate((gpio_num_t)rtcGpios[i]); #endif - // FIXME, disable internal rtc pullups/pulldowns on the non isolated pins. for inputs that we aren't using - // to detect wake and in normal operation the external part drives them hard. + // FIXME, disable internal rtc pullups/pulldowns on the non isolated pins. for inputs that we aren't using + // to detect wake and in normal operation the external part drives them hard. #ifdef BUTTON_PIN - // Only GPIOs which are have RTC functionality can be used in this bit map: 0,2,4,12-15,25-27,32-39. + // Only GPIOs which are have RTC functionality can be used in this bit map: 0,2,4,12-15,25-27,32-39. #if SOC_RTCIO_HOLD_SUPPORTED - uint64_t gpioMask = (1ULL << (config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN)); + uint64_t gpioMask = (1ULL << (config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN)); #endif #ifdef BUTTON_NEED_PULLUP - gpio_pullup_en((gpio_num_t)BUTTON_PIN); + gpio_pullup_en((gpio_num_t)BUTTON_PIN); #endif - // Not needed because both of the current boards have external pullups - // FIXME change polarity in hw so we can wake on ANY_HIGH instead - that would allow us to use all three buttons (instead of - // just the first) gpio_pullup_en((gpio_num_t)BUTTON_PIN); + // Not needed because both of the current boards have external pullups + // FIXME change polarity in hw so we can wake on ANY_HIGH instead - that would allow us to use all three buttons (instead + // of just the first) gpio_pullup_en((gpio_num_t)BUTTON_PIN); #if SOC_PM_SUPPORT_EXT_WAKEUP #ifdef CONFIG_IDF_TARGET_ESP32 - // ESP_EXT1_WAKEUP_ALL_LOW has been deprecated since esp-idf v5.4 for any other target. - esp_sleep_enable_ext1_wakeup(gpioMask, ESP_EXT1_WAKEUP_ALL_LOW); + // ESP_EXT1_WAKEUP_ALL_LOW has been deprecated since esp-idf v5.4 for any other target. + esp_sleep_enable_ext1_wakeup(gpioMask, ESP_EXT1_WAKEUP_ALL_LOW); #else - esp_sleep_enable_ext1_wakeup(gpioMask, ESP_EXT1_WAKEUP_ANY_LOW); + esp_sleep_enable_ext1_wakeup(gpioMask, ESP_EXT1_WAKEUP_ANY_LOW); #endif #endif #endif - // We want RTC peripherals to stay on - esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); + // We want RTC peripherals to stay on + esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); - esp_sleep_enable_timer_wakeup(msecToWake * 1000ULL); // call expects usecs - esp_deep_sleep_start(); // TBD mA sleep current (battery) -} \ No newline at end of file + esp_sleep_enable_timer_wakeup(msecToWake * 1000ULL); // call expects usecs + esp_deep_sleep_start(); // TBD mA sleep current (battery) + } \ No newline at end of file From d09da9678092f56908ee3ebce8fb80b62b96ba2d Mon Sep 17 00:00:00 2001 From: Talie5in Date: Thu, 6 Jun 2024 23:57:44 +0930 Subject: [PATCH 44/80] Fix indentation oopsie --- src/platform/esp32/main-esp32.cpp | 231 +++++++++++++++--------------- 1 file changed, 116 insertions(+), 115 deletions(-) diff --git a/src/platform/esp32/main-esp32.cpp b/src/platform/esp32/main-esp32.cpp index 3d5eb059c..1dd7a389a 100644 --- a/src/platform/esp32/main-esp32.cpp +++ b/src/platform/esp32/main-esp32.cpp @@ -25,11 +25,12 @@ void setBluetoothEnable(bool enable) { #ifndef MESHTASTIC_EXCLUDE_WIFI - if (!isWifiAvailable() && config.bluetooth.enabled == true) { + if (!isWifiAvailable() && config.bluetooth.enabled == true) #endif #ifdef MESHTASTIC_EXCLUDE_WIFI - if (config.bluetooth.enabled == true) { + if (config.bluetooth.enabled == true) #endif + { if (!nimbleBluetooth) { nimbleBluetooth = new NimbleBluetooth(); } @@ -40,110 +41,110 @@ void setBluetoothEnable(bool enable) // BLE advertising automatically stops when MCU enters light-sleep(?) // For deep-sleep, shutdown hardware with nimbleBluetooth->deinit(). Requires reboot to reverse } - } +} #else void setBluetoothEnable(bool enable) {} void updateBatteryLevel(uint8_t level) {} #endif - void getMacAddr(uint8_t * dmac) - { - assert(esp_efuse_mac_get_default(dmac) == ESP_OK); - } +void getMacAddr(uint8_t *dmac) +{ + assert(esp_efuse_mac_get_default(dmac) == ESP_OK); +} #ifdef HAS_32768HZ #define CALIBRATE_ONE(cali_clk) calibrate_one(cali_clk, #cali_clk) - static uint32_t calibrate_one(rtc_cal_sel_t cal_clk, const char *name) - { - const uint32_t cal_count = 1000; - // const float factor = (1 << 19) * 1000.0f; unused var? - uint32_t cali_val; - for (int i = 0; i < 5; ++i) { - cali_val = rtc_clk_cal(cal_clk, cal_count); - } - return cali_val; +static uint32_t calibrate_one(rtc_cal_sel_t cal_clk, const char *name) +{ + const uint32_t cal_count = 1000; + // const float factor = (1 << 19) * 1000.0f; unused var? + uint32_t cali_val; + for (int i = 0; i < 5; ++i) { + cali_val = rtc_clk_cal(cal_clk, cal_count); } + return cali_val; +} - void enableSlowCLK() - { - rtc_clk_32k_enable(true); +void enableSlowCLK() +{ + rtc_clk_32k_enable(true); - CALIBRATE_ONE(RTC_CAL_RTC_MUX); - uint32_t cal_32k = CALIBRATE_ONE(RTC_CAL_32K_XTAL); + CALIBRATE_ONE(RTC_CAL_RTC_MUX); + uint32_t cal_32k = CALIBRATE_ONE(RTC_CAL_32K_XTAL); - if (cal_32k == 0) { - LOG_DEBUG("32K XTAL OSC has not started up\n"); - } else { - rtc_clk_slow_freq_set(RTC_SLOW_FREQ_32K_XTAL); - LOG_DEBUG("Switching RTC Source to 32.768Khz succeeded, using 32K XTAL\n"); - CALIBRATE_ONE(RTC_CAL_RTC_MUX); - CALIBRATE_ONE(RTC_CAL_32K_XTAL); - } + if (cal_32k == 0) { + LOG_DEBUG("32K XTAL OSC has not started up\n"); + } else { + rtc_clk_slow_freq_set(RTC_SLOW_FREQ_32K_XTAL); + LOG_DEBUG("Switching RTC Source to 32.768Khz succeeded, using 32K XTAL\n"); CALIBRATE_ONE(RTC_CAL_RTC_MUX); CALIBRATE_ONE(RTC_CAL_32K_XTAL); - if (rtc_clk_slow_freq_get() != RTC_SLOW_FREQ_32K_XTAL) { - LOG_WARN("Failed to switch 32K XTAL RTC source to 32.768Khz !!! \n"); - return; - } } + CALIBRATE_ONE(RTC_CAL_RTC_MUX); + CALIBRATE_ONE(RTC_CAL_32K_XTAL); + if (rtc_clk_slow_freq_get() != RTC_SLOW_FREQ_32K_XTAL) { + LOG_WARN("Failed to switch 32K XTAL RTC source to 32.768Khz !!! \n"); + return; + } +} #endif - void esp32Setup() - { - uint32_t seed = esp_random(); - LOG_DEBUG("Setting random seed %u\n", seed); +void esp32Setup() +{ + uint32_t seed = esp_random(); + LOG_DEBUG("Setting random seed %u\n", seed); - LOG_DEBUG("Total heap: %d\n", ESP.getHeapSize()); - LOG_DEBUG("Free heap: %d\n", ESP.getFreeHeap()); - LOG_DEBUG("Total PSRAM: %d\n", ESP.getPsramSize()); - LOG_DEBUG("Free PSRAM: %d\n", ESP.getFreePsram()); + LOG_DEBUG("Total heap: %d\n", ESP.getHeapSize()); + LOG_DEBUG("Free heap: %d\n", ESP.getFreeHeap()); + LOG_DEBUG("Total PSRAM: %d\n", ESP.getPsramSize()); + LOG_DEBUG("Free PSRAM: %d\n", ESP.getFreePsram()); - nvs_stats_t nvs_stats; - auto res = nvs_get_stats(NULL, &nvs_stats); - assert(res == ESP_OK); - LOG_DEBUG("NVS: UsedEntries %d, FreeEntries %d, AllEntries %d, NameSpaces %d\n", nvs_stats.used_entries, - nvs_stats.free_entries, nvs_stats.total_entries, nvs_stats.namespace_count); + nvs_stats_t nvs_stats; + auto res = nvs_get_stats(NULL, &nvs_stats); + assert(res == ESP_OK); + LOG_DEBUG("NVS: UsedEntries %d, FreeEntries %d, AllEntries %d, NameSpaces %d\n", nvs_stats.used_entries, + nvs_stats.free_entries, nvs_stats.total_entries, nvs_stats.namespace_count); - LOG_DEBUG("Setup Preferences in Flash Storage\n"); + LOG_DEBUG("Setup Preferences in Flash Storage\n"); - // Create object to store our persistent data - Preferences preferences; - preferences.begin("meshtastic", false); + // Create object to store our persistent data + Preferences preferences; + preferences.begin("meshtastic", false); - uint32_t rebootCounter = preferences.getUInt("rebootCounter", 0); - rebootCounter++; - preferences.putUInt("rebootCounter", rebootCounter); - preferences.end(); - LOG_DEBUG("Number of Device Reboots: %d\n", rebootCounter); + uint32_t rebootCounter = preferences.getUInt("rebootCounter", 0); + rebootCounter++; + preferences.putUInt("rebootCounter", rebootCounter); + preferences.end(); + LOG_DEBUG("Number of Device Reboots: %d\n", rebootCounter); #if !MESHTASTIC_EXCLUDE_BLUETOOTH - String BLEOTA = BleOta::getOtaAppVersion(); - if (BLEOTA.isEmpty()) { - LOG_DEBUG("No OTA firmware available\n"); - } else { - LOG_DEBUG("OTA firmware version %s\n", BLEOTA.c_str()); - } + String BLEOTA = BleOta::getOtaAppVersion(); + if (BLEOTA.isEmpty()) { + LOG_DEBUG("No OTA firmware available\n"); + } else { + LOG_DEBUG("OTA firmware version %s\n", BLEOTA.c_str()); + } #else LOG_DEBUG("No OTA firmware available\n"); #endif - // enableModemSleep(); + // enableModemSleep(); // Since we are turning on watchdogs rather late in the release schedule, we really don't want to catch any // false positives. The wait-to-sleep timeout for shutting down radios is 30 secs, so pick 45 for now. // #define APP_WATCHDOG_SECS 45 #define APP_WATCHDOG_SECS 90 - res = esp_task_wdt_init(APP_WATCHDOG_SECS, true); - assert(res == ESP_OK); + res = esp_task_wdt_init(APP_WATCHDOG_SECS, true); + assert(res == ESP_OK); - res = esp_task_wdt_add(NULL); - assert(res == ESP_OK); + res = esp_task_wdt_add(NULL); + assert(res == ESP_OK); #ifdef HAS_32768HZ - enableSlowCLK(); + enableSlowCLK(); #endif - } +} #if 0 // Turn off for now @@ -165,76 +166,76 @@ uint32_t axpDebugRead() Periodic axpDebugOutput(axpDebugRead); #endif - /// loop code specific to ESP32 targets - void esp32Loop() - { - esp_task_wdt_reset(); // service our app level watchdog +/// loop code specific to ESP32 targets +void esp32Loop() +{ + esp_task_wdt_reset(); // service our app level watchdog - // for debug printing - // radio.radioIf.canSleep(); - } + // for debug printing + // radio.radioIf.canSleep(); +} - void cpuDeepSleep(uint32_t msecToWake) - { - /* - Some ESP32 IOs have internal pullups or pulldowns, which are enabled by default. - If an external circuit drives this pin in deep sleep mode, current consumption may - increase due to current flowing through these pullups and pulldowns. +void cpuDeepSleep(uint32_t msecToWake) +{ + /* + Some ESP32 IOs have internal pullups or pulldowns, which are enabled by default. + If an external circuit drives this pin in deep sleep mode, current consumption may + increase due to current flowing through these pullups and pulldowns. - To isolate a pin, preventing extra current draw, call rtc_gpio_isolate() function. - For example, on ESP32-WROVER module, GPIO12 is pulled up externally. - GPIO12 also has an internal pulldown in the ESP32 chip. This means that in deep sleep, - some current will flow through these external and internal resistors, increasing deep - sleep current above the minimal possible value. + To isolate a pin, preventing extra current draw, call rtc_gpio_isolate() function. + For example, on ESP32-WROVER module, GPIO12 is pulled up externally. + GPIO12 also has an internal pulldown in the ESP32 chip. This means that in deep sleep, + some current will flow through these external and internal resistors, increasing deep + sleep current above the minimal possible value. - Note: we don't isolate pins that are used for the LORA, LED, i2c, or ST7735 Display for the Chatter2, spi or the wake - button(s), maybe we should not include any other GPIOs... - */ + Note: we don't isolate pins that are used for the LORA, LED, i2c, or ST7735 Display for the Chatter2, spi or the wake + button(s), maybe we should not include any other GPIOs... + */ #if SOC_RTCIO_HOLD_SUPPORTED - static const uint8_t rtcGpios[] = {/* 0, */ 2, - /* 4, */ + static const uint8_t rtcGpios[] = {/* 0, */ 2, + /* 4, */ #ifndef USE_JTAG - 13, - /* 14, */ /* 15, */ + 13, + /* 14, */ /* 15, */ #endif - /* 25, */ /* 26, */ /* 27, */ - /* 32, */ /* 33, */ 34, 35, - /* 36, */ 37 - /* 38, 39 */}; + /* 25, */ /* 26, */ /* 27, */ + /* 32, */ /* 33, */ 34, 35, + /* 36, */ 37 + /* 38, 39 */}; - for (int i = 0; i < sizeof(rtcGpios); i++) - rtc_gpio_isolate((gpio_num_t)rtcGpios[i]); + for (int i = 0; i < sizeof(rtcGpios); i++) + rtc_gpio_isolate((gpio_num_t)rtcGpios[i]); #endif - // FIXME, disable internal rtc pullups/pulldowns on the non isolated pins. for inputs that we aren't using - // to detect wake and in normal operation the external part drives them hard. + // FIXME, disable internal rtc pullups/pulldowns on the non isolated pins. for inputs that we aren't using + // to detect wake and in normal operation the external part drives them hard. #ifdef BUTTON_PIN - // Only GPIOs which are have RTC functionality can be used in this bit map: 0,2,4,12-15,25-27,32-39. + // Only GPIOs which are have RTC functionality can be used in this bit map: 0,2,4,12-15,25-27,32-39. #if SOC_RTCIO_HOLD_SUPPORTED - uint64_t gpioMask = (1ULL << (config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN)); + uint64_t gpioMask = (1ULL << (config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN)); #endif #ifdef BUTTON_NEED_PULLUP - gpio_pullup_en((gpio_num_t)BUTTON_PIN); + gpio_pullup_en((gpio_num_t)BUTTON_PIN); #endif - // Not needed because both of the current boards have external pullups - // FIXME change polarity in hw so we can wake on ANY_HIGH instead - that would allow us to use all three buttons (instead - // of just the first) gpio_pullup_en((gpio_num_t)BUTTON_PIN); + // Not needed because both of the current boards have external pullups + // FIXME change polarity in hw so we can wake on ANY_HIGH instead - that would allow us to use all three buttons (instead + // of just the first) gpio_pullup_en((gpio_num_t)BUTTON_PIN); #if SOC_PM_SUPPORT_EXT_WAKEUP #ifdef CONFIG_IDF_TARGET_ESP32 - // ESP_EXT1_WAKEUP_ALL_LOW has been deprecated since esp-idf v5.4 for any other target. - esp_sleep_enable_ext1_wakeup(gpioMask, ESP_EXT1_WAKEUP_ALL_LOW); + // ESP_EXT1_WAKEUP_ALL_LOW has been deprecated since esp-idf v5.4 for any other target. + esp_sleep_enable_ext1_wakeup(gpioMask, ESP_EXT1_WAKEUP_ALL_LOW); #else - esp_sleep_enable_ext1_wakeup(gpioMask, ESP_EXT1_WAKEUP_ANY_LOW); + esp_sleep_enable_ext1_wakeup(gpioMask, ESP_EXT1_WAKEUP_ANY_LOW); #endif #endif #endif - // We want RTC peripherals to stay on - esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); + // We want RTC peripherals to stay on + esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); - esp_sleep_enable_timer_wakeup(msecToWake * 1000ULL); // call expects usecs - esp_deep_sleep_start(); // TBD mA sleep current (battery) - } \ No newline at end of file + esp_sleep_enable_timer_wakeup(msecToWake * 1000ULL); // call expects usecs + esp_deep_sleep_start(); // TBD mA sleep current (battery) +} \ No newline at end of file From 338244de32686c7d1f882e92d8785e76e99fa054 Mon Sep 17 00:00:00 2001 From: todd-herbert Date: Sat, 8 Jun 2024 00:28:29 +1200 Subject: [PATCH 45/80] Wake screen on first press (#4052) --- src/ButtonThread.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ButtonThread.cpp b/src/ButtonThread.cpp index aaead62be..7e678d69d 100644 --- a/src/ButtonThread.cpp +++ b/src/ButtonThread.cpp @@ -232,10 +232,10 @@ void ButtonThread::attachButtonInterrupts() attachInterrupt( config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN, []() { - BaseType_t higherWake = 0; - mainDelay.interruptFromISR(&higherWake); ButtonThread::userButton.tick(); runASAP = true; + BaseType_t higherWake = 0; + mainDelay.interruptFromISR(&higherWake); }, CHANGE); #endif From a52db85ebe0a2b7aec1da710083cabf0c3542b1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Fri, 7 Jun 2024 15:36:31 +0200 Subject: [PATCH 46/80] fix base setup --- .github/actions/setup-base/action.yml | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/.github/actions/setup-base/action.yml b/.github/actions/setup-base/action.yml index 7e57f6a31..b5b4cb6f3 100644 --- a/.github/actions/setup-base/action.yml +++ b/.github/actions/setup-base/action.yml @@ -11,23 +11,11 @@ runs: ref: ${{github.event.pull_request.head.ref}} repository: ${{github.event.pull_request.head.repo.full_name}} - - name: Install cppcheck + - name: Install dependencies shell: bash run: | - sudo apt-get install -y cppcheck - - - name: Install libbluetooth - shell: bash - run: | - sudo apt-get install -y libbluetooth-dev - - name: Install libgpiod - shell: bash - run: | - sudo apt-get install -y libgpiod-dev - - name: Install libyaml-cpp - shell: bash - run: | - sudo apt-get install -y libyaml-cpp-dev + sudo apt-get -y update + sudo apt-get install -y cppcheck libbluetooth-dev libgpiod-dev libyaml-cpp-dev - name: Setup Python uses: actions/setup-python@v5 From 355c6108247479dba405c8141f74b8fe69c0f426 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Fri, 7 Jun 2024 15:31:53 +0200 Subject: [PATCH 47/80] Compile without toolchain patching --- variants/xiao_ble/nrf52840_s140_v7.ld | 38 + variants/xiao_ble/platformio.ini | 3 +- variants/xiao_ble/softdevice/ble.h | 652 ++++ variants/xiao_ble/softdevice/ble_err.h | 92 + variants/xiao_ble/softdevice/ble_gap.h | 2895 ++++++++++++++++++ variants/xiao_ble/softdevice/ble_gatt.h | 232 ++ variants/xiao_ble/softdevice/ble_gattc.h | 764 +++++ variants/xiao_ble/softdevice/ble_gatts.h | 904 ++++++ variants/xiao_ble/softdevice/ble_hci.h | 135 + variants/xiao_ble/softdevice/ble_l2cap.h | 495 +++ variants/xiao_ble/softdevice/ble_ranges.h | 149 + variants/xiao_ble/softdevice/ble_types.h | 217 ++ variants/xiao_ble/softdevice/nrf52/nrf_mbr.h | 259 ++ variants/xiao_ble/softdevice/nrf_error.h | 90 + variants/xiao_ble/softdevice/nrf_error_sdm.h | 73 + variants/xiao_ble/softdevice/nrf_error_soc.h | 85 + variants/xiao_ble/softdevice/nrf_nvic.h | 449 +++ variants/xiao_ble/softdevice/nrf_sdm.h | 380 +++ variants/xiao_ble/softdevice/nrf_soc.h | 1046 +++++++ variants/xiao_ble/softdevice/nrf_svc.h | 98 + 20 files changed, 9055 insertions(+), 1 deletion(-) create mode 100644 variants/xiao_ble/nrf52840_s140_v7.ld create mode 100644 variants/xiao_ble/softdevice/ble.h create mode 100644 variants/xiao_ble/softdevice/ble_err.h create mode 100644 variants/xiao_ble/softdevice/ble_gap.h create mode 100644 variants/xiao_ble/softdevice/ble_gatt.h create mode 100644 variants/xiao_ble/softdevice/ble_gattc.h create mode 100644 variants/xiao_ble/softdevice/ble_gatts.h create mode 100644 variants/xiao_ble/softdevice/ble_hci.h create mode 100644 variants/xiao_ble/softdevice/ble_l2cap.h create mode 100644 variants/xiao_ble/softdevice/ble_ranges.h create mode 100644 variants/xiao_ble/softdevice/ble_types.h create mode 100644 variants/xiao_ble/softdevice/nrf52/nrf_mbr.h create mode 100644 variants/xiao_ble/softdevice/nrf_error.h create mode 100644 variants/xiao_ble/softdevice/nrf_error_sdm.h create mode 100644 variants/xiao_ble/softdevice/nrf_error_soc.h create mode 100644 variants/xiao_ble/softdevice/nrf_nvic.h create mode 100644 variants/xiao_ble/softdevice/nrf_sdm.h create mode 100644 variants/xiao_ble/softdevice/nrf_soc.h create mode 100644 variants/xiao_ble/softdevice/nrf_svc.h diff --git a/variants/xiao_ble/nrf52840_s140_v7.ld b/variants/xiao_ble/nrf52840_s140_v7.ld new file mode 100644 index 000000000..6aaeb4034 --- /dev/null +++ b/variants/xiao_ble/nrf52840_s140_v7.ld @@ -0,0 +1,38 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x27000, LENGTH = 0xED000 - 0x27000 + + /* SRAM required by Softdevice depend on + * - Attribute Table Size (Number of Services and Characteristics) + * - Vendor UUID count + * - Max ATT MTU + * - Concurrent connection peripheral + central + secure links + * - Event Len, HVN queue, Write CMD queue + */ + RAM (rwx) : ORIGIN = 0x20006000, LENGTH = 0x20040000 - 0x20006000 +} + +SECTIONS +{ + . = ALIGN(4); + .svc_data : + { + PROVIDE(__start_svc_data = .); + KEEP(*(.svc_data)) + PROVIDE(__stop_svc_data = .); + } > RAM + + .fs_data : + { + PROVIDE(__start_fs_data = .); + KEEP(*(.fs_data)) + PROVIDE(__stop_fs_data = .); + } > RAM +} INSERT AFTER .data; + +INCLUDE "nrf52_common.ld" diff --git a/variants/xiao_ble/platformio.ini b/variants/xiao_ble/platformio.ini index 8e9a663a9..60e7cecbd 100644 --- a/variants/xiao_ble/platformio.ini +++ b/variants/xiao_ble/platformio.ini @@ -3,8 +3,9 @@ extends = nrf52840_base board = xiao_ble_sense board_level = extra -build_flags = ${nrf52840_base.build_flags} -Ivariants/xiao_ble -Dxiao_ble -D EBYTE_E22 +build_flags = ${nrf52840_base.build_flags} -Ivariants/xiao_ble -Ivariants/xiao_ble/softdevice -Ivariants/xiao_ble/softdevice/nrf52 -D EBYTE_E22 -DPRIVATE_HW -L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m4/fpv4-sp-d16-hard" +board_build.ldscript = variants/xiao_ble/nrf52840_s140_v7.ld build_src_filter = ${nrf52_base.build_src_filter} +<../variants/xiao_ble> lib_deps = ${nrf52840_base.lib_deps} diff --git a/variants/xiao_ble/softdevice/ble.h b/variants/xiao_ble/softdevice/ble.h new file mode 100644 index 000000000..177b436ad --- /dev/null +++ b/variants/xiao_ble/softdevice/ble.h @@ -0,0 +1,652 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + @addtogroup BLE_COMMON BLE SoftDevice Common + @{ + @defgroup ble_api Events, type definitions and API calls + @{ + + @brief Module independent events, type definitions and API calls for the BLE SoftDevice. + + */ + +#ifndef BLE_H__ +#define BLE_H__ + +#include "ble_err.h" +#include "ble_gap.h" +#include "ble_gatt.h" +#include "ble_gattc.h" +#include "ble_gatts.h" +#include "ble_l2cap.h" +#include "nrf_error.h" +#include "nrf_svc.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup BLE_COMMON_ENUMERATIONS Enumerations + * @{ */ + +/** + * @brief Common API SVC numbers. + */ +enum BLE_COMMON_SVCS { + SD_BLE_ENABLE = BLE_SVC_BASE, /**< Enable and initialize the BLE stack */ + SD_BLE_EVT_GET, /**< Get an event from the pending events queue. */ + SD_BLE_UUID_VS_ADD, /**< Add a Vendor Specific base UUID. */ + SD_BLE_UUID_DECODE, /**< Decode UUID bytes. */ + SD_BLE_UUID_ENCODE, /**< Encode UUID bytes. */ + SD_BLE_VERSION_GET, /**< Get the local version information (company ID, Link Layer Version, Link Layer Subversion). */ + SD_BLE_USER_MEM_REPLY, /**< User Memory Reply. */ + SD_BLE_OPT_SET, /**< Set a BLE option. */ + SD_BLE_OPT_GET, /**< Get a BLE option. */ + SD_BLE_CFG_SET, /**< Add a configuration to the BLE stack. */ + SD_BLE_UUID_VS_REMOVE, /**< Remove a Vendor Specific base UUID. */ +}; + +/** + * @brief BLE Module Independent Event IDs. + */ +enum BLE_COMMON_EVTS { + BLE_EVT_USER_MEM_REQUEST = BLE_EVT_BASE + 0, /**< User Memory request. See @ref ble_evt_user_mem_request_t + \n Reply with @ref sd_ble_user_mem_reply. */ + BLE_EVT_USER_MEM_RELEASE = BLE_EVT_BASE + 1, /**< User Memory release. See @ref ble_evt_user_mem_release_t */ +}; + +/**@brief BLE Connection Configuration IDs. + * + * IDs that uniquely identify a connection configuration. + */ +enum BLE_CONN_CFGS { + BLE_CONN_CFG_GAP = BLE_CONN_CFG_BASE + 0, /**< BLE GAP specific connection configuration. */ + BLE_CONN_CFG_GATTC = BLE_CONN_CFG_BASE + 1, /**< BLE GATTC specific connection configuration. */ + BLE_CONN_CFG_GATTS = BLE_CONN_CFG_BASE + 2, /**< BLE GATTS specific connection configuration. */ + BLE_CONN_CFG_GATT = BLE_CONN_CFG_BASE + 3, /**< BLE GATT specific connection configuration. */ + BLE_CONN_CFG_L2CAP = BLE_CONN_CFG_BASE + 4, /**< BLE L2CAP specific connection configuration. */ +}; + +/**@brief BLE Common Configuration IDs. + * + * IDs that uniquely identify a common configuration. + */ +enum BLE_COMMON_CFGS { + BLE_COMMON_CFG_VS_UUID = BLE_CFG_BASE, /**< Vendor specific base UUID configuration */ +}; + +/**@brief Common Option IDs. + * IDs that uniquely identify a common option. + */ +enum BLE_COMMON_OPTS { + BLE_COMMON_OPT_PA_LNA = BLE_OPT_BASE + 0, /**< PA and LNA options */ + BLE_COMMON_OPT_CONN_EVT_EXT = BLE_OPT_BASE + 1, /**< Extended connection events option */ + BLE_COMMON_OPT_EXTENDED_RC_CAL = BLE_OPT_BASE + 2, /**< Extended RC calibration option */ +}; + +/** @} */ + +/** @addtogroup BLE_COMMON_DEFINES Defines + * @{ */ + +/** @brief Required pointer alignment for BLE Events. + */ +#define BLE_EVT_PTR_ALIGNMENT 4 + +/** @brief Leaves the maximum of the two arguments. + */ +#define BLE_MAX(a, b) ((a) < (b) ? (b) : (a)) + +/** @brief Maximum possible length for BLE Events. + * @note The highest value used for @ref ble_gatt_conn_cfg_t::att_mtu in any connection configuration shall be used as a + * parameter. If that value has not been configured for any connections then @ref BLE_GATT_ATT_MTU_DEFAULT must be used instead. + */ +#define BLE_EVT_LEN_MAX(ATT_MTU) \ + (offsetof(ble_evt_t, evt.gattc_evt.params.prim_srvc_disc_rsp.services) + ((ATT_MTU)-1) / 4 * sizeof(ble_gattc_service_t)) + +/** @defgroup BLE_USER_MEM_TYPES User Memory Types + * @{ */ +#define BLE_USER_MEM_TYPE_INVALID 0x00 /**< Invalid User Memory Types. */ +#define BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES 0x01 /**< User Memory for GATTS queued writes. */ +/** @} */ + +/** @defgroup BLE_UUID_VS_COUNTS Vendor Specific base UUID counts + * @{ + */ +#define BLE_UUID_VS_COUNT_DEFAULT 10 /**< Default VS UUID count. */ +#define BLE_UUID_VS_COUNT_MAX 254 /**< Maximum VS UUID count. */ +/** @} */ + +/** @defgroup BLE_COMMON_CFG_DEFAULTS Configuration defaults. + * @{ + */ +#define BLE_CONN_CFG_TAG_DEFAULT 0 /**< Default configuration tag, SoftDevice default connection configuration. */ + +/** @} */ + +/** @} */ + +/** @addtogroup BLE_COMMON_STRUCTURES Structures + * @{ */ + +/**@brief User Memory Block. */ +typedef struct { + uint8_t *p_mem; /**< Pointer to the start of the user memory block. */ + uint16_t len; /**< Length in bytes of the user memory block. */ +} ble_user_mem_block_t; + +/**@brief Event structure for @ref BLE_EVT_USER_MEM_REQUEST. */ +typedef struct { + uint8_t type; /**< User memory type, see @ref BLE_USER_MEM_TYPES. */ +} ble_evt_user_mem_request_t; + +/**@brief Event structure for @ref BLE_EVT_USER_MEM_RELEASE. */ +typedef struct { + uint8_t type; /**< User memory type, see @ref BLE_USER_MEM_TYPES. */ + ble_user_mem_block_t mem_block; /**< User memory block */ +} ble_evt_user_mem_release_t; + +/**@brief Event structure for events not associated with a specific function module. */ +typedef struct { + uint16_t conn_handle; /**< Connection Handle on which this event occurred. */ + union { + ble_evt_user_mem_request_t user_mem_request; /**< User Memory Request Event Parameters. */ + ble_evt_user_mem_release_t user_mem_release; /**< User Memory Release Event Parameters. */ + } params; /**< Event parameter union. */ +} ble_common_evt_t; + +/**@brief BLE Event header. */ +typedef struct { + uint16_t evt_id; /**< Value from a BLE__EVT series. */ + uint16_t evt_len; /**< Length in octets including this header. */ +} ble_evt_hdr_t; + +/**@brief Common BLE Event type, wrapping the module specific event reports. */ +typedef struct { + ble_evt_hdr_t header; /**< Event header. */ + union { + ble_common_evt_t common_evt; /**< Common Event, evt_id in BLE_EVT_* series. */ + ble_gap_evt_t gap_evt; /**< GAP originated event, evt_id in BLE_GAP_EVT_* series. */ + ble_gattc_evt_t gattc_evt; /**< GATT client originated event, evt_id in BLE_GATTC_EVT* series. */ + ble_gatts_evt_t gatts_evt; /**< GATT server originated event, evt_id in BLE_GATTS_EVT* series. */ + ble_l2cap_evt_t l2cap_evt; /**< L2CAP originated event, evt_id in BLE_L2CAP_EVT* series. */ + } evt; /**< Event union. */ +} ble_evt_t; + +/** + * @brief Version Information. + */ +typedef struct { + uint8_t version_number; /**< Link Layer Version number. See + https://www.bluetooth.org/en-us/specification/assigned-numbers/link-layer for assigned values. */ + uint16_t company_id; /**< Company ID, Nordic Semiconductor's company ID is 89 (0x0059) + (https://www.bluetooth.org/apps/content/Default.aspx?doc_id=49708). */ + uint16_t + subversion_number; /**< Link Layer Sub Version number, corresponds to the SoftDevice Config ID or Firmware ID (FWID). */ +} ble_version_t; + +/** + * @brief Configuration parameters for the PA and LNA. + */ +typedef struct { + uint8_t enable : 1; /**< Enable toggling for this amplifier */ + uint8_t active_high : 1; /**< Set the pin to be active high */ + uint8_t gpio_pin : 6; /**< The GPIO pin to toggle for this amplifier */ +} ble_pa_lna_cfg_t; + +/** + * @brief PA & LNA GPIO toggle configuration + * + * This option configures the SoftDevice to toggle pins when the radio is active for use with a power amplifier and/or + * a low noise amplifier. + * + * Toggling the pins is achieved by using two PPI channels and a GPIOTE channel. The hardware channel IDs are provided + * by the application and should be regarded as reserved as long as any PA/LNA toggling is enabled. + * + * @note @ref sd_ble_opt_get is not supported for this option. + * @note Setting this option while the radio is in use (i.e. any of the roles are active) may have undefined consequences + * and must be avoided by the application. + */ +typedef struct { + ble_pa_lna_cfg_t pa_cfg; /**< Power Amplifier configuration */ + ble_pa_lna_cfg_t lna_cfg; /**< Low Noise Amplifier configuration */ + + uint8_t ppi_ch_id_set; /**< PPI channel used for radio pin setting */ + uint8_t ppi_ch_id_clr; /**< PPI channel used for radio pin clearing */ + uint8_t gpiote_ch_id; /**< GPIOTE channel used for radio pin toggling */ +} ble_common_opt_pa_lna_t; + +/** + * @brief Configuration of extended BLE connection events. + * + * When enabled the SoftDevice will dynamically extend the connection event when possible. + * + * The connection event length is controlled by the connection configuration as set by @ref ble_gap_conn_cfg_t::event_length. + * The connection event can be extended if there is time to send another packet pair before the start of the next connection + * interval, and if there are no conflicts with other BLE roles requesting radio time. + * + * @note @ref sd_ble_opt_get is not supported for this option. + */ +typedef struct { + uint8_t enable : 1; /**< Enable extended BLE connection events, disabled by default. */ +} ble_common_opt_conn_evt_ext_t; + +/** + * @brief Enable/disable extended RC calibration. + * + * If extended RC calibration is enabled and the internal RC oscillator (@ref NRF_CLOCK_LF_SRC_RC) is used as the SoftDevice + * LFCLK source, the SoftDevice as a peripheral will by default try to increase the receive window if two consecutive packets + * are not received. If it turns out that the packets were not received due to clock drift, the RC calibration is started. + * This calibration comes in addition to the periodic calibration that is configured by @ref sd_softdevice_enable(). When + * using only peripheral connections, the periodic calibration can therefore be configured with a much longer interval as the + * peripheral will be able to detect and adjust automatically to clock drift, and calibrate on demand. + * + * If extended RC calibration is disabled and the internal RC oscillator is used as the SoftDevice LFCLK source, the + * RC oscillator is calibrated periodically as configured by @ref sd_softdevice_enable(). + * + * @note @ref sd_ble_opt_get is not supported for this option. + */ +typedef struct { + uint8_t enable : 1; /**< Enable extended RC calibration, enabled by default. */ +} ble_common_opt_extended_rc_cal_t; + +/**@brief Option structure for common options. */ +typedef union { + ble_common_opt_pa_lna_t pa_lna; /**< Parameters for controlling PA and LNA pin toggling. */ + ble_common_opt_conn_evt_ext_t conn_evt_ext; /**< Parameters for enabling extended connection events. */ + ble_common_opt_extended_rc_cal_t extended_rc_cal; /**< Parameters for enabling extended RC calibration. */ +} ble_common_opt_t; + +/**@brief Common BLE Option type, wrapping the module specific options. */ +typedef union { + ble_common_opt_t common_opt; /**< COMMON options, opt_id in @ref BLE_COMMON_OPTS series. */ + ble_gap_opt_t gap_opt; /**< GAP option, opt_id in @ref BLE_GAP_OPTS series. */ + ble_gattc_opt_t gattc_opt; /**< GATTC option, opt_id in @ref BLE_GATTC_OPTS series. */ +} ble_opt_t; + +/**@brief BLE connection configuration type, wrapping the module specific configurations, set with + * @ref sd_ble_cfg_set. + * + * @note Connection configurations don't have to be set. + * In the case that no configurations has been set, or fewer connection configurations has been set than enabled connections, + * the default connection configuration will be automatically added for the remaining connections. + * When creating connections with the default configuration, @ref BLE_CONN_CFG_TAG_DEFAULT should be used in + * place of @ref ble_conn_cfg_t::conn_cfg_tag. + * + * @sa sd_ble_gap_adv_start() + * @sa sd_ble_gap_connect() + * + * @mscs + * @mmsc{@ref BLE_CONN_CFG} + * @endmscs + + */ +typedef struct { + uint8_t conn_cfg_tag; /**< The application chosen tag it can use with the + @ref sd_ble_gap_adv_start() and @ref sd_ble_gap_connect() calls + to select this configuration when creating a connection. + Must be different for all connection configurations added and not @ref BLE_CONN_CFG_TAG_DEFAULT. */ + union { + ble_gap_conn_cfg_t gap_conn_cfg; /**< GAP connection configuration, cfg_id is @ref BLE_CONN_CFG_GAP. */ + ble_gattc_conn_cfg_t gattc_conn_cfg; /**< GATTC connection configuration, cfg_id is @ref BLE_CONN_CFG_GATTC. */ + ble_gatts_conn_cfg_t gatts_conn_cfg; /**< GATTS connection configuration, cfg_id is @ref BLE_CONN_CFG_GATTS. */ + ble_gatt_conn_cfg_t gatt_conn_cfg; /**< GATT connection configuration, cfg_id is @ref BLE_CONN_CFG_GATT. */ + ble_l2cap_conn_cfg_t l2cap_conn_cfg; /**< L2CAP connection configuration, cfg_id is @ref BLE_CONN_CFG_L2CAP. */ + } params; /**< Connection configuration union. */ +} ble_conn_cfg_t; + +/** + * @brief Configuration of Vendor Specific base UUIDs, set with @ref sd_ble_cfg_set. + * + * @retval ::NRF_ERROR_INVALID_PARAM Too many UUIDs configured. + */ +typedef struct { + uint8_t vs_uuid_count; /**< Number of 128-bit Vendor Specific base UUID bases to allocate memory for. + Default value is @ref BLE_UUID_VS_COUNT_DEFAULT. Maximum value is + @ref BLE_UUID_VS_COUNT_MAX. */ +} ble_common_cfg_vs_uuid_t; + +/**@brief Common BLE Configuration type, wrapping the common configurations. */ +typedef union { + ble_common_cfg_vs_uuid_t vs_uuid_cfg; /**< Vendor Specific base UUID configuration, cfg_id is @ref BLE_COMMON_CFG_VS_UUID. */ +} ble_common_cfg_t; + +/**@brief BLE Configuration type, wrapping the module specific configurations. */ +typedef union { + ble_conn_cfg_t conn_cfg; /**< Connection specific configurations, cfg_id in @ref BLE_CONN_CFGS series. */ + ble_common_cfg_t common_cfg; /**< Global common configurations, cfg_id in @ref BLE_COMMON_CFGS series. */ + ble_gap_cfg_t gap_cfg; /**< Global GAP configurations, cfg_id in @ref BLE_GAP_CFGS series. */ + ble_gatts_cfg_t gatts_cfg; /**< Global GATTS configuration, cfg_id in @ref BLE_GATTS_CFGS series. */ +} ble_cfg_t; + +/** @} */ + +/** @addtogroup BLE_COMMON_FUNCTIONS Functions + * @{ */ + +/**@brief Enable the BLE stack + * + * @param[in, out] p_app_ram_base Pointer to a variable containing the start address of the + * application RAM region (APP_RAM_BASE). On return, this will + * contain the minimum start address of the application RAM region + * required by the SoftDevice for this configuration. + * @warning After this call, the SoftDevice may generate several events. The list of events provided + * below require the application to initiate a SoftDevice API call. The corresponding API call + * is referenced in the event documentation. + * If the application fails to do so, the BLE connection may timeout, or the SoftDevice may stop + * communicating with the peer device. + * - @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST + * - @ref BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST + * - @ref BLE_GAP_EVT_PHY_UPDATE_REQUEST + * - @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST + * - @ref BLE_GAP_EVT_SEC_INFO_REQUEST + * - @ref BLE_GAP_EVT_SEC_REQUEST + * - @ref BLE_GAP_EVT_AUTH_KEY_REQUEST + * - @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST + * - @ref BLE_EVT_USER_MEM_REQUEST + * - @ref BLE_L2CAP_EVT_CH_SETUP_REQUEST + * + * @note The memory requirement for a specific configuration will not increase between SoftDevices + * with the same major version number. + * + * @note At runtime the IC's RAM is split into 2 regions: The SoftDevice RAM region is located + * between 0x20000000 and APP_RAM_BASE-1 and the application's RAM region is located between + * APP_RAM_BASE and the start of the call stack. + * + * @details This call initializes the BLE stack, no BLE related function other than @ref + * sd_ble_cfg_set can be called before this one. + * + * @mscs + * @mmsc{@ref BLE_COMMON_ENABLE} + * @endmscs + * + * @retval ::NRF_SUCCESS The BLE stack has been initialized successfully. + * @retval ::NRF_ERROR_INVALID_STATE The BLE stack had already been initialized and cannot be reinitialized. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. + * @retval ::NRF_ERROR_NO_MEM One or more of the following is true: + * - The amount of memory assigned to the SoftDevice by *p_app_ram_base is not + * large enough to fit this configuration's memory requirement. Check *p_app_ram_base + * and set the start address of the application RAM region accordingly. + * - Dynamic part of the SoftDevice RAM region is larger then 64 kB which + * is currently not supported. + * @retval ::NRF_ERROR_RESOURCES The total number of L2CAP Channels configured using @ref sd_ble_cfg_set is too large. + */ +SVCALL(SD_BLE_ENABLE, uint32_t, sd_ble_enable(uint32_t *p_app_ram_base)); + +/**@brief Add configurations for the BLE stack + * + * @param[in] cfg_id Config ID, see @ref BLE_CONN_CFGS, @ref BLE_COMMON_CFGS, @ref + * BLE_GAP_CFGS or @ref BLE_GATTS_CFGS. + * @param[in] p_cfg Pointer to a ble_cfg_t structure containing the configuration value. + * @param[in] app_ram_base The start address of the application RAM region (APP_RAM_BASE). + * See @ref sd_ble_enable for details about APP_RAM_BASE. + * + * @note The memory requirement for a specific configuration will not increase between SoftDevices + * with the same major version number. + * + * @note If a configuration is set more than once, the last one set is the one that takes effect on + * @ref sd_ble_enable. + * + * @note Any part of the BLE stack that is NOT configured with @ref sd_ble_cfg_set will have default + * configuration. + * + * @note @ref sd_ble_cfg_set may be called at any time when the SoftDevice is enabled (see @ref + * sd_softdevice_enable) while the BLE part of the SoftDevice is not enabled (see @ref + * sd_ble_enable). + * + * @note Error codes for the configurations are described in the configuration structs. + * + * @mscs + * @mmsc{@ref BLE_COMMON_ENABLE} + * @endmscs + * + * @retval ::NRF_SUCCESS The configuration has been added successfully. + * @retval ::NRF_ERROR_INVALID_STATE The BLE stack had already been initialized. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid cfg_id supplied. + * @retval ::NRF_ERROR_NO_MEM The amount of memory assigned to the SoftDevice by app_ram_base is not + * large enough to fit this configuration's memory requirement. + */ +SVCALL(SD_BLE_CFG_SET, uint32_t, sd_ble_cfg_set(uint32_t cfg_id, ble_cfg_t const *p_cfg, uint32_t app_ram_base)); + +/**@brief Get an event from the pending events queue. + * + * @param[out] p_dest Pointer to buffer to be filled in with an event, or NULL to retrieve the event length. + * This buffer must be aligned to the extend defined by @ref BLE_EVT_PTR_ALIGNMENT. + * The buffer should be interpreted as a @ref ble_evt_t struct. + * @param[in, out] p_len Pointer the length of the buffer, on return it is filled with the event length. + * + * @details This call allows the application to pull a BLE event from the BLE stack. The application is signaled that + * an event is available from the BLE stack by the triggering of the SD_EVT_IRQn interrupt. + * The application is free to choose whether to call this function from thread mode (main context) or directly from the + * Interrupt Service Routine that maps to SD_EVT_IRQn. In any case however, and because the BLE stack runs at a higher + * priority than the application, this function should be called in a loop (until @ref NRF_ERROR_NOT_FOUND is returned) + * every time SD_EVT_IRQn is raised to ensure that all available events are pulled from the BLE stack. Failure to do so + * could potentially leave events in the internal queue without the application being aware of this fact. + * + * Sizing the p_dest buffer is equally important, since the application needs to provide all the memory necessary for the event to + * be copied into application memory. If the buffer provided is not large enough to fit the entire contents of the event, + * @ref NRF_ERROR_DATA_SIZE will be returned and the application can then call again with a larger buffer size. + * The maximum possible event length is defined by @ref BLE_EVT_LEN_MAX. The application may also "peek" the event length + * by providing p_dest as a NULL pointer and inspecting the value of *p_len upon return: + * + * \code + * uint16_t len; + * errcode = sd_ble_evt_get(NULL, &len); + * \endcode + * + * @mscs + * @mmsc{@ref BLE_COMMON_IRQ_EVT_MSC} + * @mmsc{@ref BLE_COMMON_THREAD_EVT_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Event pulled and stored into the supplied buffer. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. + * @retval ::NRF_ERROR_NOT_FOUND No events ready to be pulled. + * @retval ::NRF_ERROR_DATA_SIZE Event ready but could not fit into the supplied buffer. + */ +SVCALL(SD_BLE_EVT_GET, uint32_t, sd_ble_evt_get(uint8_t *p_dest, uint16_t *p_len)); + +/**@brief Add a Vendor Specific base UUID. + * + * @details This call enables the application to add a Vendor Specific base UUID to the BLE stack's table, for later + * use with all other modules and APIs. This then allows the application to use the shorter, 24-bit @ref ble_uuid_t + * format when dealing with both 16-bit and 128-bit UUIDs without having to check for lengths and having split code + * paths. This is accomplished by extending the grouping mechanism that the Bluetooth SIG standard base UUID uses + * for all other 128-bit UUIDs. The type field in the @ref ble_uuid_t structure is an index (relative to + * @ref BLE_UUID_TYPE_VENDOR_BEGIN) to the table populated by multiple calls to this function, and the UUID field + * in the same structure contains the 2 bytes at indexes 12 and 13. The number of possible 128-bit UUIDs available to + * the application is therefore the number of Vendor Specific UUIDs added with the help of this function times 65536, + * although restricted to modifying bytes 12 and 13 for each of the entries in the supplied array. + * + * @note Bytes 12 and 13 of the provided UUID will not be used internally, since those are always replaced by + * the 16-bit uuid field in @ref ble_uuid_t. + * + * @note If a UUID is already present in the BLE stack's internal table, the corresponding index will be returned in + * p_uuid_type along with an @ref NRF_SUCCESS error code. + * + * @param[in] p_vs_uuid Pointer to a 16-octet (128-bit) little endian Vendor Specific base UUID disregarding + * bytes 12 and 13. + * @param[out] p_uuid_type Pointer to a uint8_t where the type field in @ref ble_uuid_t corresponding to this UUID will be + * stored. + * + * @retval ::NRF_SUCCESS Successfully added the Vendor Specific base UUID. + * @retval ::NRF_ERROR_INVALID_ADDR If p_vs_uuid or p_uuid_type is NULL or invalid. + * @retval ::NRF_ERROR_NO_MEM If there are no more free slots for VS UUIDs. + */ +SVCALL(SD_BLE_UUID_VS_ADD, uint32_t, sd_ble_uuid_vs_add(ble_uuid128_t const *p_vs_uuid, uint8_t *p_uuid_type)); + +/**@brief Remove a Vendor Specific base UUID. + * + * @details This call removes a Vendor Specific base UUID. This function allows + * the application to reuse memory allocated for Vendor Specific base UUIDs. + * + * @note Currently this function can only be called with a p_uuid_type set to @ref BLE_UUID_TYPE_UNKNOWN or the last added UUID + * type. + * + * @param[inout] p_uuid_type Pointer to a uint8_t where its value matches the UUID type in @ref ble_uuid_t::type to be removed. + * If the type is set to @ref BLE_UUID_TYPE_UNKNOWN, or the pointer is NULL, the last Vendor Specific + * base UUID will be removed. If the function returns successfully, the UUID type that was removed will + * be written back to @p p_uuid_type. If function returns with a failure, it contains the last type that + * is in use by the ATT Server. + * + * @retval ::NRF_SUCCESS Successfully removed the Vendor Specific base UUID. + * @retval ::NRF_ERROR_INVALID_ADDR If p_uuid_type is invalid. + * @retval ::NRF_ERROR_INVALID_PARAM If p_uuid_type points to a non-valid UUID type. + * @retval ::NRF_ERROR_FORBIDDEN If the Vendor Specific base UUID is in use by the ATT Server. + */ +SVCALL(SD_BLE_UUID_VS_REMOVE, uint32_t, sd_ble_uuid_vs_remove(uint8_t *p_uuid_type)); + +/** @brief Decode little endian raw UUID bytes (16-bit or 128-bit) into a 24 bit @ref ble_uuid_t structure. + * + * @details The raw UUID bytes excluding bytes 12 and 13 (i.e. bytes 0-11 and 14-15) of p_uuid_le are compared + * to the corresponding ones in each entry of the table of Vendor Specific base UUIDs + * to look for a match. If there is such a match, bytes 12 and 13 are returned as p_uuid->uuid and the index + * relative to @ref BLE_UUID_TYPE_VENDOR_BEGIN as p_uuid->type. + * + * @note If the UUID length supplied is 2, then the type set by this call will always be @ref BLE_UUID_TYPE_BLE. + * + * @param[in] uuid_le_len Length in bytes of the buffer pointed to by p_uuid_le (must be 2 or 16 bytes). + * @param[in] p_uuid_le Pointer pointing to little endian raw UUID bytes. + * @param[out] p_uuid Pointer to a @ref ble_uuid_t structure to be filled in. + * + * @retval ::NRF_SUCCESS Successfully decoded into the @ref ble_uuid_t structure. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_LENGTH Invalid UUID length. + * @retval ::NRF_ERROR_NOT_FOUND For a 128-bit UUID, no match in the populated table of UUIDs. + */ +SVCALL(SD_BLE_UUID_DECODE, uint32_t, sd_ble_uuid_decode(uint8_t uuid_le_len, uint8_t const *p_uuid_le, ble_uuid_t *p_uuid)); + +/** @brief Encode a @ref ble_uuid_t structure into little endian raw UUID bytes (16-bit or 128-bit). + * + * @note The pointer to the destination buffer p_uuid_le may be NULL, in which case only the validity and size of p_uuid is + * computed. + * + * @param[in] p_uuid Pointer to a @ref ble_uuid_t structure that will be encoded into bytes. + * @param[out] p_uuid_le_len Pointer to a uint8_t that will be filled with the encoded length (2 or 16 bytes). + * @param[out] p_uuid_le Pointer to a buffer where the little endian raw UUID bytes (2 or 16) will be stored. + * + * @retval ::NRF_SUCCESS Successfully encoded into the buffer. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid UUID type. + */ +SVCALL(SD_BLE_UUID_ENCODE, uint32_t, sd_ble_uuid_encode(ble_uuid_t const *p_uuid, uint8_t *p_uuid_le_len, uint8_t *p_uuid_le)); + +/**@brief Get Version Information. + * + * @details This call allows the application to get the BLE stack version information. + * + * @param[out] p_version Pointer to a ble_version_t structure to be filled in. + * + * @retval ::NRF_SUCCESS Version information stored successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY The BLE stack is busy (typically doing a locally-initiated disconnection procedure). + */ +SVCALL(SD_BLE_VERSION_GET, uint32_t, sd_ble_version_get(ble_version_t *p_version)); + +/**@brief Provide a user memory block. + * + * @note This call can only be used as a response to a @ref BLE_EVT_USER_MEM_REQUEST event issued to the application. + * + * @param[in] conn_handle Connection handle. + * @param[in] p_block Pointer to a user memory block structure or NULL if memory is managed by the application. + * + * @mscs + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_PEER_CANCEL_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_NOAUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Successfully queued a response to the peer. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_LENGTH Invalid user memory block length supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection state or no user memory request pending. + */ +SVCALL(SD_BLE_USER_MEM_REPLY, uint32_t, sd_ble_user_mem_reply(uint16_t conn_handle, ble_user_mem_block_t const *p_block)); + +/**@brief Set a BLE option. + * + * @details This call allows the application to set the value of an option. + * + * @param[in] opt_id Option ID, see @ref BLE_COMMON_OPTS, @ref BLE_GAP_OPTS, and @ref BLE_GATTC_OPTS. + * @param[in] p_opt Pointer to a @ref ble_opt_t structure containing the option value. + * + * @retval ::NRF_SUCCESS Option set successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. + * @retval ::NRF_ERROR_INVALID_STATE Unable to set the parameter at this time. + * @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed. + */ +SVCALL(SD_BLE_OPT_SET, uint32_t, sd_ble_opt_set(uint32_t opt_id, ble_opt_t const *p_opt)); + +/**@brief Get a BLE option. + * + * @details This call allows the application to retrieve the value of an option. + * + * @param[in] opt_id Option ID, see @ref BLE_COMMON_OPTS and @ref BLE_GAP_OPTS. + * @param[out] p_opt Pointer to a ble_opt_t structure to be filled in. + * + * @retval ::NRF_SUCCESS Option retrieved successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. + * @retval ::NRF_ERROR_INVALID_STATE Unable to retrieve the parameter at this time. + * @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed. + * @retval ::NRF_ERROR_NOT_SUPPORTED This option is not supported. + * + */ +SVCALL(SD_BLE_OPT_GET, uint32_t, sd_ble_opt_get(uint32_t opt_id, ble_opt_t *p_opt)); + +/** @} */ +#ifdef __cplusplus +} +#endif +#endif /* BLE_H__ */ + +/** + @} + @} +*/ diff --git a/variants/xiao_ble/softdevice/ble_err.h b/variants/xiao_ble/softdevice/ble_err.h new file mode 100644 index 000000000..d20f6d141 --- /dev/null +++ b/variants/xiao_ble/softdevice/ble_err.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + @addtogroup BLE_COMMON + @{ + @addtogroup nrf_error + @{ + @ingroup BLE_COMMON + @} + + @defgroup ble_err General error codes + @{ + + @brief General error code definitions for the BLE API. + + @ingroup BLE_COMMON +*/ +#ifndef NRF_BLE_ERR_H__ +#define NRF_BLE_ERR_H__ + +#include "nrf_error.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* @defgroup BLE_ERRORS Error Codes + * @{ */ +#define BLE_ERROR_NOT_ENABLED (NRF_ERROR_STK_BASE_NUM + 0x001) /**< @ref sd_ble_enable has not been called. */ +#define BLE_ERROR_INVALID_CONN_HANDLE (NRF_ERROR_STK_BASE_NUM + 0x002) /**< Invalid connection handle. */ +#define BLE_ERROR_INVALID_ATTR_HANDLE (NRF_ERROR_STK_BASE_NUM + 0x003) /**< Invalid attribute handle. */ +#define BLE_ERROR_INVALID_ADV_HANDLE (NRF_ERROR_STK_BASE_NUM + 0x004) /**< Invalid advertising handle. */ +#define BLE_ERROR_INVALID_ROLE (NRF_ERROR_STK_BASE_NUM + 0x005) /**< Invalid role. */ +#define BLE_ERROR_BLOCKED_BY_OTHER_LINKS \ + (NRF_ERROR_STK_BASE_NUM + 0x006) /**< The attempt to change link settings failed due to the scheduling of other links. */ +/** @} */ + +/** @defgroup BLE_ERROR_SUBRANGES Module specific error code subranges + * @brief Assignment of subranges for module specific error codes. + * @note For specific error codes, see ble_.h or ble_error_.h. + * @{ */ +#define NRF_L2CAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM + 0x100) /**< L2CAP specific errors. */ +#define NRF_GAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM + 0x200) /**< GAP specific errors. */ +#define NRF_GATTC_ERR_BASE (NRF_ERROR_STK_BASE_NUM + 0x300) /**< GATT client specific errors. */ +#define NRF_GATTS_ERR_BASE (NRF_ERROR_STK_BASE_NUM + 0x400) /**< GATT server specific errors. */ +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif + +/** + @} + @} +*/ diff --git a/variants/xiao_ble/softdevice/ble_gap.h b/variants/xiao_ble/softdevice/ble_gap.h new file mode 100644 index 000000000..8ebdfa82b --- /dev/null +++ b/variants/xiao_ble/softdevice/ble_gap.h @@ -0,0 +1,2895 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + @addtogroup BLE_GAP Generic Access Profile (GAP) + @{ + @brief Definitions and prototypes for the GAP interface. + */ + +#ifndef BLE_GAP_H__ +#define BLE_GAP_H__ + +#include "ble_err.h" +#include "ble_hci.h" +#include "ble_ranges.h" +#include "ble_types.h" +#include "nrf_error.h" +#include "nrf_svc.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@addtogroup BLE_GAP_ENUMERATIONS Enumerations + * @{ */ + +/**@brief GAP API SVC numbers. + */ +enum BLE_GAP_SVCS { + SD_BLE_GAP_ADDR_SET = BLE_GAP_SVC_BASE, /**< Set own Bluetooth Address. */ + SD_BLE_GAP_ADDR_GET = BLE_GAP_SVC_BASE + 1, /**< Get own Bluetooth Address. */ + SD_BLE_GAP_WHITELIST_SET = BLE_GAP_SVC_BASE + 2, /**< Set active whitelist. */ + SD_BLE_GAP_DEVICE_IDENTITIES_SET = BLE_GAP_SVC_BASE + 3, /**< Set device identity list. */ + SD_BLE_GAP_PRIVACY_SET = BLE_GAP_SVC_BASE + 4, /**< Set Privacy settings*/ + SD_BLE_GAP_PRIVACY_GET = BLE_GAP_SVC_BASE + 5, /**< Get Privacy settings*/ + SD_BLE_GAP_ADV_SET_CONFIGURE = BLE_GAP_SVC_BASE + 6, /**< Configure an advertising set. */ + SD_BLE_GAP_ADV_START = BLE_GAP_SVC_BASE + 7, /**< Start Advertising. */ + SD_BLE_GAP_ADV_STOP = BLE_GAP_SVC_BASE + 8, /**< Stop Advertising. */ + SD_BLE_GAP_CONN_PARAM_UPDATE = BLE_GAP_SVC_BASE + 9, /**< Connection Parameter Update. */ + SD_BLE_GAP_DISCONNECT = BLE_GAP_SVC_BASE + 10, /**< Disconnect. */ + SD_BLE_GAP_TX_POWER_SET = BLE_GAP_SVC_BASE + 11, /**< Set TX Power. */ + SD_BLE_GAP_APPEARANCE_SET = BLE_GAP_SVC_BASE + 12, /**< Set Appearance. */ + SD_BLE_GAP_APPEARANCE_GET = BLE_GAP_SVC_BASE + 13, /**< Get Appearance. */ + SD_BLE_GAP_PPCP_SET = BLE_GAP_SVC_BASE + 14, /**< Set PPCP. */ + SD_BLE_GAP_PPCP_GET = BLE_GAP_SVC_BASE + 15, /**< Get PPCP. */ + SD_BLE_GAP_DEVICE_NAME_SET = BLE_GAP_SVC_BASE + 16, /**< Set Device Name. */ + SD_BLE_GAP_DEVICE_NAME_GET = BLE_GAP_SVC_BASE + 17, /**< Get Device Name. */ + SD_BLE_GAP_AUTHENTICATE = BLE_GAP_SVC_BASE + 18, /**< Initiate Pairing/Bonding. */ + SD_BLE_GAP_SEC_PARAMS_REPLY = BLE_GAP_SVC_BASE + 19, /**< Reply with Security Parameters. */ + SD_BLE_GAP_AUTH_KEY_REPLY = BLE_GAP_SVC_BASE + 20, /**< Reply with an authentication key. */ + SD_BLE_GAP_LESC_DHKEY_REPLY = BLE_GAP_SVC_BASE + 21, /**< Reply with an LE Secure Connections DHKey. */ + SD_BLE_GAP_KEYPRESS_NOTIFY = BLE_GAP_SVC_BASE + 22, /**< Notify of a keypress during an authentication procedure. */ + SD_BLE_GAP_LESC_OOB_DATA_GET = BLE_GAP_SVC_BASE + 23, /**< Get the local LE Secure Connections OOB data. */ + SD_BLE_GAP_LESC_OOB_DATA_SET = BLE_GAP_SVC_BASE + 24, /**< Set the remote LE Secure Connections OOB data. */ + SD_BLE_GAP_ENCRYPT = BLE_GAP_SVC_BASE + 25, /**< Initiate encryption procedure. */ + SD_BLE_GAP_SEC_INFO_REPLY = BLE_GAP_SVC_BASE + 26, /**< Reply with Security Information. */ + SD_BLE_GAP_CONN_SEC_GET = BLE_GAP_SVC_BASE + 27, /**< Obtain connection security level. */ + SD_BLE_GAP_RSSI_START = BLE_GAP_SVC_BASE + 28, /**< Start reporting of changes in RSSI. */ + SD_BLE_GAP_RSSI_STOP = BLE_GAP_SVC_BASE + 29, /**< Stop reporting of changes in RSSI. */ + SD_BLE_GAP_SCAN_START = BLE_GAP_SVC_BASE + 30, /**< Start Scanning. */ + SD_BLE_GAP_SCAN_STOP = BLE_GAP_SVC_BASE + 31, /**< Stop Scanning. */ + SD_BLE_GAP_CONNECT = BLE_GAP_SVC_BASE + 32, /**< Connect. */ + SD_BLE_GAP_CONNECT_CANCEL = BLE_GAP_SVC_BASE + 33, /**< Cancel ongoing connection procedure. */ + SD_BLE_GAP_RSSI_GET = BLE_GAP_SVC_BASE + 34, /**< Get the last RSSI sample. */ + SD_BLE_GAP_PHY_UPDATE = BLE_GAP_SVC_BASE + 35, /**< Initiate or respond to a PHY Update Procedure. */ + SD_BLE_GAP_DATA_LENGTH_UPDATE = BLE_GAP_SVC_BASE + 36, /**< Initiate or respond to a Data Length Update Procedure. */ + SD_BLE_GAP_QOS_CHANNEL_SURVEY_START = BLE_GAP_SVC_BASE + 37, /**< Start Quality of Service (QoS) channel survey module. */ + SD_BLE_GAP_QOS_CHANNEL_SURVEY_STOP = BLE_GAP_SVC_BASE + 38, /**< Stop Quality of Service (QoS) channel survey module. */ + SD_BLE_GAP_ADV_ADDR_GET = BLE_GAP_SVC_BASE + 39, /**< Get the Address used on air while Advertising. */ + SD_BLE_GAP_NEXT_CONN_EVT_COUNTER_GET = BLE_GAP_SVC_BASE + 40, /**< Get the next connection event counter. */ + SD_BLE_GAP_CONN_EVT_TRIGGER_START = BLE_GAP_SVC_BASE + 41, /** Start triggering a given task on connection event start. */ + SD_BLE_GAP_CONN_EVT_TRIGGER_STOP = + BLE_GAP_SVC_BASE + 42, /** Stop triggering the task configured using @ref sd_ble_gap_conn_evt_trigger_start. */ +}; + +/**@brief GAP Event IDs. + * IDs that uniquely identify an event coming from the stack to the application. + */ +enum BLE_GAP_EVTS { + BLE_GAP_EVT_CONNECTED = + BLE_GAP_EVT_BASE, /**< Connected to peer. \n See @ref ble_gap_evt_connected_t */ + BLE_GAP_EVT_DISCONNECTED = + BLE_GAP_EVT_BASE + 1, /**< Disconnected from peer. \n See @ref ble_gap_evt_disconnected_t. */ + BLE_GAP_EVT_CONN_PARAM_UPDATE = + BLE_GAP_EVT_BASE + 2, /**< Connection Parameters updated. \n See @ref ble_gap_evt_conn_param_update_t. */ + BLE_GAP_EVT_SEC_PARAMS_REQUEST = + BLE_GAP_EVT_BASE + 3, /**< Request to provide security parameters. \n Reply with @ref sd_ble_gap_sec_params_reply. + \n See @ref ble_gap_evt_sec_params_request_t. */ + BLE_GAP_EVT_SEC_INFO_REQUEST = + BLE_GAP_EVT_BASE + 4, /**< Request to provide security information. \n Reply with @ref sd_ble_gap_sec_info_reply. + \n See @ref ble_gap_evt_sec_info_request_t. */ + BLE_GAP_EVT_PASSKEY_DISPLAY = + BLE_GAP_EVT_BASE + 5, /**< Request to display a passkey to the user. \n In LESC Numeric Comparison, reply with @ref + sd_ble_gap_auth_key_reply. \n See @ref ble_gap_evt_passkey_display_t. */ + BLE_GAP_EVT_KEY_PRESSED = + BLE_GAP_EVT_BASE + 6, /**< Notification of a keypress on the remote device.\n See @ref ble_gap_evt_key_pressed_t */ + BLE_GAP_EVT_AUTH_KEY_REQUEST = + BLE_GAP_EVT_BASE + 7, /**< Request to provide an authentication key. \n Reply with @ref sd_ble_gap_auth_key_reply. + \n See @ref ble_gap_evt_auth_key_request_t. */ + BLE_GAP_EVT_LESC_DHKEY_REQUEST = + BLE_GAP_EVT_BASE + 8, /**< Request to calculate an LE Secure Connections DHKey. \n Reply with @ref + sd_ble_gap_lesc_dhkey_reply. \n See @ref ble_gap_evt_lesc_dhkey_request_t */ + BLE_GAP_EVT_AUTH_STATUS = + BLE_GAP_EVT_BASE + 9, /**< Authentication procedure completed with status. \n See @ref ble_gap_evt_auth_status_t. */ + BLE_GAP_EVT_CONN_SEC_UPDATE = + BLE_GAP_EVT_BASE + 10, /**< Connection security updated. \n See @ref ble_gap_evt_conn_sec_update_t. */ + BLE_GAP_EVT_TIMEOUT = + BLE_GAP_EVT_BASE + 11, /**< Timeout expired. \n See @ref ble_gap_evt_timeout_t. */ + BLE_GAP_EVT_RSSI_CHANGED = + BLE_GAP_EVT_BASE + 12, /**< RSSI report. \n See @ref ble_gap_evt_rssi_changed_t. */ + BLE_GAP_EVT_ADV_REPORT = + BLE_GAP_EVT_BASE + 13, /**< Advertising report. \n See @ref ble_gap_evt_adv_report_t. */ + BLE_GAP_EVT_SEC_REQUEST = + BLE_GAP_EVT_BASE + 14, /**< Security Request. \n Reply with @ref sd_ble_gap_authenticate +\n or with @ref sd_ble_gap_encrypt if required security information is available +. \n See @ref ble_gap_evt_sec_request_t. */ + BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST = + BLE_GAP_EVT_BASE + 15, /**< Connection Parameter Update Request. \n Reply with @ref + sd_ble_gap_conn_param_update. \n See @ref ble_gap_evt_conn_param_update_request_t. */ + BLE_GAP_EVT_SCAN_REQ_REPORT = + BLE_GAP_EVT_BASE + 16, /**< Scan request report. \n See @ref ble_gap_evt_scan_req_report_t. */ + BLE_GAP_EVT_PHY_UPDATE_REQUEST = + BLE_GAP_EVT_BASE + 17, /**< PHY Update Request. \n Reply with @ref sd_ble_gap_phy_update. \n + See @ref ble_gap_evt_phy_update_request_t. */ + BLE_GAP_EVT_PHY_UPDATE = + BLE_GAP_EVT_BASE + 18, /**< PHY Update Procedure is complete. \n See @ref ble_gap_evt_phy_update_t. */ + BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST = + BLE_GAP_EVT_BASE + 19, /**< Data Length Update Request. \n Reply with @ref + sd_ble_gap_data_length_update. \n See @ref ble_gap_evt_data_length_update_request_t. */ + BLE_GAP_EVT_DATA_LENGTH_UPDATE = + BLE_GAP_EVT_BASE + + 20, /**< LL Data Channel PDU payload length updated. \n See @ref ble_gap_evt_data_length_update_t. */ + BLE_GAP_EVT_QOS_CHANNEL_SURVEY_REPORT = + BLE_GAP_EVT_BASE + + 21, /**< Channel survey report. \n See @ref ble_gap_evt_qos_channel_survey_report_t. */ + BLE_GAP_EVT_ADV_SET_TERMINATED = + BLE_GAP_EVT_BASE + + 22, /**< Advertising set terminated. \n See @ref ble_gap_evt_adv_set_terminated_t. */ +}; + +/**@brief GAP Option IDs. + * IDs that uniquely identify a GAP option. + */ +enum BLE_GAP_OPTS { + BLE_GAP_OPT_CH_MAP = BLE_GAP_OPT_BASE, /**< Channel Map. @ref ble_gap_opt_ch_map_t */ + BLE_GAP_OPT_LOCAL_CONN_LATENCY = BLE_GAP_OPT_BASE + 1, /**< Local connection latency. @ref ble_gap_opt_local_conn_latency_t */ + BLE_GAP_OPT_PASSKEY = BLE_GAP_OPT_BASE + 2, /**< Set passkey. @ref ble_gap_opt_passkey_t */ + BLE_GAP_OPT_COMPAT_MODE_1 = BLE_GAP_OPT_BASE + 3, /**< Compatibility mode. @ref ble_gap_opt_compat_mode_1_t */ + BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT = + BLE_GAP_OPT_BASE + 4, /**< Set Authenticated payload timeout. @ref ble_gap_opt_auth_payload_timeout_t */ + BLE_GAP_OPT_SLAVE_LATENCY_DISABLE = + BLE_GAP_OPT_BASE + 5, /**< Disable slave latency. @ref ble_gap_opt_slave_latency_disable_t */ +}; + +/**@brief GAP Configuration IDs. + * + * IDs that uniquely identify a GAP configuration. + */ +enum BLE_GAP_CFGS { + BLE_GAP_CFG_ROLE_COUNT = BLE_GAP_CFG_BASE, /**< Role count configuration. */ + BLE_GAP_CFG_DEVICE_NAME = BLE_GAP_CFG_BASE + 1, /**< Device name configuration. */ + BLE_GAP_CFG_PPCP_INCL_CONFIG = BLE_GAP_CFG_BASE + 2, /**< Peripheral Preferred Connection Parameters characteristic + inclusion configuration. */ + BLE_GAP_CFG_CAR_INCL_CONFIG = BLE_GAP_CFG_BASE + 3, /**< Central Address Resolution characteristic + inclusion configuration. */ +}; + +/**@brief GAP TX Power roles. + */ +enum BLE_GAP_TX_POWER_ROLES { + BLE_GAP_TX_POWER_ROLE_ADV = 1, /**< Advertiser role. */ + BLE_GAP_TX_POWER_ROLE_SCAN_INIT = 2, /**< Scanner and initiator role. */ + BLE_GAP_TX_POWER_ROLE_CONN = 3, /**< Connection role. */ +}; + +/** @} */ + +/**@addtogroup BLE_GAP_DEFINES Defines + * @{ */ + +/**@defgroup BLE_ERRORS_GAP SVC return values specific to GAP + * @{ */ +#define BLE_ERROR_GAP_UUID_LIST_MISMATCH \ + (NRF_GAP_ERR_BASE + 0x000) /**< UUID list does not contain an integral number of UUIDs. */ +#define BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST \ + (NRF_GAP_ERR_BASE + 0x001) /**< Use of Whitelist not permitted with discoverable advertising. */ +#define BLE_ERROR_GAP_INVALID_BLE_ADDR \ + (NRF_GAP_ERR_BASE + 0x002) /**< The upper two bits of the address do not correspond to the specified address type. */ +#define BLE_ERROR_GAP_WHITELIST_IN_USE \ + (NRF_GAP_ERR_BASE + 0x003) /**< Attempt to modify the whitelist while already in use by another operation. */ +#define BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE \ + (NRF_GAP_ERR_BASE + 0x004) /**< Attempt to modify the device identity list while already in use by another operation. */ +#define BLE_ERROR_GAP_DEVICE_IDENTITIES_DUPLICATE \ + (NRF_GAP_ERR_BASE + 0x005) /**< The device identity list contains entries with duplicate identity addresses. */ +/**@} */ + +/**@defgroup BLE_GAP_ROLES GAP Roles + * @{ */ +#define BLE_GAP_ROLE_INVALID 0x0 /**< Invalid Role. */ +#define BLE_GAP_ROLE_PERIPH 0x1 /**< Peripheral Role. */ +#define BLE_GAP_ROLE_CENTRAL 0x2 /**< Central Role. */ +/**@} */ + +/**@defgroup BLE_GAP_TIMEOUT_SOURCES GAP Timeout sources + * @{ */ +#define BLE_GAP_TIMEOUT_SRC_SCAN 0x01 /**< Scanning timeout. */ +#define BLE_GAP_TIMEOUT_SRC_CONN 0x02 /**< Connection timeout. */ +#define BLE_GAP_TIMEOUT_SRC_AUTH_PAYLOAD 0x03 /**< Authenticated payload timeout. */ +/**@} */ + +/**@defgroup BLE_GAP_ADDR_TYPES GAP Address types + * @{ */ +#define BLE_GAP_ADDR_TYPE_PUBLIC 0x00 /**< Public (identity) address.*/ +#define BLE_GAP_ADDR_TYPE_RANDOM_STATIC 0x01 /**< Random static (identity) address. */ +#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE 0x02 /**< Random private resolvable address. */ +#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE 0x03 /**< Random private non-resolvable address. */ +#define BLE_GAP_ADDR_TYPE_ANONYMOUS \ + 0x7F /**< An advertiser may advertise without its address. \ + This type of advertising is called anonymous. */ +/**@} */ + +/**@brief The default interval in seconds at which a private address is refreshed. */ +#define BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S (900) /* 15 minutes. */ +/**@brief The maximum interval in seconds at which a private address can be refreshed. */ +#define BLE_GAP_MAX_PRIVATE_ADDR_CYCLE_INTERVAL_S (41400) /* 11 hours 30 minutes. */ + +/** @brief BLE address length. */ +#define BLE_GAP_ADDR_LEN (6) + +/**@defgroup BLE_GAP_PRIVACY_MODES Privacy modes + * @{ */ +#define BLE_GAP_PRIVACY_MODE_OFF 0x00 /**< Device will send and accept its identity address for its own address. */ +#define BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY 0x01 /**< Device will send and accept only private addresses for its own address. */ +#define BLE_GAP_PRIVACY_MODE_NETWORK_PRIVACY \ + 0x02 /**< Device will send and accept only private addresses for its own address, \ + and will not accept a peer using identity address as sender address when \ + the peer IRK is exchanged, non-zero and added to the identity list. */ +/**@} */ + +/** @brief Invalid power level. */ +#define BLE_GAP_POWER_LEVEL_INVALID 127 + +/** @brief Advertising set handle not set. */ +#define BLE_GAP_ADV_SET_HANDLE_NOT_SET (0xFF) + +/** @brief The default number of advertising sets. */ +#define BLE_GAP_ADV_SET_COUNT_DEFAULT (1) + +/** @brief The maximum number of advertising sets supported by this SoftDevice. */ +#define BLE_GAP_ADV_SET_COUNT_MAX (1) + +/**@defgroup BLE_GAP_ADV_SET_DATA_SIZES Advertising data sizes. + * @{ */ +#define BLE_GAP_ADV_SET_DATA_SIZE_MAX \ + (31) /**< Maximum data length for an advertising set. \ + If more advertising data is required, use extended advertising instead. */ +#define BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_MAX_SUPPORTED \ + (255) /**< Maximum supported data length for an extended advertising set. */ + +#define BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_CONNECTABLE_MAX_SUPPORTED \ + (238) /**< Maximum supported data length for an extended connectable advertising set. */ +/**@}. */ + +/** @brief Set ID not available in advertising report. */ +#define BLE_GAP_ADV_REPORT_SET_ID_NOT_AVAILABLE 0xFF + +/**@defgroup BLE_GAP_EVT_ADV_SET_TERMINATED_REASON GAP Advertising Set Terminated reasons + * @{ */ +#define BLE_GAP_EVT_ADV_SET_TERMINATED_REASON_TIMEOUT 0x01 /**< Timeout value reached. */ +#define BLE_GAP_EVT_ADV_SET_TERMINATED_REASON_LIMIT_REACHED 0x02 /**< @ref ble_gap_adv_params_t::max_adv_evts was reached. */ +/**@} */ + +/**@defgroup BLE_GAP_AD_TYPE_DEFINITIONS GAP Advertising and Scan Response Data format + * @note Found at https://www.bluetooth.org/Technical/AssignedNumbers/generic_access_profile.htm + * @{ */ +#define BLE_GAP_AD_TYPE_FLAGS 0x01 /**< Flags for discoverability. */ +#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE 0x02 /**< Partial list of 16 bit service UUIDs. */ +#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE 0x03 /**< Complete list of 16 bit service UUIDs. */ +#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_MORE_AVAILABLE 0x04 /**< Partial list of 32 bit service UUIDs. */ +#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_COMPLETE 0x05 /**< Complete list of 32 bit service UUIDs. */ +#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE 0x06 /**< Partial list of 128 bit service UUIDs. */ +#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE 0x07 /**< Complete list of 128 bit service UUIDs. */ +#define BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME 0x08 /**< Short local device name. */ +#define BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME 0x09 /**< Complete local device name. */ +#define BLE_GAP_AD_TYPE_TX_POWER_LEVEL 0x0A /**< Transmit power level. */ +#define BLE_GAP_AD_TYPE_CLASS_OF_DEVICE 0x0D /**< Class of device. */ +#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C 0x0E /**< Simple Pairing Hash C. */ +#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R 0x0F /**< Simple Pairing Randomizer R. */ +#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE 0x10 /**< Security Manager TK Value. */ +#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS 0x11 /**< Security Manager Out Of Band Flags. */ +#define BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE 0x12 /**< Slave Connection Interval Range. */ +#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT 0x14 /**< List of 16-bit Service Solicitation UUIDs. */ +#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT 0x15 /**< List of 128-bit Service Solicitation UUIDs. */ +#define BLE_GAP_AD_TYPE_SERVICE_DATA 0x16 /**< Service Data - 16-bit UUID. */ +#define BLE_GAP_AD_TYPE_PUBLIC_TARGET_ADDRESS 0x17 /**< Public Target Address. */ +#define BLE_GAP_AD_TYPE_RANDOM_TARGET_ADDRESS 0x18 /**< Random Target Address. */ +#define BLE_GAP_AD_TYPE_APPEARANCE 0x19 /**< Appearance. */ +#define BLE_GAP_AD_TYPE_ADVERTISING_INTERVAL 0x1A /**< Advertising Interval. */ +#define BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS 0x1B /**< LE Bluetooth Device Address. */ +#define BLE_GAP_AD_TYPE_LE_ROLE 0x1C /**< LE Role. */ +#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C256 0x1D /**< Simple Pairing Hash C-256. */ +#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R256 0x1E /**< Simple Pairing Randomizer R-256. */ +#define BLE_GAP_AD_TYPE_SERVICE_DATA_32BIT_UUID 0x20 /**< Service Data - 32-bit UUID. */ +#define BLE_GAP_AD_TYPE_SERVICE_DATA_128BIT_UUID 0x21 /**< Service Data - 128-bit UUID. */ +#define BLE_GAP_AD_TYPE_LESC_CONFIRMATION_VALUE 0x22 /**< LE Secure Connections Confirmation Value */ +#define BLE_GAP_AD_TYPE_LESC_RANDOM_VALUE 0x23 /**< LE Secure Connections Random Value */ +#define BLE_GAP_AD_TYPE_URI 0x24 /**< URI */ +#define BLE_GAP_AD_TYPE_3D_INFORMATION_DATA 0x3D /**< 3D Information Data. */ +#define BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA 0xFF /**< Manufacturer Specific Data. */ +/**@} */ + +/**@defgroup BLE_GAP_ADV_FLAGS GAP Advertisement Flags + * @{ */ +#define BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE (0x01) /**< LE Limited Discoverable Mode. */ +#define BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE (0x02) /**< LE General Discoverable Mode. */ +#define BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED (0x04) /**< BR/EDR not supported. */ +#define BLE_GAP_ADV_FLAG_LE_BR_EDR_CONTROLLER (0x08) /**< Simultaneous LE and BR/EDR, Controller. */ +#define BLE_GAP_ADV_FLAG_LE_BR_EDR_HOST (0x10) /**< Simultaneous LE and BR/EDR, Host. */ +#define BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE \ + (BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE | \ + BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) /**< LE Limited Discoverable Mode, BR/EDR not supported. */ +#define BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE \ + (BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE | \ + BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) /**< LE General Discoverable Mode, BR/EDR not supported. */ +/**@} */ + +/**@defgroup BLE_GAP_ADV_INTERVALS GAP Advertising interval max and min + * @{ */ +#define BLE_GAP_ADV_INTERVAL_MIN 0x000020 /**< Minimum Advertising interval in 625 us units, i.e. 20 ms. */ +#define BLE_GAP_ADV_INTERVAL_MAX 0x004000 /**< Maximum Advertising interval in 625 us units, i.e. 10.24 s. */ + /**@} */ + +/**@defgroup BLE_GAP_SCAN_INTERVALS GAP Scan interval max and min + * @{ */ +#define BLE_GAP_SCAN_INTERVAL_MIN 0x0004 /**< Minimum Scan interval in 625 us units, i.e. 2.5 ms. */ +#define BLE_GAP_SCAN_INTERVAL_MAX 0xFFFF /**< Maximum Scan interval in 625 us units, i.e. 40,959.375 s. */ + /** @} */ + +/**@defgroup BLE_GAP_SCAN_WINDOW GAP Scan window max and min + * @{ */ +#define BLE_GAP_SCAN_WINDOW_MIN 0x0004 /**< Minimum Scan window in 625 us units, i.e. 2.5 ms. */ +#define BLE_GAP_SCAN_WINDOW_MAX 0xFFFF /**< Maximum Scan window in 625 us units, i.e. 40,959.375 s. */ + /** @} */ + +/**@defgroup BLE_GAP_SCAN_TIMEOUT GAP Scan timeout max and min + * @{ */ +#define BLE_GAP_SCAN_TIMEOUT_MIN 0x0001 /**< Minimum Scan timeout in 10 ms units, i.e 10 ms. */ +#define BLE_GAP_SCAN_TIMEOUT_UNLIMITED 0x0000 /**< Continue to scan forever. */ + /** @} */ + +/**@defgroup BLE_GAP_SCAN_BUFFER_SIZE GAP Minimum scanner buffer size + * + * Scan buffers are used for storing advertising data received from an advertiser. + * If ble_gap_scan_params_t::extended is set to 0, @ref BLE_GAP_SCAN_BUFFER_MIN is the minimum scan buffer length. + * else the minimum scan buffer size is @ref BLE_GAP_SCAN_BUFFER_EXTENDED_MIN. + * @{ */ +#define BLE_GAP_SCAN_BUFFER_MIN \ + (31) /**< Minimum data length for an \ + advertising set. */ +#define BLE_GAP_SCAN_BUFFER_MAX \ + (31) /**< Maximum data length for an \ + advertising set. */ +#define BLE_GAP_SCAN_BUFFER_EXTENDED_MIN \ + (255) /**< Minimum data length for an \ + extended advertising set. */ +#define BLE_GAP_SCAN_BUFFER_EXTENDED_MAX \ + (1650) /**< Maximum data length for an \ + extended advertising set. */ +#define BLE_GAP_SCAN_BUFFER_EXTENDED_MAX_SUPPORTED \ + (255) /**< Maximum supported data length for \ + an extended advertising set. */ +/** @} */ + +/**@defgroup BLE_GAP_ADV_TYPES GAP Advertising types + * + * Advertising types defined in Bluetooth Core Specification v5.0, Vol 6, Part B, Section 4.4.2. + * + * The maximum advertising data length is defined by @ref BLE_GAP_ADV_SET_DATA_SIZE_MAX. + * The maximum supported data length for an extended advertiser is defined by + * @ref BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_MAX_SUPPORTED + * Note that some of the advertising types do not support advertising data. Non-scannable types do not support + * scan response data. + * + * @{ */ +#define BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED \ + 0x01 /**< Connectable and scannable undirected \ + advertising events. */ +#define BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED_HIGH_DUTY_CYCLE \ + 0x02 /**< Connectable non-scannable directed advertising \ + events. Advertising interval is less that 3.75 ms. \ + Use this type for fast reconnections. \ + @note Advertising data is not supported. */ +#define BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED \ + 0x03 /**< Connectable non-scannable directed advertising \ + events. \ + @note Advertising data is not supported. */ +#define BLE_GAP_ADV_TYPE_NONCONNECTABLE_SCANNABLE_UNDIRECTED \ + 0x04 /**< Non-connectable scannable undirected \ + advertising events. */ +#define BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED \ + 0x05 /**< Non-connectable non-scannable undirected \ + advertising events. */ +#define BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_UNDIRECTED \ + 0x06 /**< Connectable non-scannable undirected advertising \ + events using extended advertising PDUs. */ +#define BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_DIRECTED \ + 0x07 /**< Connectable non-scannable directed advertising \ + events using extended advertising PDUs. */ +#define BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_SCANNABLE_UNDIRECTED \ + 0x08 /**< Non-connectable scannable undirected advertising \ + events using extended advertising PDUs. \ + @note Only scan response data is supported. */ +#define BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_SCANNABLE_DIRECTED \ + 0x09 /**< Non-connectable scannable directed advertising \ + events using extended advertising PDUs. \ + @note Only scan response data is supported. */ +#define BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED \ + 0x0A /**< Non-connectable non-scannable undirected advertising \ + events using extended advertising PDUs. */ +#define BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_NONSCANNABLE_DIRECTED \ + 0x0B /**< Non-connectable non-scannable directed advertising \ + events using extended advertising PDUs. */ +/**@} */ + +/**@defgroup BLE_GAP_ADV_FILTER_POLICIES GAP Advertising filter policies + * @{ */ +#define BLE_GAP_ADV_FP_ANY 0x00 /**< Allow scan requests and connect requests from any device. */ +#define BLE_GAP_ADV_FP_FILTER_SCANREQ 0x01 /**< Filter scan requests with whitelist. */ +#define BLE_GAP_ADV_FP_FILTER_CONNREQ 0x02 /**< Filter connect requests with whitelist. */ +#define BLE_GAP_ADV_FP_FILTER_BOTH 0x03 /**< Filter both scan and connect requests with whitelist. */ +/**@} */ + +/**@defgroup BLE_GAP_ADV_DATA_STATUS GAP Advertising data status + * @{ */ +#define BLE_GAP_ADV_DATA_STATUS_COMPLETE 0x00 /**< All data in the advertising event have been received. */ +#define BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA \ + 0x01 /**< More data to be received. \ + @note This value will only be used if \ + @ref ble_gap_scan_params_t::report_incomplete_evts and \ + @ref ble_gap_adv_report_type_t::extended_pdu are set to true. */ +#define BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_TRUNCATED \ + 0x02 /**< Incomplete data. Buffer size insufficient to receive more. \ + @note This value will only be used if \ + @ref ble_gap_adv_report_type_t::extended_pdu is set to true. */ +#define BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MISSED \ + 0x03 /**< Failed to receive the remaining data. \ + @note This value will only be used if \ + @ref ble_gap_adv_report_type_t::extended_pdu is set to true. */ +/**@} */ + +/**@defgroup BLE_GAP_SCAN_FILTER_POLICIES GAP Scanner filter policies + * @{ */ +#define BLE_GAP_SCAN_FP_ACCEPT_ALL \ + 0x00 /**< Accept all advertising packets except directed advertising packets \ + not addressed to this device. */ +#define BLE_GAP_SCAN_FP_WHITELIST \ + 0x01 /**< Accept advertising packets from devices in the whitelist except directed \ + packets not addressed to this device. */ +#define BLE_GAP_SCAN_FP_ALL_NOT_RESOLVED_DIRECTED \ + 0x02 /**< Accept all advertising packets specified in @ref BLE_GAP_SCAN_FP_ACCEPT_ALL. \ + In addition, accept directed advertising packets, where the advertiser's \ + address is a resolvable private address that cannot be resolved. */ +#define BLE_GAP_SCAN_FP_WHITELIST_NOT_RESOLVED_DIRECTED \ + 0x03 /**< Accept all advertising packets specified in @ref BLE_GAP_SCAN_FP_WHITELIST. \ + In addition, accept directed advertising packets, where the advertiser's \ + address is a resolvable private address that cannot be resolved. */ +/**@} */ + +/**@defgroup BLE_GAP_ADV_TIMEOUT_VALUES GAP Advertising timeout values in 10 ms units + * @{ */ +#define BLE_GAP_ADV_TIMEOUT_HIGH_DUTY_MAX \ + (128) /**< Maximum high duty advertising time in 10 ms units. Corresponds to 1.28 s. \ + */ +#define BLE_GAP_ADV_TIMEOUT_LIMITED_MAX \ + (18000) /**< Maximum advertising time in 10 ms units corresponding to TGAP(lim_adv_timeout) = 180 s in limited discoverable \ + mode. */ +#define BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED \ + (0) /**< Unlimited advertising in general discoverable mode. \ + For high duty cycle advertising, this corresponds to @ref BLE_GAP_ADV_TIMEOUT_HIGH_DUTY_MAX. */ +/**@} */ + +/**@defgroup BLE_GAP_DISC_MODES GAP Discovery modes + * @{ */ +#define BLE_GAP_DISC_MODE_NOT_DISCOVERABLE 0x00 /**< Not discoverable discovery Mode. */ +#define BLE_GAP_DISC_MODE_LIMITED 0x01 /**< Limited Discovery Mode. */ +#define BLE_GAP_DISC_MODE_GENERAL 0x02 /**< General Discovery Mode. */ +/**@} */ + +/**@defgroup BLE_GAP_IO_CAPS GAP IO Capabilities + * @{ */ +#define BLE_GAP_IO_CAPS_DISPLAY_ONLY 0x00 /**< Display Only. */ +#define BLE_GAP_IO_CAPS_DISPLAY_YESNO 0x01 /**< Display and Yes/No entry. */ +#define BLE_GAP_IO_CAPS_KEYBOARD_ONLY 0x02 /**< Keyboard Only. */ +#define BLE_GAP_IO_CAPS_NONE 0x03 /**< No I/O capabilities. */ +#define BLE_GAP_IO_CAPS_KEYBOARD_DISPLAY 0x04 /**< Keyboard and Display. */ +/**@} */ + +/**@defgroup BLE_GAP_AUTH_KEY_TYPES GAP Authentication Key Types + * @{ */ +#define BLE_GAP_AUTH_KEY_TYPE_NONE 0x00 /**< No key (may be used to reject). */ +#define BLE_GAP_AUTH_KEY_TYPE_PASSKEY 0x01 /**< 6-digit Passkey. */ +#define BLE_GAP_AUTH_KEY_TYPE_OOB 0x02 /**< Out Of Band data. */ +/**@} */ + +/**@defgroup BLE_GAP_KP_NOT_TYPES GAP Keypress Notification Types + * @{ */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_START 0x00 /**< Passkey entry started. */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_DIGIT_IN 0x01 /**< Passkey digit entered. */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_DIGIT_OUT 0x02 /**< Passkey digit erased. */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_CLEAR 0x03 /**< Passkey cleared. */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_END 0x04 /**< Passkey entry completed. */ +/**@} */ + +/**@defgroup BLE_GAP_SEC_STATUS GAP Security status + * @{ */ +#define BLE_GAP_SEC_STATUS_SUCCESS 0x00 /**< Procedure completed with success. */ +#define BLE_GAP_SEC_STATUS_TIMEOUT 0x01 /**< Procedure timed out. */ +#define BLE_GAP_SEC_STATUS_PDU_INVALID 0x02 /**< Invalid PDU received. */ +#define BLE_GAP_SEC_STATUS_RFU_RANGE1_BEGIN 0x03 /**< Reserved for Future Use range #1 begin. */ +#define BLE_GAP_SEC_STATUS_RFU_RANGE1_END 0x80 /**< Reserved for Future Use range #1 end. */ +#define BLE_GAP_SEC_STATUS_PASSKEY_ENTRY_FAILED 0x81 /**< Passkey entry failed (user canceled or other). */ +#define BLE_GAP_SEC_STATUS_OOB_NOT_AVAILABLE 0x82 /**< Out of Band Key not available. */ +#define BLE_GAP_SEC_STATUS_AUTH_REQ 0x83 /**< Authentication requirements not met. */ +#define BLE_GAP_SEC_STATUS_CONFIRM_VALUE 0x84 /**< Confirm value failed. */ +#define BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP 0x85 /**< Pairing not supported. */ +#define BLE_GAP_SEC_STATUS_ENC_KEY_SIZE 0x86 /**< Encryption key size. */ +#define BLE_GAP_SEC_STATUS_SMP_CMD_UNSUPPORTED 0x87 /**< Unsupported SMP command. */ +#define BLE_GAP_SEC_STATUS_UNSPECIFIED 0x88 /**< Unspecified reason. */ +#define BLE_GAP_SEC_STATUS_REPEATED_ATTEMPTS 0x89 /**< Too little time elapsed since last attempt. */ +#define BLE_GAP_SEC_STATUS_INVALID_PARAMS 0x8A /**< Invalid parameters. */ +#define BLE_GAP_SEC_STATUS_DHKEY_FAILURE 0x8B /**< DHKey check failure. */ +#define BLE_GAP_SEC_STATUS_NUM_COMP_FAILURE 0x8C /**< Numeric Comparison failure. */ +#define BLE_GAP_SEC_STATUS_BR_EDR_IN_PROG 0x8D /**< BR/EDR pairing in progress. */ +#define BLE_GAP_SEC_STATUS_X_TRANS_KEY_DISALLOWED 0x8E /**< BR/EDR Link Key cannot be used for LE keys. */ +#define BLE_GAP_SEC_STATUS_RFU_RANGE2_BEGIN 0x8F /**< Reserved for Future Use range #2 begin. */ +#define BLE_GAP_SEC_STATUS_RFU_RANGE2_END 0xFF /**< Reserved for Future Use range #2 end. */ +/**@} */ + +/**@defgroup BLE_GAP_SEC_STATUS_SOURCES GAP Security status sources + * @{ */ +#define BLE_GAP_SEC_STATUS_SOURCE_LOCAL 0x00 /**< Local failure. */ +#define BLE_GAP_SEC_STATUS_SOURCE_REMOTE 0x01 /**< Remote failure. */ +/**@} */ + +/**@defgroup BLE_GAP_CP_LIMITS GAP Connection Parameters Limits + * @{ */ +#define BLE_GAP_CP_MIN_CONN_INTVL_NONE 0xFFFF /**< No new minimum connection interval specified in connect parameters. */ +#define BLE_GAP_CP_MIN_CONN_INTVL_MIN \ + 0x0006 /**< Lowest minimum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */ +#define BLE_GAP_CP_MIN_CONN_INTVL_MAX \ + 0x0C80 /**< Highest minimum connection interval permitted, in units of 1.25 ms, i.e. 4 s. \ + */ +#define BLE_GAP_CP_MAX_CONN_INTVL_NONE 0xFFFF /**< No new maximum connection interval specified in connect parameters. */ +#define BLE_GAP_CP_MAX_CONN_INTVL_MIN \ + 0x0006 /**< Lowest maximum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */ +#define BLE_GAP_CP_MAX_CONN_INTVL_MAX \ + 0x0C80 /**< Highest maximum connection interval permitted, in units of 1.25 ms, i.e. 4 s. \ + */ +#define BLE_GAP_CP_SLAVE_LATENCY_MAX 0x01F3 /**< Highest slave latency permitted, in connection events. */ +#define BLE_GAP_CP_CONN_SUP_TIMEOUT_NONE 0xFFFF /**< No new supervision timeout specified in connect parameters. */ +#define BLE_GAP_CP_CONN_SUP_TIMEOUT_MIN 0x000A /**< Lowest supervision timeout permitted, in units of 10 ms, i.e. 100 ms. */ +#define BLE_GAP_CP_CONN_SUP_TIMEOUT_MAX 0x0C80 /**< Highest supervision timeout permitted, in units of 10 ms, i.e. 32 s. */ +/**@} */ + +/**@defgroup BLE_GAP_DEVNAME GAP device name defines. + * @{ */ +#define BLE_GAP_DEVNAME_DEFAULT "nRF5x" /**< Default device name value. */ +#define BLE_GAP_DEVNAME_DEFAULT_LEN 31 /**< Default number of octets in device name. */ +#define BLE_GAP_DEVNAME_MAX_LEN 248 /**< Maximum number of octets in device name. */ +/**@} */ + +/**@brief Disable RSSI events for connections */ +#define BLE_GAP_RSSI_THRESHOLD_INVALID 0xFF + +/**@defgroup BLE_GAP_PHYS GAP PHYs + * @{ */ +#define BLE_GAP_PHY_AUTO 0x00 /**< Automatic PHY selection. Refer @ref sd_ble_gap_phy_update for more information.*/ +#define BLE_GAP_PHY_1MBPS 0x01 /**< 1 Mbps PHY. */ +#define BLE_GAP_PHY_2MBPS 0x02 /**< 2 Mbps PHY. */ +#define BLE_GAP_PHY_CODED 0x04 /**< Coded PHY. */ +#define BLE_GAP_PHY_NOT_SET 0xFF /**< PHY is not configured. */ + +/**@brief Supported PHYs in connections, for scanning, and for advertising. */ +#define BLE_GAP_PHYS_SUPPORTED (BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS | BLE_GAP_PHY_CODED) /**< All PHYs are supported. */ + +/**@} */ + +/**@defgroup BLE_GAP_CONN_SEC_MODE_SET_MACROS GAP attribute security requirement setters + * + * See @ref ble_gap_conn_sec_mode_t. + * @{ */ +/**@brief Set sec_mode pointed to by ptr to have no access rights.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(ptr) \ + do { \ + (ptr)->sm = 0; \ + (ptr)->lv = 0; \ + } while (0) +/**@brief Set sec_mode pointed to by ptr to require no protection, open link.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_OPEN(ptr) \ + do { \ + (ptr)->sm = 1; \ + (ptr)->lv = 1; \ + } while (0) +/**@brief Set sec_mode pointed to by ptr to require encryption, but no MITM protection.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(ptr) \ + do { \ + (ptr)->sm = 1; \ + (ptr)->lv = 2; \ + } while (0) +/**@brief Set sec_mode pointed to by ptr to require encryption and MITM protection.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(ptr) \ + do { \ + (ptr)->sm = 1; \ + (ptr)->lv = 3; \ + } while (0) +/**@brief Set sec_mode pointed to by ptr to require LESC encryption and MITM protection.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_LESC_ENC_WITH_MITM(ptr) \ + do { \ + (ptr)->sm = 1; \ + (ptr)->lv = 4; \ + } while (0) +/**@brief Set sec_mode pointed to by ptr to require signing or encryption, no MITM protection needed.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(ptr) \ + do { \ + (ptr)->sm = 2; \ + (ptr)->lv = 1; \ + } while (0) +/**@brief Set sec_mode pointed to by ptr to require signing or encryption with MITM protection.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(ptr) \ + do { \ + (ptr)->sm = 2; \ + (ptr)->lv = 2; \ + } while (0) +/**@} */ + +/**@brief GAP Security Random Number Length. */ +#define BLE_GAP_SEC_RAND_LEN 8 + +/**@brief GAP Security Key Length. */ +#define BLE_GAP_SEC_KEY_LEN 16 + +/**@brief GAP LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Public Key Length. */ +#define BLE_GAP_LESC_P256_PK_LEN 64 + +/**@brief GAP LE Secure Connections Elliptic Curve Diffie-Hellman DHKey Length. */ +#define BLE_GAP_LESC_DHKEY_LEN 32 + +/**@brief GAP Passkey Length. */ +#define BLE_GAP_PASSKEY_LEN 6 + +/**@brief Maximum amount of addresses in the whitelist. */ +#define BLE_GAP_WHITELIST_ADDR_MAX_COUNT (8) + +/**@brief Maximum amount of identities in the device identities list. */ +#define BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT (8) + +/**@brief Default connection count for a configuration. */ +#define BLE_GAP_CONN_COUNT_DEFAULT (1) + +/**@defgroup BLE_GAP_EVENT_LENGTH GAP event length defines. + * @{ */ +#define BLE_GAP_EVENT_LENGTH_MIN (2) /**< Minimum event length, in 1.25 ms units. */ +#define BLE_GAP_EVENT_LENGTH_CODED_PHY_MIN (6) /**< The shortest event length in 1.25 ms units supporting LE Coded PHY. */ +#define BLE_GAP_EVENT_LENGTH_DEFAULT (3) /**< Default event length, in 1.25 ms units. */ +/**@} */ + +/**@defgroup BLE_GAP_ROLE_COUNT GAP concurrent connection count defines. + * @{ */ +#define BLE_GAP_ROLE_COUNT_PERIPH_DEFAULT (1) /**< Default maximum number of connections concurrently acting as peripherals. */ +#define BLE_GAP_ROLE_COUNT_CENTRAL_DEFAULT (3) /**< Default maximum number of connections concurrently acting as centrals. */ +#define BLE_GAP_ROLE_COUNT_CENTRAL_SEC_DEFAULT \ + (1) /**< Default number of SMP instances shared between all connections acting as centrals. */ +#define BLE_GAP_ROLE_COUNT_COMBINED_MAX \ + (20) /**< Maximum supported number of concurrent connections in the peripheral and central roles combined. */ + +/**@} */ + +/**@brief Automatic data length parameter. */ +#define BLE_GAP_DATA_LENGTH_AUTO 0 + +/**@defgroup BLE_GAP_AUTH_PAYLOAD_TIMEOUT Authenticated payload timeout defines. + * @{ */ +#define BLE_GAP_AUTH_PAYLOAD_TIMEOUT_MAX (48000) /**< Maximum authenticated payload timeout in 10 ms units, i.e. 8 minutes. */ +#define BLE_GAP_AUTH_PAYLOAD_TIMEOUT_MIN (1) /**< Minimum authenticated payload timeout in 10 ms units, i.e. 10 ms. */ +/**@} */ + +/**@defgroup GAP_SEC_MODES GAP Security Modes + * @{ */ +#define BLE_GAP_SEC_MODE 0x00 /**< No key (may be used to reject). */ +/**@} */ + +/**@brief The total number of channels in Bluetooth Low Energy. */ +#define BLE_GAP_CHANNEL_COUNT (40) + +/**@defgroup BLE_GAP_QOS_CHANNEL_SURVEY_INTERVALS Quality of Service (QoS) Channel survey interval defines + * @{ */ +#define BLE_GAP_QOS_CHANNEL_SURVEY_INTERVAL_CONTINUOUS (0) /**< Continuous channel survey. */ +#define BLE_GAP_QOS_CHANNEL_SURVEY_INTERVAL_MIN_US (7500) /**< Minimum channel survey interval in microseconds (7.5 ms). */ +#define BLE_GAP_QOS_CHANNEL_SURVEY_INTERVAL_MAX_US (4000000) /**< Maximum channel survey interval in microseconds (4 s). */ + /**@} */ + +/** @} */ + +/** @defgroup BLE_GAP_CHAR_INCL_CONFIG GAP Characteristic inclusion configurations + * @{ + */ +#define BLE_GAP_CHAR_INCL_CONFIG_INCLUDE (0) /**< Include the characteristic in the Attribute Table */ +#define BLE_GAP_CHAR_INCL_CONFIG_EXCLUDE_WITH_SPACE \ + (1) /**< Do not include the characteristic in the Attribute table. \ + The SoftDevice will reserve the attribute handles \ + which are otherwise used for this characteristic. \ + By reserving the attribute handles it will be possible \ + to upgrade the SoftDevice without changing handle of the \ + Service Changed characteristic. */ +#define BLE_GAP_CHAR_INCL_CONFIG_EXCLUDE_WITHOUT_SPACE \ + (2) /**< Do not include the characteristic in the Attribute table. \ + The SoftDevice will not reserve the attribute handles \ + which are otherwise used for this characteristic. */ +/**@} */ + +/** @defgroup BLE_GAP_CHAR_INCL_CONFIG_DEFAULTS Characteristic inclusion default values + * @{ */ +#define BLE_GAP_PPCP_INCL_CONFIG_DEFAULT (BLE_GAP_CHAR_INCL_CONFIG_INCLUDE) /**< Included by default. */ +#define BLE_GAP_CAR_INCL_CONFIG_DEFAULT (BLE_GAP_CHAR_INCL_CONFIG_INCLUDE) /**< Included by default. */ +/**@} */ + +/** @defgroup BLE_GAP_SLAVE_LATENCY Slave latency configuration options + * @{ */ +#define BLE_GAP_SLAVE_LATENCY_ENABLE \ + (0) /**< Slave latency is enabled. When slave latency is enabled, \ + the slave will wake up every time it has data to send, \ + and/or every slave latency number of connection events. */ +#define BLE_GAP_SLAVE_LATENCY_DISABLE \ + (1) /**< Disable slave latency. The slave will wake up every connection event \ + regardless of the requested slave latency. \ + This option consumes the most power. */ +#define BLE_GAP_SLAVE_LATENCY_WAIT_FOR_ACK \ + (2) /**< The slave will wake up every connection event if it has not received \ + an ACK from the master for at least slave latency events. This \ + configuration may increase the power consumption in environments \ + with a lot of radio activity. */ +/**@} */ + +/**@addtogroup BLE_GAP_STRUCTURES Structures + * @{ */ + +/**@brief Advertising event properties. */ +typedef struct { + uint8_t type; /**< Advertising type. See @ref BLE_GAP_ADV_TYPES. */ + uint8_t anonymous : 1; /**< Omit advertiser's address from all PDUs. + @note Anonymous advertising is only available for + @ref BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED and + @ref BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_NONSCANNABLE_DIRECTED. */ + uint8_t include_tx_power : 1; /**< This feature is not supported on this SoftDevice. */ +} ble_gap_adv_properties_t; + +/**@brief Advertising report type. */ +typedef struct { + uint16_t connectable : 1; /**< Connectable advertising event type. */ + uint16_t scannable : 1; /**< Scannable advertising event type. */ + uint16_t directed : 1; /**< Directed advertising event type. */ + uint16_t scan_response : 1; /**< Received a scan response. */ + uint16_t extended_pdu : 1; /**< Received an extended advertising set. */ + uint16_t status : 2; /**< Data status. See @ref BLE_GAP_ADV_DATA_STATUS. */ + uint16_t reserved : 9; /**< Reserved for future use. */ +} ble_gap_adv_report_type_t; + +/**@brief Advertising Auxiliary Pointer. */ +typedef struct { + uint16_t aux_offset; /**< Time offset from the beginning of advertising packet to the auxiliary packet in 100 us units. */ + uint8_t aux_phy; /**< Indicates the PHY on which the auxiliary advertising packet is sent. See @ref BLE_GAP_PHYS. */ +} ble_gap_aux_pointer_t; + +/**@brief Bluetooth Low Energy address. */ +typedef struct { + uint8_t + addr_id_peer : 1; /**< Only valid for peer addresses. + This bit is set by the SoftDevice to indicate whether the address has been resolved from + a Resolvable Private Address (when the peer is using privacy). + If set to 1, @ref addr and @ref addr_type refer to the identity address of the resolved address. + + This bit is ignored when a variable of type @ref ble_gap_addr_t is used as input to API functions. + */ + uint8_t addr_type : 7; /**< See @ref BLE_GAP_ADDR_TYPES. */ + uint8_t addr[BLE_GAP_ADDR_LEN]; /**< 48-bit address, LSB format. + @ref addr is not used if @ref addr_type is @ref BLE_GAP_ADDR_TYPE_ANONYMOUS. */ +} ble_gap_addr_t; + +/**@brief GAP connection parameters. + * + * @note When ble_conn_params_t is received in an event, both min_conn_interval and + * max_conn_interval will be equal to the connection interval set by the central. + * + * @note If both conn_sup_timeout and max_conn_interval are specified, then the following constraint applies: + * conn_sup_timeout * 4 > (1 + slave_latency) * max_conn_interval + * that corresponds to the following Bluetooth Spec requirement: + * The Supervision_Timeout in milliseconds shall be larger than + * (1 + Conn_Latency) * Conn_Interval_Max * 2, where Conn_Interval_Max is given in milliseconds. + */ +typedef struct { + uint16_t min_conn_interval; /**< Minimum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/ + uint16_t max_conn_interval; /**< Maximum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/ + uint16_t slave_latency; /**< Slave Latency in number of connection events, see @ref BLE_GAP_CP_LIMITS.*/ + uint16_t conn_sup_timeout; /**< Connection Supervision Timeout in 10 ms units, see @ref BLE_GAP_CP_LIMITS.*/ +} ble_gap_conn_params_t; + +/**@brief GAP connection security modes. + * + * Security Mode 0 Level 0: No access permissions at all (this level is not defined by the Bluetooth Core specification).\n + * Security Mode 1 Level 1: No security is needed (aka open link).\n + * Security Mode 1 Level 2: Encrypted link required, MITM protection not necessary.\n + * Security Mode 1 Level 3: MITM protected encrypted link required.\n + * Security Mode 1 Level 4: LESC MITM protected encrypted link using a 128-bit strength encryption key required.\n + * Security Mode 2 Level 1: Signing or encryption required, MITM protection not necessary.\n + * Security Mode 2 Level 2: MITM protected signing required, unless link is MITM protected encrypted.\n + */ +typedef struct { + uint8_t sm : 4; /**< Security Mode (1 or 2), 0 for no permissions at all. */ + uint8_t lv : 4; /**< Level (1, 2, 3 or 4), 0 for no permissions at all. */ + +} ble_gap_conn_sec_mode_t; + +/**@brief GAP connection security status.*/ +typedef struct { + ble_gap_conn_sec_mode_t sec_mode; /**< Currently active security mode for this connection.*/ + uint8_t + encr_key_size; /**< Length of currently active encryption key, 7 to 16 octets (only applicable for bonding procedures). */ +} ble_gap_conn_sec_t; + +/**@brief Identity Resolving Key. */ +typedef struct { + uint8_t irk[BLE_GAP_SEC_KEY_LEN]; /**< Array containing IRK. */ +} ble_gap_irk_t; + +/**@brief Channel mask (40 bits). + * Every channel is represented with a bit positioned as per channel index defined in Bluetooth Core Specification v5.0, + * Vol 6, Part B, Section 1.4.1. The LSB contained in array element 0 represents channel index 0, and bit 39 represents + * channel index 39. If a bit is set to 1, the channel is not used. + */ +typedef uint8_t ble_gap_ch_mask_t[5]; + +/**@brief GAP advertising parameters. */ +typedef struct { + ble_gap_adv_properties_t properties; /**< The properties of the advertising events. */ + ble_gap_addr_t const *p_peer_addr; /**< Address of a known peer. + @note ble_gap_addr_t::addr_type cannot be + @ref BLE_GAP_ADDR_TYPE_ANONYMOUS. + - When privacy is enabled and the local device uses + @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE addresses, + the device identity list is searched for a matching entry. If + the local IRK for that device identity is set, the local IRK + for that device will be used to generate the advertiser address + field in the advertising packet. + - If @ref ble_gap_adv_properties_t::type is directed, this must be + set to the targeted scanner or initiator. If the peer address is + in the device identity list, the peer IRK for that device will be + used to generate @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE + target addresses used in the advertising event PDUs. */ + uint32_t interval; /**< Advertising interval in 625 us units. @sa BLE_GAP_ADV_INTERVALS. + @note If @ref ble_gap_adv_properties_t::type is set to + @ref BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED_HIGH_DUTY_CYCLE + advertising, this parameter is ignored. */ + uint16_t duration; /**< Advertising duration in 10 ms units. When timeout is reached, + an event of type @ref BLE_GAP_EVT_ADV_SET_TERMINATED is raised. + @sa BLE_GAP_ADV_TIMEOUT_VALUES. + @note The SoftDevice will always complete at least one advertising + event even if the duration is set too low. */ + uint8_t max_adv_evts; /**< Maximum advertising events that shall be sent prior to disabling + advertising. Setting the value to 0 disables the limitation. When + the count of advertising events specified by this parameter + (if not 0) is reached, advertising will be automatically stopped + and an event of type @ref BLE_GAP_EVT_ADV_SET_TERMINATED is raised + @note If @ref ble_gap_adv_properties_t::type is set to + @ref BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED_HIGH_DUTY_CYCLE, + this parameter is ignored. */ + ble_gap_ch_mask_t channel_mask; /**< Channel mask for primary and secondary advertising channels. + At least one of the primary channels, that is channel index 37-39, must be used. + Masking away secondary advertising channels is not supported. */ + uint8_t filter_policy; /**< Filter Policy. @sa BLE_GAP_ADV_FILTER_POLICIES. */ + uint8_t primary_phy; /**< Indicates the PHY on which the primary advertising channel packets + are transmitted. If set to @ref BLE_GAP_PHY_AUTO, @ref BLE_GAP_PHY_1MBPS + will be used. + Valid values are @ref BLE_GAP_PHY_1MBPS and @ref BLE_GAP_PHY_CODED. + @note The primary_phy shall indicate @ref BLE_GAP_PHY_1MBPS if + @ref ble_gap_adv_properties_t::type is not an extended advertising type. */ + uint8_t secondary_phy; /**< Indicates the PHY on which the secondary advertising channel packets + are transmitted. + If set to @ref BLE_GAP_PHY_AUTO, @ref BLE_GAP_PHY_1MBPS will be used. + Valid values are + @ref BLE_GAP_PHY_1MBPS, @ref BLE_GAP_PHY_2MBPS, and @ref BLE_GAP_PHY_CODED. + If @ref ble_gap_adv_properties_t::type is an extended advertising type + and connectable, this is the PHY that will be used to establish a + connection and send AUX_ADV_IND packets on. + @note This parameter will be ignored when + @ref ble_gap_adv_properties_t::type is not an extended advertising type. */ + uint8_t set_id : 4; /**< The advertising set identifier distinguishes this advertising set from other + advertising sets transmitted by this and other devices. + @note This parameter will be ignored when + @ref ble_gap_adv_properties_t::type is not an extended advertising type. */ + uint8_t scan_req_notification : 1; /**< Enable scan request notifications for this advertising set. When a + scan request is received and the scanner address is allowed + by the filter policy, @ref BLE_GAP_EVT_SCAN_REQ_REPORT is raised. + @note This parameter will be ignored when + @ref ble_gap_adv_properties_t::type is a non-scannable + advertising type. */ +} ble_gap_adv_params_t; + +/**@brief GAP advertising data buffers. + * + * The application must provide the buffers for advertisement. The memory shall reside in application RAM, and + * shall never be modified while advertising. The data shall be kept alive until either: + * - @ref BLE_GAP_EVT_ADV_SET_TERMINATED is raised. + * - @ref BLE_GAP_EVT_CONNECTED is raised with @ref ble_gap_evt_connected_t::adv_handle set to the corresponding + * advertising handle. + * - Advertising is stopped. + * - Advertising data is changed. + * To update advertising data while advertising, provide new buffers to @ref sd_ble_gap_adv_set_configure. */ +typedef struct { + ble_data_t adv_data; /**< Advertising data. + @note + Advertising data can only be specified for a @ref ble_gap_adv_properties_t::type + that is allowed to contain advertising data. */ + ble_data_t scan_rsp_data; /**< Scan response data. + @note + Scan response data can only be specified for a @ref ble_gap_adv_properties_t::type + that is scannable. */ +} ble_gap_adv_data_t; + +/**@brief GAP scanning parameters. */ +typedef struct { + uint8_t extended : 1; /**< If 1, the scanner will accept extended advertising packets. + If set to 0, the scanner will not receive advertising packets + on secondary advertising channels, and will not be able + to receive long advertising PDUs. */ + uint8_t report_incomplete_evts : 1; /**< If 1, events of type @ref ble_gap_evt_adv_report_t may have + @ref ble_gap_adv_report_type_t::status set to + @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA. + This parameter is ignored when used with @ref sd_ble_gap_connect + @note This may be used to abort receiving more packets from an extended + advertising event, and is only available for extended + scanning, see @ref sd_ble_gap_scan_start. + @note This feature is not supported by this SoftDevice. */ + uint8_t active : 1; /**< If 1, perform active scanning by sending scan requests. + This parameter is ignored when used with @ref sd_ble_gap_connect. */ + uint8_t filter_policy : 2; /**< Scanning filter policy. @sa BLE_GAP_SCAN_FILTER_POLICIES. + @note Only @ref BLE_GAP_SCAN_FP_ACCEPT_ALL and + @ref BLE_GAP_SCAN_FP_WHITELIST are valid when used with + @ref sd_ble_gap_connect */ + uint8_t scan_phys; /**< Bitfield of PHYs to scan on. If set to @ref BLE_GAP_PHY_AUTO, + scan_phys will default to @ref BLE_GAP_PHY_1MBPS. + - If @ref ble_gap_scan_params_t::extended is set to 0, the only + supported PHY is @ref BLE_GAP_PHY_1MBPS. + - When used with @ref sd_ble_gap_scan_start, + the bitfield indicates the PHYs the scanner will use for scanning + on primary advertising channels. The scanner will accept + @ref BLE_GAP_PHYS_SUPPORTED as secondary advertising channel PHYs. + - When used with @ref sd_ble_gap_connect, the bitfield indicates + the PHYs the initiator will use for scanning on primary advertising + channels. The initiator will accept connections initiated on either + of the @ref BLE_GAP_PHYS_SUPPORTED PHYs. + If scan_phys contains @ref BLE_GAP_PHY_1MBPS and/or @ref BLE_GAP_PHY_2MBPS, + the primary scan PHY is @ref BLE_GAP_PHY_1MBPS. + If scan_phys also contains @ref BLE_GAP_PHY_CODED, the primary scan + PHY will also contain @ref BLE_GAP_PHY_CODED. If the only scan PHY is + @ref BLE_GAP_PHY_CODED, the primary scan PHY is + @ref BLE_GAP_PHY_CODED only. */ + uint16_t interval; /**< Scan interval in 625 us units. @sa BLE_GAP_SCAN_INTERVALS. */ + uint16_t window; /**< Scan window in 625 us units. @sa BLE_GAP_SCAN_WINDOW. + If scan_phys contains both @ref BLE_GAP_PHY_1MBPS and + @ref BLE_GAP_PHY_CODED interval shall be larger than or + equal to twice the scan window. */ + uint16_t timeout; /**< Scan timeout in 10 ms units. @sa BLE_GAP_SCAN_TIMEOUT. */ + ble_gap_ch_mask_t channel_mask; /**< Channel mask for primary and secondary advertising channels. + At least one of the primary channels, that is channel index 37-39, must be + set to 0. + Masking away secondary channels is not supported. */ +} ble_gap_scan_params_t; + +/**@brief Privacy. + * + * The privacy feature provides a way for the device to avoid being tracked over a period of time. + * The privacy feature, when enabled, hides the local device identity and replaces it with a private address + * that is automatically refreshed at a specified interval. + * + * If a device still wants to be recognized by other peers, it needs to share it's Identity Resolving Key (IRK). + * With this key, a device can generate a random private address that can only be recognized by peers in possession of that + * key, and devices can establish connections without revealing their real identities. + * + * Both network privacy (@ref BLE_GAP_PRIVACY_MODE_NETWORK_PRIVACY) and device privacy (@ref + * BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY) are supported. + * + * @note If the device IRK is updated, the new IRK becomes the one to be distributed in all + * bonding procedures performed after @ref sd_ble_gap_privacy_set returns. + * The IRK distributed during bonding procedure is the device IRK that is active when @ref sd_ble_gap_sec_params_reply is + * called. + */ +typedef struct { + uint8_t privacy_mode; /**< Privacy mode, see @ref BLE_GAP_PRIVACY_MODES. Default is @ref BLE_GAP_PRIVACY_MODE_OFF. */ + uint8_t private_addr_type; /**< The private address type must be either @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE or + @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE. */ + uint16_t private_addr_cycle_s; /**< Private address cycle interval in seconds. Providing an address cycle value of 0 will use + the default value defined by @ref BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S. */ + ble_gap_irk_t + *p_device_irk; /**< When used as input, pointer to IRK structure that will be used as the default IRK. If NULL, the device + default IRK will be used. When used as output, pointer to IRK structure where the current default IRK + will be written to. If NULL, this argument is ignored. By default, the default IRK is used to generate + random private resolvable addresses for the local device unless instructed otherwise. */ +} ble_gap_privacy_params_t; + +/**@brief PHY preferences for TX and RX + * @note tx_phys and rx_phys are bit fields. Multiple bits can be set in them to indicate multiple preferred PHYs for each + * direction. + * @code + * p_gap_phys->tx_phys = BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS; + * p_gap_phys->rx_phys = BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS; + * @endcode + * + */ +typedef struct { + uint8_t tx_phys; /**< Preferred transmit PHYs, see @ref BLE_GAP_PHYS. */ + uint8_t rx_phys; /**< Preferred receive PHYs, see @ref BLE_GAP_PHYS. */ +} ble_gap_phys_t; + +/** @brief Keys that can be exchanged during a bonding procedure. */ +typedef struct { + uint8_t enc : 1; /**< Long Term Key and Master Identification. */ + uint8_t id : 1; /**< Identity Resolving Key and Identity Address Information. */ + uint8_t sign : 1; /**< Connection Signature Resolving Key. */ + uint8_t link : 1; /**< Derive the Link Key from the LTK. */ +} ble_gap_sec_kdist_t; + +/**@brief GAP security parameters. */ +typedef struct { + uint8_t bond : 1; /**< Perform bonding. */ + uint8_t mitm : 1; /**< Enable Man In The Middle protection. */ + uint8_t lesc : 1; /**< Enable LE Secure Connection pairing. */ + uint8_t keypress : 1; /**< Enable generation of keypress notifications. */ + uint8_t io_caps : 3; /**< IO capabilities, see @ref BLE_GAP_IO_CAPS. */ + uint8_t oob : 1; /**< The OOB data flag. + - In LE legacy pairing, this flag is set if a device has out of band authentication data. + The OOB method is used if both of the devices have out of band authentication data. + - In LE Secure Connections pairing, this flag is set if a device has the peer device's out of band + authentication data. The OOB method is used if at least one device has the peer device's OOB data + available. */ + uint8_t + min_key_size; /**< Minimum encryption key size in octets between 7 and 16. If 0 then not applicable in this instance. */ + uint8_t max_key_size; /**< Maximum encryption key size in octets between min_key_size and 16. */ + ble_gap_sec_kdist_t kdist_own; /**< Key distribution bitmap: keys that the local device will distribute. */ + ble_gap_sec_kdist_t kdist_peer; /**< Key distribution bitmap: keys that the remote device will distribute. */ +} ble_gap_sec_params_t; + +/**@brief GAP Encryption Information. */ +typedef struct { + uint8_t ltk[BLE_GAP_SEC_KEY_LEN]; /**< Long Term Key. */ + uint8_t lesc : 1; /**< Key generated using LE Secure Connections. */ + uint8_t auth : 1; /**< Authenticated Key. */ + uint8_t ltk_len : 6; /**< LTK length in octets. */ +} ble_gap_enc_info_t; + +/**@brief GAP Master Identification. */ +typedef struct { + uint16_t ediv; /**< Encrypted Diversifier. */ + uint8_t rand[BLE_GAP_SEC_RAND_LEN]; /**< Random Number. */ +} ble_gap_master_id_t; + +/**@brief GAP Signing Information. */ +typedef struct { + uint8_t csrk[BLE_GAP_SEC_KEY_LEN]; /**< Connection Signature Resolving Key. */ +} ble_gap_sign_info_t; + +/**@brief GAP LE Secure Connections P-256 Public Key. */ +typedef struct { + uint8_t pk[BLE_GAP_LESC_P256_PK_LEN]; /**< LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Public Key. Stored in the + standard SMP protocol format: {X,Y} both in little-endian. */ +} ble_gap_lesc_p256_pk_t; + +/**@brief GAP LE Secure Connections DHKey. */ +typedef struct { + uint8_t key[BLE_GAP_LESC_DHKEY_LEN]; /**< LE Secure Connections Elliptic Curve Diffie-Hellman Key. Stored in little-endian. */ +} ble_gap_lesc_dhkey_t; + +/**@brief GAP LE Secure Connections OOB data. */ +typedef struct { + ble_gap_addr_t addr; /**< Bluetooth address of the device. */ + uint8_t r[BLE_GAP_SEC_KEY_LEN]; /**< Random Number. */ + uint8_t c[BLE_GAP_SEC_KEY_LEN]; /**< Confirm Value. */ +} ble_gap_lesc_oob_data_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_CONNECTED. */ +typedef struct { + ble_gap_addr_t + peer_addr; /**< Bluetooth address of the peer device. If the peer_addr resolved: @ref + ble_gap_addr_t::addr_id_peer is set to 1 and the address is the device's identity address. */ + uint8_t role; /**< BLE role for this connection, see @ref BLE_GAP_ROLES */ + ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */ + uint8_t adv_handle; /**< Advertising handle in which advertising has ended. + This variable is only set if role is set to @ref BLE_GAP_ROLE_PERIPH. */ + ble_gap_adv_data_t adv_data; /**< Advertising buffers corresponding to the terminated + advertising set. The advertising buffers provided in + @ref sd_ble_gap_adv_set_configure are now released. + This variable is only set if role is set to @ref BLE_GAP_ROLE_PERIPH. */ +} ble_gap_evt_connected_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_DISCONNECTED. */ +typedef struct { + uint8_t reason; /**< HCI error code, see @ref BLE_HCI_STATUS_CODES. */ +} ble_gap_evt_disconnected_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_CONN_PARAM_UPDATE. */ +typedef struct { + ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */ +} ble_gap_evt_conn_param_update_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_PHY_UPDATE_REQUEST. */ +typedef struct { + ble_gap_phys_t peer_preferred_phys; /**< The PHYs the peer prefers to use. */ +} ble_gap_evt_phy_update_request_t; + +/**@brief Event Structure for @ref BLE_GAP_EVT_PHY_UPDATE. */ +typedef struct { + uint8_t status; /**< Status of the procedure, see @ref BLE_HCI_STATUS_CODES.*/ + uint8_t tx_phy; /**< TX PHY for this connection, see @ref BLE_GAP_PHYS. */ + uint8_t rx_phy; /**< RX PHY for this connection, see @ref BLE_GAP_PHYS. */ +} ble_gap_evt_phy_update_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST. */ +typedef struct { + ble_gap_sec_params_t peer_params; /**< Initiator Security Parameters. */ +} ble_gap_evt_sec_params_request_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_SEC_INFO_REQUEST. */ +typedef struct { + ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. */ + ble_gap_master_id_t master_id; /**< Master Identification for LTK lookup. */ + uint8_t enc_info : 1; /**< If 1, Encryption Information required. */ + uint8_t id_info : 1; /**< If 1, Identity Information required. */ + uint8_t sign_info : 1; /**< If 1, Signing Information required. */ +} ble_gap_evt_sec_info_request_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_PASSKEY_DISPLAY. */ +typedef struct { + uint8_t passkey[BLE_GAP_PASSKEY_LEN]; /**< 6-digit passkey in ASCII ('0'-'9' digits only). */ + uint8_t match_request : 1; /**< If 1 requires the application to report the match using @ref sd_ble_gap_auth_key_reply + with either @ref BLE_GAP_AUTH_KEY_TYPE_NONE if there is no match or + @ref BLE_GAP_AUTH_KEY_TYPE_PASSKEY if there is a match. */ +} ble_gap_evt_passkey_display_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_KEY_PRESSED. */ +typedef struct { + uint8_t kp_not; /**< Keypress notification type, see @ref BLE_GAP_KP_NOT_TYPES. */ +} ble_gap_evt_key_pressed_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_AUTH_KEY_REQUEST. */ +typedef struct { + uint8_t key_type; /**< See @ref BLE_GAP_AUTH_KEY_TYPES. */ +} ble_gap_evt_auth_key_request_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST. */ +typedef struct { + ble_gap_lesc_p256_pk_t + *p_pk_peer; /**< LE Secure Connections remote P-256 Public Key. This will point to the application-supplied memory + inside the keyset during the call to @ref sd_ble_gap_sec_params_reply. */ + uint8_t oobd_req : 1; /**< LESC OOB data required. A call to @ref sd_ble_gap_lesc_oob_data_set is required to complete the + procedure. */ +} ble_gap_evt_lesc_dhkey_request_t; + +/**@brief Security levels supported. + * @note See Bluetooth Specification Version 4.2 Volume 3, Part C, Chapter 10, Section 10.2.1. + */ +typedef struct { + uint8_t lv1 : 1; /**< If 1: Level 1 is supported. */ + uint8_t lv2 : 1; /**< If 1: Level 2 is supported. */ + uint8_t lv3 : 1; /**< If 1: Level 3 is supported. */ + uint8_t lv4 : 1; /**< If 1: Level 4 is supported. */ +} ble_gap_sec_levels_t; + +/**@brief Encryption Key. */ +typedef struct { + ble_gap_enc_info_t enc_info; /**< Encryption Information. */ + ble_gap_master_id_t master_id; /**< Master Identification. */ +} ble_gap_enc_key_t; + +/**@brief Identity Key. */ +typedef struct { + ble_gap_irk_t id_info; /**< Identity Resolving Key. */ + ble_gap_addr_t id_addr_info; /**< Identity Address. */ +} ble_gap_id_key_t; + +/**@brief Security Keys. */ +typedef struct { + ble_gap_enc_key_t *p_enc_key; /**< Encryption Key, or NULL. */ + ble_gap_id_key_t *p_id_key; /**< Identity Key, or NULL. */ + ble_gap_sign_info_t *p_sign_key; /**< Signing Key, or NULL. */ + ble_gap_lesc_p256_pk_t *p_pk; /**< LE Secure Connections P-256 Public Key. When in debug mode the application must use the + value defined in the Core Bluetooth Specification v4.2 Vol.3, Part H, Section 2.3.5.6.1 */ +} ble_gap_sec_keys_t; + +/**@brief Security key set for both local and peer keys. */ +typedef struct { + ble_gap_sec_keys_t keys_own; /**< Keys distributed by the local device. For LE Secure Connections the encryption key will be + generated locally and will always be stored if bonding. */ + ble_gap_sec_keys_t + keys_peer; /**< Keys distributed by the remote device. For LE Secure Connections, p_enc_key must always be NULL. */ +} ble_gap_sec_keyset_t; + +/**@brief Data Length Update Procedure parameters. */ +typedef struct { + uint16_t max_tx_octets; /**< Maximum number of payload octets that a Controller supports for transmission of a single Link + Layer Data Channel PDU. */ + uint16_t max_rx_octets; /**< Maximum number of payload octets that a Controller supports for reception of a single Link Layer + Data Channel PDU. */ + uint16_t max_tx_time_us; /**< Maximum time, in microseconds, that a Controller supports for transmission of a single Link + Layer Data Channel PDU. */ + uint16_t max_rx_time_us; /**< Maximum time, in microseconds, that a Controller supports for reception of a single Link Layer + Data Channel PDU. */ +} ble_gap_data_length_params_t; + +/**@brief Data Length Update Procedure local limitation. */ +typedef struct { + uint16_t tx_payload_limited_octets; /**< If > 0, the requested TX packet length is too long by this many octets. */ + uint16_t rx_payload_limited_octets; /**< If > 0, the requested RX packet length is too long by this many octets. */ + uint16_t tx_rx_time_limited_us; /**< If > 0, the requested combination of TX and RX packet lengths is too long by this many + microseconds. */ +} ble_gap_data_length_limitation_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_AUTH_STATUS. */ +typedef struct { + uint8_t auth_status; /**< Authentication status, see @ref BLE_GAP_SEC_STATUS. */ + uint8_t error_src : 2; /**< On error, source that caused the failure, see @ref BLE_GAP_SEC_STATUS_SOURCES. */ + uint8_t bonded : 1; /**< Procedure resulted in a bond. */ + uint8_t lesc : 1; /**< Procedure resulted in a LE Secure Connection. */ + ble_gap_sec_levels_t sm1_levels; /**< Levels supported in Security Mode 1. */ + ble_gap_sec_levels_t sm2_levels; /**< Levels supported in Security Mode 2. */ + ble_gap_sec_kdist_t kdist_own; /**< Bitmap stating which keys were exchanged (distributed) by the local device. If bonding + with LE Secure Connections, the enc bit will be always set. */ + ble_gap_sec_kdist_t kdist_peer; /**< Bitmap stating which keys were exchanged (distributed) by the remote device. If bonding + with LE Secure Connections, the enc bit will never be set. */ +} ble_gap_evt_auth_status_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_CONN_SEC_UPDATE. */ +typedef struct { + ble_gap_conn_sec_t conn_sec; /**< Connection security level. */ +} ble_gap_evt_conn_sec_update_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_TIMEOUT. */ +typedef struct { + uint8_t src; /**< Source of timeout event, see @ref BLE_GAP_TIMEOUT_SOURCES. */ + union { + ble_data_t adv_report_buffer; /**< If source is set to @ref BLE_GAP_TIMEOUT_SRC_SCAN, the released + scan buffer is contained in this field. */ + } params; /**< Event Parameters. */ +} ble_gap_evt_timeout_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_RSSI_CHANGED. */ +typedef struct { + int8_t rssi; /**< Received Signal Strength Indication in dBm. + @note ERRATA-153 and ERRATA-225 require the rssi sample to be compensated based on a temperature + measurement. */ + uint8_t ch_index; /**< Data Channel Index on which the Signal Strength is measured (0-36). */ +} ble_gap_evt_rssi_changed_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_ADV_SET_TERMINATED */ +typedef struct { + uint8_t reason; /**< Reason for why the advertising set terminated. See + @ref BLE_GAP_EVT_ADV_SET_TERMINATED_REASON. */ + uint8_t adv_handle; /**< Advertising handle in which advertising has ended. */ + uint8_t num_completed_adv_events; /**< If @ref ble_gap_adv_params_t::max_adv_evts was not set to 0, + this field indicates the number of completed advertising events. */ + ble_gap_adv_data_t adv_data; /**< Advertising buffers corresponding to the terminated + advertising set. The advertising buffers provided in + @ref sd_ble_gap_adv_set_configure are now released. */ +} ble_gap_evt_adv_set_terminated_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_ADV_REPORT. + * + * @note If @ref ble_gap_adv_report_type_t::status is set to @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA, + * not all fields in the advertising report may be available. + * + * @note When ble_gap_adv_report_type_t::status is not set to @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA, + * scanning will be paused. To continue scanning, call @ref sd_ble_gap_scan_start. + */ +typedef struct { + ble_gap_adv_report_type_t type; /**< Advertising report type. See @ref ble_gap_adv_report_type_t. */ + ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr is resolved: + @ref ble_gap_addr_t::addr_id_peer is set to 1 and the address is the + peer's identity address. */ + ble_gap_addr_t direct_addr; /**< Contains the target address of the advertising event if + @ref ble_gap_adv_report_type_t::directed is set to 1. If the + SoftDevice was able to resolve the address, + @ref ble_gap_addr_t::addr_id_peer is set to 1 and the direct_addr + contains the local identity address. If the target address of the + advertising event is @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE, + and the SoftDevice was unable to resolve it, the application may try + to resolve this address to find out if the advertising event was + directed to us. */ + uint8_t primary_phy; /**< Indicates the PHY on which the primary advertising packet was received. + See @ref BLE_GAP_PHYS. */ + uint8_t secondary_phy; /**< Indicates the PHY on which the secondary advertising packet was received. + See @ref BLE_GAP_PHYS. This field is set to @ref BLE_GAP_PHY_NOT_SET if no packets + were received on a secondary advertising channel. */ + int8_t tx_power; /**< TX Power reported by the advertiser in the last packet header received. + This field is set to @ref BLE_GAP_POWER_LEVEL_INVALID if the + last received packet did not contain the Tx Power field. + @note TX Power is only included in extended advertising packets. */ + int8_t rssi; /**< Received Signal Strength Indication in dBm of the last packet received. + @note ERRATA-153 and ERRATA-225 require the rssi sample to be compensated based on a temperature + measurement. */ + uint8_t ch_index; /**< Channel Index on which the last advertising packet is received (0-39). */ + uint8_t set_id; /**< Set ID of the received advertising data. Set ID is not present + if set to @ref BLE_GAP_ADV_REPORT_SET_ID_NOT_AVAILABLE. */ + uint16_t data_id : 12; /**< The advertising data ID of the received advertising data. Data ID + is not present if @ref ble_gap_evt_adv_report_t::set_id is set to + @ref BLE_GAP_ADV_REPORT_SET_ID_NOT_AVAILABLE. */ + ble_data_t data; /**< Received advertising or scan response data. If + @ref ble_gap_adv_report_type_t::status is not set to + @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA, the data buffer provided + in @ref sd_ble_gap_scan_start is now released. */ + ble_gap_aux_pointer_t aux_pointer; /**< The offset and PHY of the next advertising packet in this extended advertising + event. @note This field is only set if @ref ble_gap_adv_report_type_t::status + is set to @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA. */ +} ble_gap_evt_adv_report_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_SEC_REQUEST. */ +typedef struct { + uint8_t bond : 1; /**< Perform bonding. */ + uint8_t mitm : 1; /**< Man In The Middle protection requested. */ + uint8_t lesc : 1; /**< LE Secure Connections requested. */ + uint8_t keypress : 1; /**< Generation of keypress notifications requested. */ +} ble_gap_evt_sec_request_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST. */ +typedef struct { + ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */ +} ble_gap_evt_conn_param_update_request_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_SCAN_REQ_REPORT. */ +typedef struct { + uint8_t adv_handle; /**< Advertising handle for the advertising set which received the Scan Request */ + int8_t rssi; /**< Received Signal Strength Indication in dBm. + @note ERRATA-153 and ERRATA-225 require the rssi sample to be compensated based on a temperature + measurement. */ + ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr resolved: @ref + ble_gap_addr_t::addr_id_peer is set to 1 and the address is the device's identity address. */ +} ble_gap_evt_scan_req_report_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST. */ +typedef struct { + ble_gap_data_length_params_t peer_params; /**< Peer data length parameters. */ +} ble_gap_evt_data_length_update_request_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_DATA_LENGTH_UPDATE. + * + * @note This event may also be raised after a PHY Update procedure. + */ +typedef struct { + ble_gap_data_length_params_t effective_params; /**< The effective data length parameters. */ +} ble_gap_evt_data_length_update_t; + +/**@brief Event structure for @ref BLE_GAP_EVT_QOS_CHANNEL_SURVEY_REPORT. */ +typedef struct { + int8_t + channel_energy[BLE_GAP_CHANNEL_COUNT]; /**< The measured energy on the Bluetooth Low Energy + channels, in dBm, indexed by Channel Index. + If no measurement is available for the given channel, channel_energy is set to + @ref BLE_GAP_POWER_LEVEL_INVALID. */ +} ble_gap_evt_qos_channel_survey_report_t; + +/**@brief GAP event structure. */ +typedef struct { + uint16_t conn_handle; /**< Connection Handle on which event occurred. */ + union /**< union alternative identified by evt_id in enclosing struct. */ + { + ble_gap_evt_connected_t connected; /**< Connected Event Parameters. */ + ble_gap_evt_disconnected_t disconnected; /**< Disconnected Event Parameters. */ + ble_gap_evt_conn_param_update_t conn_param_update; /**< Connection Parameter Update Parameters. */ + ble_gap_evt_sec_params_request_t sec_params_request; /**< Security Parameters Request Event Parameters. */ + ble_gap_evt_sec_info_request_t sec_info_request; /**< Security Information Request Event Parameters. */ + ble_gap_evt_passkey_display_t passkey_display; /**< Passkey Display Event Parameters. */ + ble_gap_evt_key_pressed_t key_pressed; /**< Key Pressed Event Parameters. */ + ble_gap_evt_auth_key_request_t auth_key_request; /**< Authentication Key Request Event Parameters. */ + ble_gap_evt_lesc_dhkey_request_t lesc_dhkey_request; /**< LE Secure Connections DHKey calculation request. */ + ble_gap_evt_auth_status_t auth_status; /**< Authentication Status Event Parameters. */ + ble_gap_evt_conn_sec_update_t conn_sec_update; /**< Connection Security Update Event Parameters. */ + ble_gap_evt_timeout_t timeout; /**< Timeout Event Parameters. */ + ble_gap_evt_rssi_changed_t rssi_changed; /**< RSSI Event Parameters. */ + ble_gap_evt_adv_report_t adv_report; /**< Advertising Report Event Parameters. */ + ble_gap_evt_adv_set_terminated_t adv_set_terminated; /**< Advertising Set Terminated Event Parameters. */ + ble_gap_evt_sec_request_t sec_request; /**< Security Request Event Parameters. */ + ble_gap_evt_conn_param_update_request_t conn_param_update_request; /**< Connection Parameter Update Parameters. */ + ble_gap_evt_scan_req_report_t scan_req_report; /**< Scan Request Report Parameters. */ + ble_gap_evt_phy_update_request_t phy_update_request; /**< PHY Update Request Event Parameters. */ + ble_gap_evt_phy_update_t phy_update; /**< PHY Update Parameters. */ + ble_gap_evt_data_length_update_request_t data_length_update_request; /**< Data Length Update Request Event Parameters. */ + ble_gap_evt_data_length_update_t data_length_update; /**< Data Length Update Event Parameters. */ + ble_gap_evt_qos_channel_survey_report_t + qos_channel_survey_report; /**< Quality of Service (QoS) Channel Survey Report Parameters. */ + } params; /**< Event Parameters. */ +} ble_gap_evt_t; + +/** + * @brief BLE GAP connection configuration parameters, set with @ref sd_ble_cfg_set. + * + * @retval ::NRF_ERROR_CONN_COUNT The connection count for the connection configurations is zero. + * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true: + * - The sum of conn_count for all connection configurations combined exceeds UINT8_MAX. + * - The event length is smaller than @ref BLE_GAP_EVENT_LENGTH_MIN. + */ +typedef struct { + uint8_t conn_count; /**< The number of concurrent connections the application can create with this configuration. + The default and minimum value is @ref BLE_GAP_CONN_COUNT_DEFAULT. */ + uint16_t event_length; /**< The time set aside for this connection on every connection interval in 1.25 ms units. + The default value is @ref BLE_GAP_EVENT_LENGTH_DEFAULT, the minimum value is @ref + BLE_GAP_EVENT_LENGTH_MIN. The event length and the connection interval are the primary parameters + for setting the throughput of a connection. + See the SoftDevice Specification for details on throughput. */ +} ble_gap_conn_cfg_t; + +/** + * @brief Configuration of maximum concurrent connections in the different connected roles, set with + * @ref sd_ble_cfg_set. + * + * @retval ::NRF_ERROR_CONN_COUNT The sum of periph_role_count and central_role_count is too + * large. The maximum supported sum of concurrent connections is + * @ref BLE_GAP_ROLE_COUNT_COMBINED_MAX. + * @retval ::NRF_ERROR_INVALID_PARAM central_sec_count is larger than central_role_count. + * @retval ::NRF_ERROR_RESOURCES The adv_set_count is too large. The maximum + * supported advertising handles is + * @ref BLE_GAP_ADV_SET_COUNT_MAX. + */ +typedef struct { + uint8_t adv_set_count; /**< Maximum number of advertising sets. Default value is @ref BLE_GAP_ADV_SET_COUNT_DEFAULT. */ + uint8_t periph_role_count; /**< Maximum number of connections concurrently acting as a peripheral. Default value is @ref + BLE_GAP_ROLE_COUNT_PERIPH_DEFAULT. */ + uint8_t central_role_count; /**< Maximum number of connections concurrently acting as a central. Default value is @ref + BLE_GAP_ROLE_COUNT_CENTRAL_DEFAULT. */ + uint8_t central_sec_count; /**< Number of SMP instances shared between all connections acting as a central. Default value is + @ref BLE_GAP_ROLE_COUNT_CENTRAL_SEC_DEFAULT. */ + uint8_t qos_channel_survey_role_available : 1; /**< If set, the Quality of Service (QoS) channel survey module is available to + the application using @ref sd_ble_gap_qos_channel_survey_start. */ +} ble_gap_cfg_role_count_t; + +/** + * @brief Device name and its properties, set with @ref sd_ble_cfg_set. + * + * @note If the device name is not configured, the default device name will be + * @ref BLE_GAP_DEVNAME_DEFAULT, the maximum device name length will be + * @ref BLE_GAP_DEVNAME_DEFAULT_LEN, vloc will be set to @ref BLE_GATTS_VLOC_STACK and the device name + * will have no write access. + * + * @note If @ref max_len is more than @ref BLE_GAP_DEVNAME_DEFAULT_LEN and vloc is set to @ref BLE_GATTS_VLOC_STACK, + * the attribute table size must be increased to have room for the longer device name (see + * @ref sd_ble_cfg_set and @ref ble_gatts_cfg_attr_tab_size_t). + * + * @note If vloc is @ref BLE_GATTS_VLOC_STACK : + * - p_value must point to non-volatile memory (flash) or be NULL. + * - If p_value is NULL, the device name will initially be empty. + * + * @note If vloc is @ref BLE_GATTS_VLOC_USER : + * - p_value cannot be NULL. + * - If the device name is writable, p_value must point to volatile memory (RAM). + * + * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true: + * - Invalid device name location (vloc). + * - Invalid device name security mode. + * @retval ::NRF_ERROR_INVALID_LENGTH One or more of the following is true: + * - The device name length is invalid (must be between 0 and @ref BLE_GAP_DEVNAME_MAX_LEN). + * - The device name length is too long for the given Attribute Table. + * @retval ::NRF_ERROR_NOT_SUPPORTED Device name security mode is not supported. + */ +typedef struct { + ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */ + uint8_t vloc : 2; /**< Value location, see @ref BLE_GATTS_VLOCS.*/ + uint8_t *p_value; /**< Pointer to where the value (device name) is stored or will be stored. */ + uint16_t current_len; /**< Current length in bytes of the memory pointed to by p_value.*/ + uint16_t max_len; /**< Maximum length in bytes of the memory pointed to by p_value.*/ +} ble_gap_cfg_device_name_t; + +/**@brief Peripheral Preferred Connection Parameters include configuration parameters, set with @ref sd_ble_cfg_set. */ +typedef struct { + uint8_t include_cfg; /**< Inclusion configuration of the Peripheral Preferred Connection Parameters characteristic. + See @ref BLE_GAP_CHAR_INCL_CONFIG. Default is @ref BLE_GAP_PPCP_INCL_CONFIG_DEFAULT. */ +} ble_gap_cfg_ppcp_incl_cfg_t; + +/**@brief Central Address Resolution include configuration parameters, set with @ref sd_ble_cfg_set. */ +typedef struct { + uint8_t include_cfg; /**< Inclusion configuration of the Central Address Resolution characteristic. + See @ref BLE_GAP_CHAR_INCL_CONFIG. Default is @ref BLE_GAP_CAR_INCL_CONFIG_DEFAULT. */ +} ble_gap_cfg_car_incl_cfg_t; + +/**@brief Configuration structure for GAP configurations. */ +typedef union { + ble_gap_cfg_role_count_t role_count_cfg; /**< Role count configuration, cfg_id is @ref BLE_GAP_CFG_ROLE_COUNT. */ + ble_gap_cfg_device_name_t device_name_cfg; /**< Device name configuration, cfg_id is @ref BLE_GAP_CFG_DEVICE_NAME. */ + ble_gap_cfg_ppcp_incl_cfg_t ppcp_include_cfg; /**< Peripheral Preferred Connection Parameters characteristic include + configuration, cfg_id is @ref BLE_GAP_CFG_PPCP_INCL_CONFIG. */ + ble_gap_cfg_car_incl_cfg_t car_include_cfg; /**< Central Address Resolution characteristic include configuration, + cfg_id is @ref BLE_GAP_CFG_CAR_INCL_CONFIG. */ +} ble_gap_cfg_t; + +/**@brief Channel Map option. + * + * @details Used with @ref sd_ble_opt_get to get the current channel map + * or @ref sd_ble_opt_set to set a new channel map. When setting the + * channel map, it applies to all current and future connections. When getting the + * current channel map, it applies to a single connection and the connection handle + * must be supplied. + * + * @note Setting the channel map may take some time, depending on connection parameters. + * The time taken may be different for each connection and the get operation will + * return the previous channel map until the new one has taken effect. + * + * @note After setting the channel map, by spec it can not be set again until at least 1 s has passed. + * See Bluetooth Specification Version 4.1 Volume 2, Part E, Section 7.3.46. + * + * @retval ::NRF_SUCCESS Get or set successful. + * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true: + * - Less then two bits in @ref ch_map are set. + * - Bits for primary advertising channels (37-39) are set. + * @retval ::NRF_ERROR_BUSY Channel map was set again before enough time had passed. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied for get. + * + */ +typedef struct { + uint16_t conn_handle; /**< Connection Handle (only applicable for get) */ + uint8_t ch_map[5]; /**< Channel Map (37-bit). */ +} ble_gap_opt_ch_map_t; + +/**@brief Local connection latency option. + * + * @details Local connection latency is a feature which enables the slave to improve + * current consumption by ignoring the slave latency set by the peer. The + * local connection latency can only be set to a multiple of the slave latency, + * and cannot be longer than half of the supervision timeout. + * + * @details Used with @ref sd_ble_opt_set to set the local connection latency. The + * @ref sd_ble_opt_get is not supported for this option, but the actual + * local connection latency (unless set to NULL) is set as a return parameter + * when setting the option. + * + * @note The latency set will be truncated down to the closest slave latency event + * multiple, or the nearest multiple before half of the supervision timeout. + * + * @note The local connection latency is disabled by default, and needs to be enabled for new + * connections and whenever the connection is updated. + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_NOT_SUPPORTED Get is not supported. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter. + */ +typedef struct { + uint16_t conn_handle; /**< Connection Handle */ + uint16_t requested_latency; /**< Requested local connection latency. */ + uint16_t *p_actual_latency; /**< Pointer to storage for the actual local connection latency (can be set to NULL to skip return + value). */ +} ble_gap_opt_local_conn_latency_t; + +/**@brief Disable slave latency + * + * @details Used with @ref sd_ble_opt_set to temporarily disable slave latency of a peripheral connection + * (see @ref ble_gap_conn_params_t::slave_latency). And to re-enable it again. When disabled, the + * peripheral will ignore the slave_latency set by the central. + * + * @note Shall only be called on peripheral links. + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_NOT_SUPPORTED Get is not supported. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter. + */ +typedef struct { + uint16_t conn_handle; /**< Connection Handle */ + uint8_t disable; /**< For allowed values see @ref BLE_GAP_SLAVE_LATENCY */ +} ble_gap_opt_slave_latency_disable_t; + +/**@brief Passkey Option. + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_STATIC_PK_MSC} + * @endmscs + * + * @details Structure containing the passkey to be used during pairing. This can be used with @ref + * sd_ble_opt_set to make the SoftDevice use a preprogrammed passkey for authentication + * instead of generating a random one. + * + * @note Repeated pairing attempts using the same preprogrammed passkey makes pairing vulnerable to MITM attacks. + * + * @note @ref sd_ble_opt_get is not supported for this option. + * + */ +typedef struct { + uint8_t const *p_passkey; /**< Pointer to 6-digit ASCII string (digit 0..9 only, no NULL termination) passkey to be used + during pairing. If this is NULL, the SoftDevice will generate a random passkey if required.*/ +} ble_gap_opt_passkey_t; + +/**@brief Compatibility mode 1 option. + * + * @details This can be used with @ref sd_ble_opt_set to enable and disable + * compatibility mode 1. Compatibility mode 1 is disabled by default. + * + * @note Compatibility mode 1 enables interoperability with devices that do not support a value of + * 0 for the WinOffset parameter in the Link Layer CONNECT_IND packet. This applies to a + * limited set of legacy peripheral devices from another vendor. Enabling this compatibility + * mode will only have an effect if the local device will act as a central device and + * initiate a connection to a peripheral device. In that case it may lead to the connection + * creation taking up to one connection interval longer to complete for all connections. + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_INVALID_STATE When connection creation is ongoing while mode 1 is set. + */ +typedef struct { + uint8_t enable : 1; /**< Enable compatibility mode 1.*/ +} ble_gap_opt_compat_mode_1_t; + +/**@brief Authenticated payload timeout option. + * + * @details This can be used with @ref sd_ble_opt_set to change the Authenticated payload timeout to a value other + * than the default of @ref BLE_GAP_AUTH_PAYLOAD_TIMEOUT_MAX. + * + * @note The authenticated payload timeout event ::BLE_GAP_TIMEOUT_SRC_AUTH_PAYLOAD will be generated + * if auth_payload_timeout time has elapsed without receiving a packet with a valid MIC on an encrypted + * link. + * + * @note The LE ping procedure will be initiated before the timer expires to give the peer a chance + * to reset the timer. In addition the stack will try to prioritize running of LE ping over other + * activities to increase chances of finishing LE ping before timer expires. To avoid side-effects + * on other activities, it is recommended to use high timeout values. + * Recommended timeout > 2*(connInterval * (6 + connSlaveLatency)). + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. auth_payload_timeout was outside of allowed range. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter. + */ +typedef struct { + uint16_t conn_handle; /**< Connection Handle */ + uint16_t auth_payload_timeout; /**< Requested timeout in 10 ms unit, see @ref BLE_GAP_AUTH_PAYLOAD_TIMEOUT. */ +} ble_gap_opt_auth_payload_timeout_t; + +/**@brief Option structure for GAP options. */ +typedef union { + ble_gap_opt_ch_map_t ch_map; /**< Parameters for the Channel Map option. */ + ble_gap_opt_local_conn_latency_t local_conn_latency; /**< Parameters for the Local connection latency option */ + ble_gap_opt_passkey_t passkey; /**< Parameters for the Passkey option.*/ + ble_gap_opt_compat_mode_1_t compat_mode_1; /**< Parameters for the compatibility mode 1 option.*/ + ble_gap_opt_auth_payload_timeout_t auth_payload_timeout; /**< Parameters for the authenticated payload timeout option.*/ + ble_gap_opt_slave_latency_disable_t slave_latency_disable; /**< Parameters for the Disable slave latency option */ +} ble_gap_opt_t; + +/**@brief Connection event triggering parameters. */ +typedef struct { + uint8_t ppi_ch_id; /**< PPI channel to use. This channel should be regarded as reserved until + connection event PPI task triggering is stopped. + The PPI channel ID can not be one of the PPI channels reserved by + the SoftDevice. See @ref NRF_SOC_SD_PPI_CHANNELS_SD_ENABLED_MSK. */ + uint32_t task_endpoint; /**< Task Endpoint to trigger. */ + uint16_t conn_evt_counter_start; /**< The connection event on which the task triggering should start. */ + uint16_t period_in_events; /**< Trigger period. Valid range is [1, 32767]. + If the device is in slave role and slave latency is enabled, + this parameter should be set to a multiple of (slave latency + 1) + to ensure low power operation. */ +} ble_gap_conn_event_trigger_t; +/**@} */ + +/**@addtogroup BLE_GAP_FUNCTIONS Functions + * @{ */ + +/**@brief Set the local Bluetooth identity address. + * + * The local Bluetooth identity address is the address that identifies this device to other peers. + * The address type must be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC. + * + * @note The identity address cannot be changed while advertising, scanning or creating a connection. + * + * @note This address will be distributed to the peer during bonding. + * If the address changes, the address stored in the peer device will not be valid and the ability to + * reconnect using the old address will be lost. + * + * @note By default the SoftDevice will set an address of type @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC upon being + * enabled. The address is a random number populated during the IC manufacturing process and remains unchanged + * for the lifetime of each IC. + * + * @mscs + * @mmsc{@ref BLE_GAP_ADV_MSC} + * @endmscs + * + * @param[in] p_addr Pointer to address structure. + * + * @retval ::NRF_SUCCESS Address successfully set. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::NRF_ERROR_INVALID_STATE The identity address cannot be changed while advertising, + * scanning or creating a connection. + */ +SVCALL(SD_BLE_GAP_ADDR_SET, uint32_t, sd_ble_gap_addr_set(ble_gap_addr_t const *p_addr)); + +/**@brief Get local Bluetooth identity address. + * + * @note This will always return the identity address irrespective of the privacy settings, + * i.e. the address type will always be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC. + * + * @param[out] p_addr Pointer to address structure to be filled in. + * + * @retval ::NRF_SUCCESS Address successfully retrieved. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or NULL pointer supplied. + */ +SVCALL(SD_BLE_GAP_ADDR_GET, uint32_t, sd_ble_gap_addr_get(ble_gap_addr_t *p_addr)); + +/**@brief Get the Bluetooth device address used by the advertiser. + * + * @note This function will return the local Bluetooth address used in advertising PDUs. When + * using privacy, the SoftDevice will generate a new private address every + * @ref ble_gap_privacy_params_t::private_addr_cycle_s configured using + * @ref sd_ble_gap_privacy_set. Hence depending on when the application calls this API, the + * address returned may not be the latest address that is used in the advertising PDUs. + * + * @param[in] adv_handle The advertising handle to get the address from. + * @param[out] p_addr Pointer to address structure to be filled in. + * + * @retval ::NRF_SUCCESS Address successfully retrieved. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or NULL pointer supplied. + * @retval ::BLE_ERROR_INVALID_ADV_HANDLE The provided advertising handle was not found. + * @retval ::NRF_ERROR_INVALID_STATE The advertising set is currently not advertising. + */ +SVCALL(SD_BLE_GAP_ADV_ADDR_GET, uint32_t, sd_ble_gap_adv_addr_get(uint8_t adv_handle, ble_gap_addr_t *p_addr)); + +/**@brief Set the active whitelist in the SoftDevice. + * + * @note Only one whitelist can be used at a time and the whitelist is shared between the BLE roles. + * The whitelist cannot be set if a BLE role is using the whitelist. + * + * @note If an address is resolved using the information in the device identity list, then the whitelist + * filter policy applies to the peer identity address and not the resolvable address sent on air. + * + * @mscs + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_PRIVATE_SCAN_MSC} + * @endmscs + * + * @param[in] pp_wl_addrs Pointer to a whitelist of peer addresses, if NULL the whitelist will be cleared. + * @param[in] len Length of the whitelist, maximum @ref BLE_GAP_WHITELIST_ADDR_MAX_COUNT. + * + * @retval ::NRF_SUCCESS The whitelist is successfully set/cleared. + * @retval ::NRF_ERROR_INVALID_ADDR The whitelist (or one of its entries) provided is invalid. + * @retval ::BLE_ERROR_GAP_WHITELIST_IN_USE The whitelist is in use by a BLE role and cannot be set or cleared. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied. + * @retval ::NRF_ERROR_DATA_SIZE The given whitelist size is invalid (zero or too large); this can only return when + * pp_wl_addrs is not NULL. + */ +SVCALL(SD_BLE_GAP_WHITELIST_SET, uint32_t, sd_ble_gap_whitelist_set(ble_gap_addr_t const *const *pp_wl_addrs, uint8_t len)); + +/**@brief Set device identity list. + * + * @note Only one device identity list can be used at a time and the list is shared between the BLE roles. + * The device identity list cannot be set if a BLE role is using the list. + * + * @param[in] pp_id_keys Pointer to an array of peer identity addresses and peer IRKs, if NULL the device identity list will + * be cleared. + * @param[in] pp_local_irks Pointer to an array of local IRKs. Each entry in the array maps to the entry in pp_id_keys at the + * same index. To fill in the list with the currently set device IRK for all peers, set to NULL. + * @param[in] len Length of the device identity list, maximum @ref BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT. + * + * @mscs + * @mmsc{@ref BLE_GAP_PRIVACY_ADV_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_PRIVATE_SCAN_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_CONN_PRIV_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_CONN_PRIV_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS The device identity list successfully set/cleared. + * @retval ::NRF_ERROR_INVALID_ADDR The device identity list (or one of its entries) provided is invalid. + * This code may be returned if the local IRK list also has an invalid entry. + * @retval ::BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE The device identity list is in use and cannot be set or cleared. + * @retval ::BLE_ERROR_GAP_DEVICE_IDENTITIES_DUPLICATE The device identity list contains multiple entries with the same identity + * address. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied. + * @retval ::NRF_ERROR_DATA_SIZE The given device identity list size invalid (zero or too large); this can + * only return when pp_id_keys is not NULL. + */ +SVCALL(SD_BLE_GAP_DEVICE_IDENTITIES_SET, uint32_t, + sd_ble_gap_device_identities_set(ble_gap_id_key_t const *const *pp_id_keys, ble_gap_irk_t const *const *pp_local_irks, + uint8_t len)); + +/**@brief Set privacy settings. + * + * @note Privacy settings cannot be changed while advertising, scanning or creating a connection. + * + * @param[in] p_privacy_params Privacy settings. + * + * @mscs + * @mmsc{@ref BLE_GAP_PRIVACY_ADV_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied. + * @retval ::NRF_ERROR_INVALID_ADDR The pointer to privacy settings is NULL or invalid. + * Otherwise, the p_device_irk pointer in privacy parameter is an invalid pointer. + * @retval ::NRF_ERROR_INVALID_PARAM Out of range parameters are provided. + * @retval ::NRF_ERROR_NOT_SUPPORTED The SoftDevice does not support privacy if the Central Address Resolution + characteristic is not configured to be included and the SoftDevice is configured + to support central roles. + See @ref ble_gap_cfg_car_incl_cfg_t and @ref ble_gap_cfg_role_count_t. + * @retval ::NRF_ERROR_INVALID_STATE Privacy settings cannot be changed while advertising, scanning + * or creating a connection. + */ +SVCALL(SD_BLE_GAP_PRIVACY_SET, uint32_t, sd_ble_gap_privacy_set(ble_gap_privacy_params_t const *p_privacy_params)); + +/**@brief Get privacy settings. + * + * @note ::ble_gap_privacy_params_t::p_device_irk must be initialized to NULL or a valid address before this function is called. + * If it is initialized to a valid address, the address pointed to will contain the current device IRK on return. + * + * @param[in,out] p_privacy_params Privacy settings. + * + * @retval ::NRF_SUCCESS Privacy settings read. + * @retval ::NRF_ERROR_INVALID_ADDR The pointer given for returning the privacy settings may be NULL or invalid. + * Otherwise, the p_device_irk pointer in privacy parameter is an invalid pointer. + */ +SVCALL(SD_BLE_GAP_PRIVACY_GET, uint32_t, sd_ble_gap_privacy_get(ble_gap_privacy_params_t *p_privacy_params)); + +/**@brief Configure an advertising set. Set, clear or update advertising and scan response data. + * + * @note The format of the advertising data will be checked by this call to ensure interoperability. + * Limitations imposed by this API call to the data provided include having a flags data type in the scan response data and + * duplicating the local name in the advertising data and scan response data. + * + * @note In order to update advertising data while advertising, new advertising buffers must be provided. + * + * @mscs + * @mmsc{@ref BLE_GAP_ADV_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs + * + * @param[in,out] p_adv_handle Provide a pointer to a handle containing @ref + * BLE_GAP_ADV_SET_HANDLE_NOT_SET to configure a new advertising set. On success, a new handle is then returned through the + * pointer. Provide a pointer to an existing advertising handle to configure an existing advertising set. + * @param[in] p_adv_data Advertising data. If set to NULL, no advertising data will be used. See + * @ref ble_gap_adv_data_t. + * @param[in] p_adv_params Advertising parameters. When this function is used to update advertising + * data while advertising, this parameter must be NULL. See @ref ble_gap_adv_params_t. + * + * @retval ::NRF_SUCCESS Advertising set successfully configured. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied: + * - Invalid advertising data configuration specified. See @ref + * ble_gap_adv_data_t. + * - Invalid configuration of p_adv_params. See @ref ble_gap_adv_params_t. + * - Use of whitelist requested but whitelist has not been set, + * see @ref sd_ble_gap_whitelist_set. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR ble_gap_adv_params_t::p_peer_addr is invalid. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either: + * - It is invalid to provide non-NULL advertising set parameters while + * advertising. + * - It is invalid to provide the same data buffers while advertising. To + * update advertising data, provide new advertising buffers. + * @retval ::BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST Discoverable mode and whitelist incompatible. + * @retval ::BLE_ERROR_INVALID_ADV_HANDLE The provided advertising handle was not found. Use @ref + * BLE_GAP_ADV_SET_HANDLE_NOT_SET to configure a new advertising handle. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_FLAGS Invalid combination of advertising flags supplied. + * @retval ::NRF_ERROR_INVALID_DATA Invalid data type(s) supplied. Check the advertising data format + * specification given in Bluetooth Specification Version 5.0, Volume 3, Part C, Chapter 11. + * @retval ::NRF_ERROR_INVALID_LENGTH Invalid data length(s) supplied. + * @retval ::NRF_ERROR_NOT_SUPPORTED Unsupported data length or advertising parameter configuration. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to configure a new advertising handle. Update an + * existing advertising handle instead. + * @retval ::BLE_ERROR_GAP_UUID_LIST_MISMATCH Invalid UUID list supplied. + */ +SVCALL(SD_BLE_GAP_ADV_SET_CONFIGURE, uint32_t, + sd_ble_gap_adv_set_configure(uint8_t *p_adv_handle, ble_gap_adv_data_t const *p_adv_data, + ble_gap_adv_params_t const *p_adv_params)); + +/**@brief Start advertising (GAP Discoverable, Connectable modes, Broadcast Procedure). + * + * @note Only one advertiser may be active at any time. + * + * @note If privacy is enabled, the advertiser's private address will be refreshed when this function is called. + * See @ref sd_ble_gap_privacy_set(). + * + * @events + * @event{@ref BLE_GAP_EVT_CONNECTED, Generated after connection has been established through connectable advertising.} + * @event{@ref BLE_GAP_EVT_ADV_SET_TERMINATED, Advertising set has terminated.} + * @event{@ref BLE_GAP_EVT_SCAN_REQ_REPORT, A scan request was received.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_ADV_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_CONN_PRIV_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs + * + * @param[in] adv_handle Advertising handle to advertise on, received from @ref sd_ble_gap_adv_set_configure. + * @param[in] conn_cfg_tag Tag identifying a configuration set by @ref sd_ble_cfg_set or + * @ref BLE_CONN_CFG_TAG_DEFAULT to use the default connection configuration. For non-connectable + * advertising, this is ignored. + * + * @retval ::NRF_SUCCESS The BLE stack has started advertising. + * @retval ::NRF_ERROR_INVALID_STATE adv_handle is not configured or already advertising. + * @retval ::NRF_ERROR_CONN_COUNT The limit of available connections for this connection configuration + * tag has been reached; connectable advertiser cannot be started. + * To increase the number of available connections, + * use @ref sd_ble_cfg_set with @ref BLE_GAP_CFG_ROLE_COUNT or @ref BLE_CONN_CFG_GAP. + * @retval ::BLE_ERROR_INVALID_ADV_HANDLE Advertising handle not found. Configure a new adveriting handle with @ref + sd_ble_gap_adv_set_configure. + * @retval ::NRF_ERROR_NOT_FOUND conn_cfg_tag not found. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied: + * - Invalid configuration of p_adv_params. See @ref ble_gap_adv_params_t. + * - Use of whitelist requested but whitelist has not been set, see @ref + sd_ble_gap_whitelist_set. + * @retval ::NRF_ERROR_RESOURCES Either: + * - adv_handle is configured with connectable advertising, but the event_length parameter + * associated with conn_cfg_tag is too small to be able to establish a connection on + * the selected advertising phys. Use @ref sd_ble_cfg_set to increase the event length. + * - Not enough BLE role slots available. + Stop one or more currently active roles (Central, Peripheral, Broadcaster or Observer) + and try again. + * - p_adv_params is configured with connectable advertising, but the event_length + parameter + * associated with conn_cfg_tag is too small to be able to establish a connection on + * the selected advertising phys. Use @ref sd_ble_cfg_set to increase the event length. + */ +SVCALL(SD_BLE_GAP_ADV_START, uint32_t, sd_ble_gap_adv_start(uint8_t adv_handle, uint8_t conn_cfg_tag)); + +/**@brief Stop advertising (GAP Discoverable, Connectable modes, Broadcast Procedure). + * + * @mscs + * @mmsc{@ref BLE_GAP_ADV_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs + * + * @param[in] adv_handle The advertising handle that should stop advertising. + * + * @retval ::NRF_SUCCESS The BLE stack has stopped advertising. + * @retval ::BLE_ERROR_INVALID_ADV_HANDLE Invalid advertising handle. + * @retval ::NRF_ERROR_INVALID_STATE The advertising handle is not advertising. + */ +SVCALL(SD_BLE_GAP_ADV_STOP, uint32_t, sd_ble_gap_adv_stop(uint8_t adv_handle)); + +/**@brief Update connection parameters. + * + * @details In the central role this will initiate a Link Layer connection parameter update procedure, + * otherwise in the peripheral role, this will send the corresponding L2CAP request and wait for + * the central to perform the procedure. In both cases, and regardless of success or failure, the application + * will be informed of the result with a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE event. + * + * @details This function can be used as a central both to reply to a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST or to start the + * procedure unrequested. + * + * @events + * @event{@ref BLE_GAP_EVT_CONN_PARAM_UPDATE, Result of the connection parameter update procedure.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CPU_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC} + * @mmsc{@ref BLE_GAP_MULTILINK_CPU_MSC} + * @mmsc{@ref BLE_GAP_MULTILINK_CTRL_PROC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_CPU_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_conn_params Pointer to desired connection parameters. If NULL is provided on a peripheral role, + * the parameters in the PPCP characteristic of the GAP service will be used instead. + * If NULL is provided on a central role and in response to a @ref + * BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, the peripheral request will be rejected + * + * @retval ::NRF_SUCCESS The Connection Update procedure has been started successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. + * @retval ::NRF_ERROR_INVALID_STATE Disconnection in progress or link has not been established. + * @retval ::NRF_ERROR_BUSY Procedure already in progress, wait for pending procedures to complete and retry. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. + */ +SVCALL(SD_BLE_GAP_CONN_PARAM_UPDATE, uint32_t, + sd_ble_gap_conn_param_update(uint16_t conn_handle, ble_gap_conn_params_t const *p_conn_params)); + +/**@brief Disconnect (GAP Link Termination). + * + * @details This call initiates the disconnection procedure, and its completion will be communicated to the application + * with a @ref BLE_GAP_EVT_DISCONNECTED event. + * + * @events + * @event{@ref BLE_GAP_EVT_DISCONNECTED, Generated when disconnection procedure is complete.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CONN_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] hci_status_code HCI status code, see @ref BLE_HCI_STATUS_CODES (accepted values are @ref + * BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION and @ref BLE_HCI_CONN_INTERVAL_UNACCEPTABLE). + * + * @retval ::NRF_SUCCESS The disconnection procedure has been started successfully. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_INVALID_STATE Disconnection in progress or link has not been established. + */ +SVCALL(SD_BLE_GAP_DISCONNECT, uint32_t, sd_ble_gap_disconnect(uint16_t conn_handle, uint8_t hci_status_code)); + +/**@brief Set the radio's transmit power. + * + * @param[in] role The role to set the transmit power for, see @ref BLE_GAP_TX_POWER_ROLES for + * possible roles. + * @param[in] handle The handle parameter is interpreted depending on role: + * - If role is @ref BLE_GAP_TX_POWER_ROLE_CONN, this value is the specific connection handle. + * - If role is @ref BLE_GAP_TX_POWER_ROLE_ADV, the advertising set identified with the advertising handle, + * will use the specified transmit power, and include it in the advertising packet headers if + * @ref ble_gap_adv_properties_t::include_tx_power set. + * - For all other roles handle is ignored. + * @param[in] tx_power Radio transmit power in dBm (see note for accepted values). + * + * @note Supported tx_power values: -40dBm, -20dBm, -16dBm, -12dBm, -8dBm, -4dBm, 0dBm, +3dBm and +4dBm. + * In addition, on some chips following values are supported: +2dBm, +5dBm, +6dBm, +7dBm and +8dBm. + * Setting these values on a chip that does not support them will result in undefined behaviour. + * @note The initiator will have the same transmit power as the scanner. + * @note When a connection is created it will inherit the transmit power from the initiator or + * advertiser leading to the connection. + * + * @retval ::NRF_SUCCESS Successfully changed the transmit power. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::BLE_ERROR_INVALID_ADV_HANDLE Advertising handle not found. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_TX_POWER_SET, uint32_t, sd_ble_gap_tx_power_set(uint8_t role, uint16_t handle, int8_t tx_power)); + +/**@brief Set GAP Appearance value. + * + * @param[in] appearance Appearance (16-bit), see @ref BLE_APPEARANCES. + * + * @retval ::NRF_SUCCESS Appearance value set successfully. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + */ +SVCALL(SD_BLE_GAP_APPEARANCE_SET, uint32_t, sd_ble_gap_appearance_set(uint16_t appearance)); + +/**@brief Get GAP Appearance value. + * + * @param[out] p_appearance Pointer to appearance (16-bit) to be filled in, see @ref BLE_APPEARANCES. + * + * @retval ::NRF_SUCCESS Appearance value retrieved successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + */ +SVCALL(SD_BLE_GAP_APPEARANCE_GET, uint32_t, sd_ble_gap_appearance_get(uint16_t *p_appearance)); + +/**@brief Set GAP Peripheral Preferred Connection Parameters. + * + * @param[in] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure with the desired parameters. + * + * @retval ::NRF_SUCCESS Peripheral Preferred Connection Parameters set successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_NOT_SUPPORTED The characteristic is not included in the Attribute Table, + see @ref ble_gap_cfg_ppcp_incl_cfg_t. + */ +SVCALL(SD_BLE_GAP_PPCP_SET, uint32_t, sd_ble_gap_ppcp_set(ble_gap_conn_params_t const *p_conn_params)); + +/**@brief Get GAP Peripheral Preferred Connection Parameters. + * + * @param[out] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure where the parameters will be stored. + * + * @retval ::NRF_SUCCESS Peripheral Preferred Connection Parameters retrieved successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_NOT_SUPPORTED The characteristic is not included in the Attribute Table, + see @ref ble_gap_cfg_ppcp_incl_cfg_t. + */ +SVCALL(SD_BLE_GAP_PPCP_GET, uint32_t, sd_ble_gap_ppcp_get(ble_gap_conn_params_t *p_conn_params)); + +/**@brief Set GAP device name. + * + * @note If the device name is located in application flash memory (see @ref ble_gap_cfg_device_name_t), + * it cannot be changed. Then @ref NRF_ERROR_FORBIDDEN will be returned. + * + * @param[in] p_write_perm Write permissions for the Device Name characteristic, see @ref ble_gap_conn_sec_mode_t. + * @param[in] p_dev_name Pointer to a UTF-8 encoded, non NULL-terminated string. + * @param[in] len Length of the UTF-8, non NULL-terminated string pointed to by p_dev_name in octets (must be smaller or + * equal than @ref BLE_GAP_DEVNAME_MAX_LEN). + * + * @retval ::NRF_SUCCESS GAP device name and permissions set successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. + * @retval ::NRF_ERROR_FORBIDDEN Device name is not writable. + */ +SVCALL(SD_BLE_GAP_DEVICE_NAME_SET, uint32_t, + sd_ble_gap_device_name_set(ble_gap_conn_sec_mode_t const *p_write_perm, uint8_t const *p_dev_name, uint16_t len)); + +/**@brief Get GAP device name. + * + * @note If the device name is longer than the size of the supplied buffer, + * p_len will return the complete device name length, + * and not the number of bytes actually returned in p_dev_name. + * The application may use this information to allocate a suitable buffer size. + * + * @param[out] p_dev_name Pointer to an empty buffer where the UTF-8 non NULL-terminated string will be placed. Set to + * NULL to obtain the complete device name length. + * @param[in,out] p_len Length of the buffer pointed by p_dev_name, complete device name length on output. + * + * @retval ::NRF_SUCCESS GAP device name retrieved successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. + */ +SVCALL(SD_BLE_GAP_DEVICE_NAME_GET, uint32_t, sd_ble_gap_device_name_get(uint8_t *p_dev_name, uint16_t *p_len)); + +/**@brief Initiate the GAP Authentication procedure. + * + * @details In the central role, this function will send an SMP Pairing Request (or an SMP Pairing Failed if rejected), + * otherwise in the peripheral role, an SMP Security Request will be sent. + * + * @events + * @event{Depending on the security parameters set and the packet exchanges with the peer\, the following events may be + * generated:} + * @event{@ref BLE_GAP_EVT_SEC_PARAMS_REQUEST} + * @event{@ref BLE_GAP_EVT_SEC_INFO_REQUEST} + * @event{@ref BLE_GAP_EVT_PASSKEY_DISPLAY} + * @event{@ref BLE_GAP_EVT_KEY_PRESSED} + * @event{@ref BLE_GAP_EVT_AUTH_KEY_REQUEST} + * @event{@ref BLE_GAP_EVT_LESC_DHKEY_REQUEST} + * @event{@ref BLE_GAP_EVT_CONN_SEC_UPDATE} + * @event{@ref BLE_GAP_EVT_AUTH_STATUS} + * @event{@ref BLE_GAP_EVT_TIMEOUT} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_SEC_REQ_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_SEC_REQ_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_sec_params Pointer to the @ref ble_gap_sec_params_t structure with the security parameters to be used during the + * pairing or bonding procedure. In the peripheral role, only the bond, mitm, lesc and keypress fields of this structure are used. + * In the central role, this pointer may be NULL to reject a Security Request. + * + * @retval ::NRF_SUCCESS Successfully initiated authentication procedure. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either: + * - No link has been established. + * - An encryption is already executing or queued. + * @retval ::NRF_ERROR_NO_MEM The maximum number of authentication procedures that can run in parallel for the given role is + * reached. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_NOT_SUPPORTED Setting of sign or link fields in @ref ble_gap_sec_kdist_t not supported. + * Distribution of own Identity Information is only supported if the Central + * Address Resolution characteristic is configured to be included or + * the Softdevice is configured to support peripheral roles only. + * See @ref ble_gap_cfg_car_incl_cfg_t and @ref ble_gap_cfg_role_count_t. + * @retval ::NRF_ERROR_TIMEOUT A SMP timeout has occurred, and further SMP operations on this link is prohibited. + */ +SVCALL(SD_BLE_GAP_AUTHENTICATE, uint32_t, + sd_ble_gap_authenticate(uint16_t conn_handle, ble_gap_sec_params_t const *p_sec_params)); + +/**@brief Reply with GAP security parameters. + * + * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST, calling it at other times will result in + * an @ref NRF_ERROR_INVALID_STATE. + * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected + * parameters. + * + * @events + * @event{This function is used during authentication procedures, see the list of events in the documentation of @ref + * sd_ble_gap_authenticate.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_JW_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_PERIPH_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_CENTRAL_OOB_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_STATIC_PK_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_CONFIRM_FAIL_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_KS_TOO_SMALL_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_APP_ERROR_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_REMOTE_PAIRING_FAIL_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_TIMEOUT_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] sec_status Security status, see @ref BLE_GAP_SEC_STATUS. + * @param[in] p_sec_params Pointer to a @ref ble_gap_sec_params_t security parameters structure. In the central role this must be + * set to NULL, as the parameters have already been provided during a previous call to @ref sd_ble_gap_authenticate. + * @param[in,out] p_sec_keyset Pointer to a @ref ble_gap_sec_keyset_t security keyset structure. Any keys generated and/or + * distributed as a result of the ongoing security procedure will be stored into the memory referenced by the pointers inside this + * structure. The keys will be stored and available to the application upon reception of a @ref BLE_GAP_EVT_AUTH_STATUS event. + * Note that the SoftDevice expects the application to provide memory for storing the + * peer's keys. So it must be ensured that the relevant pointers inside this structure are not NULL. The + * pointers to the local key can, however, be NULL, in which case, the local key data will not be available to the application + * upon reception of the + * @ref BLE_GAP_EVT_AUTH_STATUS event. + * + * @retval ::NRF_SUCCESS Successfully accepted security parameter from the application. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Security parameters has not been requested. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_NOT_SUPPORTED Setting of sign or link fields in @ref ble_gap_sec_kdist_t not supported. + * Distribution of own Identity Information is only supported if the Central + * Address Resolution characteristic is configured to be included or + * the Softdevice is configured to support peripheral roles only. + * See @ref ble_gap_cfg_car_incl_cfg_t and @ref ble_gap_cfg_role_count_t. + */ +SVCALL(SD_BLE_GAP_SEC_PARAMS_REPLY, uint32_t, + sd_ble_gap_sec_params_reply(uint16_t conn_handle, uint8_t sec_status, ble_gap_sec_params_t const *p_sec_params, + ble_gap_sec_keyset_t const *p_sec_keyset)); + +/**@brief Reply with an authentication key. + * + * @details This function is only used to reply to a @ref BLE_GAP_EVT_AUTH_KEY_REQUEST or a @ref BLE_GAP_EVT_PASSKEY_DISPLAY, + * calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. + * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected + * parameters. + * + * @events + * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref + * sd_ble_gap_authenticate.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_CENTRAL_OOB_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] key_type See @ref BLE_GAP_AUTH_KEY_TYPES. + * @param[in] p_key If key type is @ref BLE_GAP_AUTH_KEY_TYPE_NONE, then NULL. + * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_PASSKEY, then a 6-byte ASCII string (digit 0..9 only, no NULL + * termination) or NULL when confirming LE Secure Connections Numeric Comparison. If key type is @ref BLE_GAP_AUTH_KEY_TYPE_OOB, + * then a 16-byte OOB key value in little-endian format. + * + * @retval ::NRF_SUCCESS Authentication key successfully set. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Authentication key has not been requested. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_AUTH_KEY_REPLY, uint32_t, + sd_ble_gap_auth_key_reply(uint16_t conn_handle, uint8_t key_type, uint8_t const *p_key)); + +/**@brief Reply with an LE Secure connections DHKey. + * + * @details This function is only used to reply to a @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST, calling it at other times will result in + * an @ref NRF_ERROR_INVALID_STATE. + * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected + * parameters. + * + * @events + * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref + * sd_ble_gap_authenticate.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_dhkey LE Secure Connections DHKey. + * + * @retval ::NRF_SUCCESS DHKey successfully set. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either: + * - The peer is not authenticated. + * - The application has not pulled a @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST event. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_LESC_DHKEY_REPLY, uint32_t, + sd_ble_gap_lesc_dhkey_reply(uint16_t conn_handle, ble_gap_lesc_dhkey_t const *p_dhkey)); + +/**@brief Notify the peer of a local keypress. + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] kp_not See @ref BLE_GAP_KP_NOT_TYPES. + * + * @retval ::NRF_SUCCESS Keypress notification successfully queued for transmission. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either: + * - Authentication key not requested. + * - Passkey has not been entered. + * - Keypresses have not been enabled by both peers. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_BUSY The BLE stack is busy. Retry at later time. + */ +SVCALL(SD_BLE_GAP_KEYPRESS_NOTIFY, uint32_t, sd_ble_gap_keypress_notify(uint16_t conn_handle, uint8_t kp_not)); + +/**@brief Generate a set of OOB data to send to a peer out of band. + * + * @note The @ref ble_gap_addr_t included in the OOB data returned will be the currently active one (or, if a connection has + * already been established, the one used during connection setup). The application may manually overwrite it with an updated + * value. + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. Can be @ref BLE_CONN_HANDLE_INVALID if a BLE connection has not been established yet. + * @param[in] p_pk_own LE Secure Connections local P-256 Public Key. + * @param[out] p_oobd_own The OOB data to be sent out of band to a peer. + * + * @retval ::NRF_SUCCESS OOB data successfully generated. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_LESC_OOB_DATA_GET, uint32_t, + sd_ble_gap_lesc_oob_data_get(uint16_t conn_handle, ble_gap_lesc_p256_pk_t const *p_pk_own, + ble_gap_lesc_oob_data_t *p_oobd_own)); + +/**@brief Provide the OOB data sent/received out of band. + * + * @note An authentication procedure with OOB selected as an algorithm must be in progress when calling this function. + * @note A @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST event with the oobd_req set to 1 must have been received prior to calling this + * function. + * + * @events + * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref + * sd_ble_gap_authenticate.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_oobd_own The OOB data sent out of band to a peer or NULL if the peer has not received OOB data. + * Must correspond to @ref ble_gap_sec_params_t::oob flag in @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST. + * @param[in] p_oobd_peer The OOB data received out of band from a peer or NULL if none received. + * Must correspond to @ref ble_gap_sec_params_t::oob flag + * in @ref sd_ble_gap_authenticate in the central role or + * in @ref sd_ble_gap_sec_params_reply in the peripheral role. + * + * @retval ::NRF_SUCCESS OOB data accepted. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either: + * - Authentication key not requested + * - Not expecting LESC OOB data + * - Have not actually exchanged passkeys. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_LESC_OOB_DATA_SET, uint32_t, + sd_ble_gap_lesc_oob_data_set(uint16_t conn_handle, ble_gap_lesc_oob_data_t const *p_oobd_own, + ble_gap_lesc_oob_data_t const *p_oobd_peer)); + +/**@brief Initiate GAP Encryption procedure. + * + * @details In the central role, this function will initiate the encryption procedure using the encryption information provided. + * + * @events + * @event{@ref BLE_GAP_EVT_CONN_SEC_UPDATE, The connection security has been updated.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_ENC_MSC} + * @mmsc{@ref BLE_GAP_MULTILINK_CTRL_PROC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_SEC_REQ_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_master_id Pointer to a @ref ble_gap_master_id_t master identification structure. + * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure. + * + * @retval ::NRF_SUCCESS Successfully initiated authentication procedure. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE No link has been established. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::BLE_ERROR_INVALID_ROLE Operation is not supported in the Peripheral role. + * @retval ::NRF_ERROR_BUSY Procedure already in progress or not allowed at this time, wait for pending procedures to complete and + * retry. + */ +SVCALL(SD_BLE_GAP_ENCRYPT, uint32_t, + sd_ble_gap_encrypt(uint16_t conn_handle, ble_gap_master_id_t const *p_master_id, ble_gap_enc_info_t const *p_enc_info)); + +/**@brief Reply with GAP security information. + * + * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_INFO_REQUEST, calling it at other times will result in + * @ref NRF_ERROR_INVALID_STATE. + * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected + * parameters. + * @note Data signing is not yet supported, and p_sign_info must therefore be NULL. + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_ENC_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure. May be NULL to signal none is + * available. + * @param[in] p_id_info Pointer to a @ref ble_gap_irk_t identity information structure. May be NULL to signal none is available. + * @param[in] p_sign_info Pointer to a @ref ble_gap_sign_info_t signing information structure. May be NULL to signal none is + * available. + * + * @retval ::NRF_SUCCESS Successfully accepted security information. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either: + * - No link has been established. + * - No @ref BLE_GAP_EVT_SEC_INFO_REQUEST pending. + * - Encryption information provided by the app without being requested. See @ref + * ble_gap_evt_sec_info_request_t::enc_info. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_SEC_INFO_REPLY, uint32_t, + sd_ble_gap_sec_info_reply(uint16_t conn_handle, ble_gap_enc_info_t const *p_enc_info, ble_gap_irk_t const *p_id_info, + ble_gap_sign_info_t const *p_sign_info)); + +/**@brief Get the current connection security. + * + * @param[in] conn_handle Connection handle. + * @param[out] p_conn_sec Pointer to a @ref ble_gap_conn_sec_t structure to be filled in. + * + * @retval ::NRF_SUCCESS Current connection security successfully retrieved. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_CONN_SEC_GET, uint32_t, sd_ble_gap_conn_sec_get(uint16_t conn_handle, ble_gap_conn_sec_t *p_conn_sec)); + +/**@brief Start reporting the received signal strength to the application. + * + * A new event is reported whenever the RSSI value changes, until @ref sd_ble_gap_rssi_stop is called. + * + * @events + * @event{@ref BLE_GAP_EVT_RSSI_CHANGED, New RSSI data available. How often the event is generated is + * dependent on the settings of the threshold_dbm + * and skip_count input parameters.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC} + * @mmsc{@ref BLE_GAP_RSSI_FILT_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] threshold_dbm Minimum change in dBm before triggering the @ref BLE_GAP_EVT_RSSI_CHANGED event. Events are + * disabled if threshold_dbm equals @ref BLE_GAP_RSSI_THRESHOLD_INVALID. + * @param[in] skip_count Number of RSSI samples with a change of threshold_dbm or more before sending a new @ref + * BLE_GAP_EVT_RSSI_CHANGED event. + * + * @retval ::NRF_SUCCESS Successfully activated RSSI reporting. + * @retval ::NRF_ERROR_INVALID_STATE RSSI reporting is already ongoing. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_RSSI_START, uint32_t, sd_ble_gap_rssi_start(uint16_t conn_handle, uint8_t threshold_dbm, uint8_t skip_count)); + +/**@brief Stop reporting the received signal strength. + * + * @note An RSSI change detected before the call but not yet received by the application + * may be reported after @ref sd_ble_gap_rssi_stop has been called. + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC} + * @mmsc{@ref BLE_GAP_RSSI_FILT_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * + * @retval ::NRF_SUCCESS Successfully deactivated RSSI reporting. + * @retval ::NRF_ERROR_INVALID_STATE RSSI reporting is not ongoing. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_RSSI_STOP, uint32_t, sd_ble_gap_rssi_stop(uint16_t conn_handle)); + +/**@brief Get the received signal strength for the last connection event. + * + * @ref sd_ble_gap_rssi_start must be called to start reporting RSSI before using this function. @ref NRF_ERROR_NOT_FOUND + * will be returned until RSSI was sampled for the first time after calling @ref sd_ble_gap_rssi_start. + * @note ERRATA-153 and ERRATA-225 require the rssi sample to be compensated based on a temperature measurement. + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[out] p_rssi Pointer to the location where the RSSI measurement shall be stored. + * @param[out] p_ch_index Pointer to the location where Channel Index for the RSSI measurement shall be stored. + * + * @retval ::NRF_SUCCESS Successfully read the RSSI. + * @retval ::NRF_ERROR_NOT_FOUND No sample is available. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_INVALID_STATE RSSI reporting is not ongoing. + */ +SVCALL(SD_BLE_GAP_RSSI_GET, uint32_t, sd_ble_gap_rssi_get(uint16_t conn_handle, int8_t *p_rssi, uint8_t *p_ch_index)); + +/**@brief Start or continue scanning (GAP Discovery procedure, Observer Procedure). + * + * @note A call to this function will require the application to keep the memory pointed by + * p_adv_report_buffer alive until the buffer is released. The buffer is released when the scanner is stopped + * or when this function is called with another buffer. + * + * @note The scanner will automatically stop in the following cases: + * - @ref sd_ble_gap_scan_stop is called. + * - @ref sd_ble_gap_connect is called. + * - A @ref BLE_GAP_EVT_TIMEOUT with source set to @ref BLE_GAP_TIMEOUT_SRC_SCAN is received. + * - When a @ref BLE_GAP_EVT_ADV_REPORT event is received and @ref ble_gap_adv_report_type_t::status is not set to + * @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA. In this case scanning is only paused to let the application + * access received data. The application must call this function to continue scanning, or call @ref + * sd_ble_gap_scan_stop to stop scanning. + * + * @note If a @ref BLE_GAP_EVT_ADV_REPORT event is received with @ref ble_gap_adv_report_type_t::status set to + * @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA, the scanner will continue scanning, and the application will + * receive more reports from this advertising event. The following reports will include the old and new received data. + * + * @events + * @event{@ref BLE_GAP_EVT_ADV_REPORT, An advertising or scan response packet has been received.} + * @event{@ref BLE_GAP_EVT_TIMEOUT, Scanner has timed out.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_SCAN_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs + * + * @param[in] p_scan_params Pointer to scan parameters structure. When this function is used to continue + * scanning, this parameter must be NULL. + * @param[in] p_adv_report_buffer Pointer to buffer used to store incoming advertising data. + * The memory pointed to should be kept alive until the scanning is stopped. + * See @ref BLE_GAP_SCAN_BUFFER_SIZE for minimum and maximum buffer size. + * If the scanner receives advertising data larger than can be stored in the buffer, + * a @ref BLE_GAP_EVT_ADV_REPORT will be raised with @ref ble_gap_adv_report_type_t::status + * set to @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_TRUNCATED. + * + * @retval ::NRF_SUCCESS Successfully initiated scanning procedure. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either: + * - Scanning is already ongoing and p_scan_params was not NULL + * - Scanning is not running and p_scan_params was NULL. + * - The scanner has timed out when this function is called to continue scanning. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. See @ref ble_gap_scan_params_t. + * @retval ::NRF_ERROR_NOT_SUPPORTED Unsupported parameters supplied. See @ref ble_gap_scan_params_t. + * @retval ::NRF_ERROR_INVALID_LENGTH The provided buffer length is invalid. See @ref BLE_GAP_SCAN_BUFFER_MIN. + * @retval ::NRF_ERROR_RESOURCES Not enough BLE role slots available. + * Stop one or more currently active roles (Central, Peripheral or Broadcaster) and try again + */ +SVCALL(SD_BLE_GAP_SCAN_START, uint32_t, + sd_ble_gap_scan_start(ble_gap_scan_params_t const *p_scan_params, ble_data_t const *p_adv_report_buffer)); + +/**@brief Stop scanning (GAP Discovery procedure, Observer Procedure). + * + * @note The buffer provided in @ref sd_ble_gap_scan_start is released. + * + * @mscs + * @mmsc{@ref BLE_GAP_SCAN_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Successfully stopped scanning procedure. + * @retval ::NRF_ERROR_INVALID_STATE Not in the scanning state. + */ +SVCALL(SD_BLE_GAP_SCAN_STOP, uint32_t, sd_ble_gap_scan_stop(void)); + +/**@brief Create a connection (GAP Link Establishment). + * + * @note If a scanning procedure is currently in progress it will be automatically stopped when calling this function. + * The scanning procedure will be stopped even if the function returns an error. + * + * @events + * @event{@ref BLE_GAP_EVT_CONNECTED, A connection was established.} + * @event{@ref BLE_GAP_EVT_TIMEOUT, Failed to establish a connection.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_CONN_PRIV_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_CONN_MSC} + * @endmscs + * + * @param[in] p_peer_addr Pointer to peer identity address. If @ref ble_gap_scan_params_t::filter_policy is set to use + * whitelist, then p_peer_addr is ignored. + * @param[in] p_scan_params Pointer to scan parameters structure. + * @param[in] p_conn_params Pointer to desired connection parameters. + * @param[in] conn_cfg_tag Tag identifying a configuration set by @ref sd_ble_cfg_set or + * @ref BLE_CONN_CFG_TAG_DEFAULT to use the default connection configuration. + * + * @retval ::NRF_SUCCESS Successfully initiated connection procedure. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid parameter(s) pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * - Invalid parameter(s) in p_scan_params or p_conn_params. + * - Use of whitelist requested but whitelist has not been set, see @ref + * sd_ble_gap_whitelist_set. + * - Peer address was not present in the device identity list, see @ref + * sd_ble_gap_device_identities_set. + * @retval ::NRF_ERROR_NOT_FOUND conn_cfg_tag not found. + * @retval ::NRF_ERROR_INVALID_STATE The SoftDevice is in an invalid state to perform this operation. This may be due to an + * existing locally initiated connect procedure, which must complete before initiating again. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid Peer address. + * @retval ::NRF_ERROR_CONN_COUNT The limit of available connections for this connection configuration tag has been reached. + * To increase the number of available connections, + * use @ref sd_ble_cfg_set with @ref BLE_GAP_CFG_ROLE_COUNT or @ref BLE_CONN_CFG_GAP. + * @retval ::NRF_ERROR_RESOURCES Either: + * - Not enough BLE role slots available. + * Stop one or more currently active roles (Central, Peripheral or Observer) and try again. + * - The event_length parameter associated with conn_cfg_tag is too small to be able to + * establish a connection on the selected @ref ble_gap_scan_params_t::scan_phys. + * Use @ref sd_ble_cfg_set to increase the event length. + */ +SVCALL(SD_BLE_GAP_CONNECT, uint32_t, + sd_ble_gap_connect(ble_gap_addr_t const *p_peer_addr, ble_gap_scan_params_t const *p_scan_params, + ble_gap_conn_params_t const *p_conn_params, uint8_t conn_cfg_tag)); + +/**@brief Cancel a connection establishment. + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_CONN_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Successfully canceled an ongoing connection procedure. + * @retval ::NRF_ERROR_INVALID_STATE No locally initiated connect procedure started or connection + * completed occurred. + */ +SVCALL(SD_BLE_GAP_CONNECT_CANCEL, uint32_t, sd_ble_gap_connect_cancel(void)); + +/**@brief Initiate or respond to a PHY Update Procedure + * + * @details This function is used to initiate or respond to a PHY Update Procedure. It will always + * generate a @ref BLE_GAP_EVT_PHY_UPDATE event if successfully executed. + * If this function is used to initiate a PHY Update procedure and the only option + * provided in @ref ble_gap_phys_t::tx_phys and @ref ble_gap_phys_t::rx_phys is the + * currently active PHYs in the respective directions, the SoftDevice will generate a + * @ref BLE_GAP_EVT_PHY_UPDATE with the current PHYs set and will not initiate the + * procedure in the Link Layer. + * + * If @ref ble_gap_phys_t::tx_phys or @ref ble_gap_phys_t::rx_phys is @ref BLE_GAP_PHY_AUTO, + * then the stack will select PHYs based on the peer's PHY preferences and the local link + * configuration. The PHY Update procedure will for this case result in a PHY combination + * that respects the time constraints configured with @ref sd_ble_cfg_set and the current + * link layer data length. + * + * When acting as a central, the SoftDevice will select the fastest common PHY in each direction. + * + * If the peer does not support the PHY Update Procedure, then the resulting + * @ref BLE_GAP_EVT_PHY_UPDATE event will have a status set to + * @ref BLE_HCI_UNSUPPORTED_REMOTE_FEATURE. + * + * If the PHY Update procedure was rejected by the peer due to a procedure collision, the status + * will be @ref BLE_HCI_STATUS_CODE_LMP_ERROR_TRANSACTION_COLLISION or + * @ref BLE_HCI_DIFFERENT_TRANSACTION_COLLISION. + * If the peer responds to the PHY Update procedure with invalid parameters, the status + * will be @ref BLE_HCI_STATUS_CODE_INVALID_LMP_PARAMETERS. + * If the PHY Update procedure was rejected by the peer for a different reason, the status will + * contain the reason as specified by the peer. + * + * @events + * @event{@ref BLE_GAP_EVT_PHY_UPDATE, Result of the PHY Update Procedure.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_PHY_UPDATE} + * @mmsc{@ref BLE_GAP_PERIPHERAL_PHY_UPDATE} + * @endmscs + * + * @param[in] conn_handle Connection handle to indicate the connection for which the PHY Update is requested. + * @param[in] p_gap_phys Pointer to PHY structure. + * + * @retval ::NRF_SUCCESS Successfully requested a PHY Update. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE No link has been established. + * @retval ::NRF_ERROR_RESOURCES The connection event length configured for this link is not sufficient for the combination of + * @ref ble_gap_phys_t::tx_phys, @ref ble_gap_phys_t::rx_phys, and @ref + * ble_gap_data_length_params_t. The connection event length is configured with @ref BLE_CONN_CFG_GAP using @ref sd_ble_cfg_set. + * @retval ::NRF_ERROR_BUSY Procedure is already in progress or not allowed at this time. Process pending events and wait for the + * pending procedure to complete and retry. + * + */ +SVCALL(SD_BLE_GAP_PHY_UPDATE, uint32_t, sd_ble_gap_phy_update(uint16_t conn_handle, ble_gap_phys_t const *p_gap_phys)); + +/**@brief Initiate or respond to a Data Length Update Procedure. + * + * @note If the application uses @ref BLE_GAP_DATA_LENGTH_AUTO for one or more members of + * p_dl_params, the SoftDevice will choose the highest value supported in current + * configuration and connection parameters. + * @note If the link PHY is Coded, the SoftDevice will ensure that the MaxTxTime and/or MaxRxTime + * used in the Data Length Update procedure is at least 2704 us. Otherwise, MaxTxTime and + * MaxRxTime will be limited to maximum 2120 us. + * + * @param[in] conn_handle Connection handle. + * @param[in] p_dl_params Pointer to local parameters to be used in Data Length Update + * Procedure. Set any member to @ref BLE_GAP_DATA_LENGTH_AUTO to let + * the SoftDevice automatically decide the value for that member. + * Set to NULL to use automatic values for all members. + * @param[out] p_dl_limitation Pointer to limitation to be written when local device does not + * have enough resources or does not support the requested Data Length + * Update parameters. Ignored if NULL. + * + * @mscs + * @mmsc{@ref BLE_GAP_DATA_LENGTH_UPDATE_PROCEDURE_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Successfully set Data Length Extension initiation/response parameters. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter supplied. + * @retval ::NRF_ERROR_INVALID_STATE No link has been established. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameters supplied. + * @retval ::NRF_ERROR_NOT_SUPPORTED The requested parameters are not supported by the SoftDevice. Inspect + * p_dl_limitation to see which parameter is not supported. + * @retval ::NRF_ERROR_RESOURCES The connection event length configured for this link is not sufficient for the requested + * parameters. Use @ref sd_ble_cfg_set with @ref BLE_CONN_CFG_GAP to increase the connection event length. Inspect p_dl_limitation + * to see where the limitation is. + * @retval ::NRF_ERROR_BUSY Peer has already initiated a Data Length Update Procedure. Process the + * pending @ref BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST event to respond. + */ +SVCALL(SD_BLE_GAP_DATA_LENGTH_UPDATE, uint32_t, + sd_ble_gap_data_length_update(uint16_t conn_handle, ble_gap_data_length_params_t const *p_dl_params, + ble_gap_data_length_limitation_t *p_dl_limitation)); + +/**@brief Start the Quality of Service (QoS) channel survey module. + * + * @details The channel survey module provides measurements of the energy levels on + * the Bluetooth Low Energy channels. When the module is enabled, @ref BLE_GAP_EVT_QOS_CHANNEL_SURVEY_REPORT + * events will periodically report the measured energy levels for each channel. + * + * @note The measurements are scheduled with lower priority than other Bluetooth Low Energy roles, + * Radio Timeslot API events and Flash API events. + * + * @note The channel survey module will attempt to do measurements so that the average interval + * between measurements will be interval_us. However due to the channel survey module + * having the lowest priority of all roles and modules, this may not be possible. In that + * case fewer than expected channel survey reports may be given. + * + * @note In order to use the channel survey module, @ref ble_gap_cfg_role_count_t::qos_channel_survey_role_available + * must be set. This is done using @ref sd_ble_cfg_set. + * + * @param[in] interval_us Requested average interval for the measurements and reports. See + * @ref BLE_GAP_QOS_CHANNEL_SURVEY_INTERVALS for valid ranges. If set + * to @ref BLE_GAP_QOS_CHANNEL_SURVEY_INTERVAL_CONTINUOUS, the channel + * survey role will be scheduled at every available opportunity. + * + * @retval ::NRF_SUCCESS The module is successfully started. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter supplied. interval_us is out of the + * allowed range. + * @retval ::NRF_ERROR_INVALID_STATE Trying to start the module when already running. + * @retval ::NRF_ERROR_RESOURCES The channel survey module is not available to the application. + * Set @ref ble_gap_cfg_role_count_t::qos_channel_survey_role_available using + * @ref sd_ble_cfg_set. + */ +SVCALL(SD_BLE_GAP_QOS_CHANNEL_SURVEY_START, uint32_t, sd_ble_gap_qos_channel_survey_start(uint32_t interval_us)); + +/**@brief Stop the Quality of Service (QoS) channel survey module. + * + * @note The SoftDevice may generate one @ref BLE_GAP_EVT_QOS_CHANNEL_SURVEY_REPORT event after this + * function is called. + * + * @retval ::NRF_SUCCESS The module is successfully stopped. + * @retval ::NRF_ERROR_INVALID_STATE Trying to stop the module when it is not running. + */ +SVCALL(SD_BLE_GAP_QOS_CHANNEL_SURVEY_STOP, uint32_t, sd_ble_gap_qos_channel_survey_stop(void)); + +/**@brief Obtain the next connection event counter value. + * + * @details The connection event counter is initialized to zero on the first connection event. The value is incremented + * by one for each connection event. For more information see Bluetooth Core Specification v5.0, Vol 6, Part B, + * Section 4.5.1. + * + * @note The connection event counter obtained through this API will be outdated if this API is called + * at the same time as the connection event counter is incremented. + * + * @note This API will always return the last connection event counter + 1. + * The actual connection event may be multiple connection events later if: + * - Slave latency is enabled and there is no data to transmit or receive. + * - Another role is scheduled with a higher priority at the same time as the next connection event. + * + * @param[in] conn_handle Connection handle. + * @param[out] p_counter Pointer to the variable where the next connection event counter will be written. + * + * @retval ::NRF_SUCCESS The connection event counter was successfully retrieved. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter supplied. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + */ +SVCALL(SD_BLE_GAP_NEXT_CONN_EVT_COUNTER_GET, uint32_t, + sd_ble_gap_next_conn_evt_counter_get(uint16_t conn_handle, uint16_t *p_counter)); + +/**@brief Start triggering a given task on connection event start. + * + * @details When enabled, this feature will trigger a PPI task at the start of connection events. + * The application can configure the SoftDevice to trigger every N connection events starting from + * a given connection event counter. See also @ref ble_gap_conn_event_trigger_t. + * + * @param[in] conn_handle Connection handle. + * @param[in] p_params Connection event trigger parameters. + * + * @retval ::NRF_SUCCESS Success. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter supplied. See @ref ble_gap_conn_event_trigger_t. + * @retval ::NRF_ERROR_INVALID_STATE Either: + * - Trying to start connection event triggering when it is already ongoing. + * - @ref ble_gap_conn_event_trigger_t::conn_evt_counter_start is in the past. + * Use @ref sd_ble_gap_next_conn_evt_counter_get to find a new value + to be used as ble_gap_conn_event_trigger_t::conn_evt_counter_start. + */ +SVCALL(SD_BLE_GAP_CONN_EVT_TRIGGER_START, uint32_t, + sd_ble_gap_conn_evt_trigger_start(uint16_t conn_handle, ble_gap_conn_event_trigger_t const *p_params)); + +/**@brief Stop triggering the task configured using @ref sd_ble_gap_conn_evt_trigger_start. + * + * @param[in] conn_handle Connection handle. + * + * @retval ::NRF_SUCCESS Success. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_INVALID_STATE Trying to stop connection event triggering when it is not enabled. + */ +SVCALL(SD_BLE_GAP_CONN_EVT_TRIGGER_STOP, uint32_t, sd_ble_gap_conn_evt_trigger_stop(uint16_t conn_handle)); + +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // BLE_GAP_H__ + +/** + @} +*/ diff --git a/variants/xiao_ble/softdevice/ble_gatt.h b/variants/xiao_ble/softdevice/ble_gatt.h new file mode 100644 index 000000000..df0d728fc --- /dev/null +++ b/variants/xiao_ble/softdevice/ble_gatt.h @@ -0,0 +1,232 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + @addtogroup BLE_GATT Generic Attribute Profile (GATT) Common + @{ + @brief Common definitions and prototypes for the GATT interfaces. + */ + +#ifndef BLE_GATT_H__ +#define BLE_GATT_H__ + +#include "ble_err.h" +#include "ble_hci.h" +#include "ble_ranges.h" +#include "ble_types.h" +#include "nrf_error.h" +#include "nrf_svc.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup BLE_GATT_DEFINES Defines + * @{ */ + +/** @brief Default ATT MTU, in bytes. */ +#define BLE_GATT_ATT_MTU_DEFAULT 23 + +/**@brief Invalid Attribute Handle. */ +#define BLE_GATT_HANDLE_INVALID 0x0000 + +/**@brief First Attribute Handle. */ +#define BLE_GATT_HANDLE_START 0x0001 + +/**@brief Last Attribute Handle. */ +#define BLE_GATT_HANDLE_END 0xFFFF + +/** @defgroup BLE_GATT_TIMEOUT_SOURCES GATT Timeout sources + * @{ */ +#define BLE_GATT_TIMEOUT_SRC_PROTOCOL 0x00 /**< ATT Protocol timeout. */ +/** @} */ + +/** @defgroup BLE_GATT_WRITE_OPS GATT Write operations + * @{ */ +#define BLE_GATT_OP_INVALID 0x00 /**< Invalid Operation. */ +#define BLE_GATT_OP_WRITE_REQ 0x01 /**< Write Request. */ +#define BLE_GATT_OP_WRITE_CMD 0x02 /**< Write Command. */ +#define BLE_GATT_OP_SIGN_WRITE_CMD 0x03 /**< Signed Write Command. */ +#define BLE_GATT_OP_PREP_WRITE_REQ 0x04 /**< Prepare Write Request. */ +#define BLE_GATT_OP_EXEC_WRITE_REQ 0x05 /**< Execute Write Request. */ +/** @} */ + +/** @defgroup BLE_GATT_EXEC_WRITE_FLAGS GATT Execute Write flags + * @{ */ +#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL 0x00 /**< Cancel prepared write. */ +#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE 0x01 /**< Execute prepared write. */ +/** @} */ + +/** @defgroup BLE_GATT_HVX_TYPES GATT Handle Value operations + * @{ */ +#define BLE_GATT_HVX_INVALID 0x00 /**< Invalid Operation. */ +#define BLE_GATT_HVX_NOTIFICATION 0x01 /**< Handle Value Notification. */ +#define BLE_GATT_HVX_INDICATION 0x02 /**< Handle Value Indication. */ +/** @} */ + +/** @defgroup BLE_GATT_STATUS_CODES GATT Status Codes + * @{ */ +#define BLE_GATT_STATUS_SUCCESS 0x0000 /**< Success. */ +#define BLE_GATT_STATUS_UNKNOWN 0x0001 /**< Unknown or not applicable status. */ +#define BLE_GATT_STATUS_ATTERR_INVALID 0x0100 /**< ATT Error: Invalid Error Code. */ +#define BLE_GATT_STATUS_ATTERR_INVALID_HANDLE 0x0101 /**< ATT Error: Invalid Attribute Handle. */ +#define BLE_GATT_STATUS_ATTERR_READ_NOT_PERMITTED 0x0102 /**< ATT Error: Read not permitted. */ +#define BLE_GATT_STATUS_ATTERR_WRITE_NOT_PERMITTED 0x0103 /**< ATT Error: Write not permitted. */ +#define BLE_GATT_STATUS_ATTERR_INVALID_PDU 0x0104 /**< ATT Error: Used in ATT as Invalid PDU. */ +#define BLE_GATT_STATUS_ATTERR_INSUF_AUTHENTICATION 0x0105 /**< ATT Error: Authenticated link required. */ +#define BLE_GATT_STATUS_ATTERR_REQUEST_NOT_SUPPORTED 0x0106 /**< ATT Error: Used in ATT as Request Not Supported. */ +#define BLE_GATT_STATUS_ATTERR_INVALID_OFFSET 0x0107 /**< ATT Error: Offset specified was past the end of the attribute. */ +#define BLE_GATT_STATUS_ATTERR_INSUF_AUTHORIZATION 0x0108 /**< ATT Error: Used in ATT as Insufficient Authorization. */ +#define BLE_GATT_STATUS_ATTERR_PREPARE_QUEUE_FULL 0x0109 /**< ATT Error: Used in ATT as Prepare Queue Full. */ +#define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND 0x010A /**< ATT Error: Used in ATT as Attribute not found. */ +#define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_LONG \ + 0x010B /**< ATT Error: Attribute cannot be read or written using read/write blob requests. */ +#define BLE_GATT_STATUS_ATTERR_INSUF_ENC_KEY_SIZE 0x010C /**< ATT Error: Encryption key size used is insufficient. */ +#define BLE_GATT_STATUS_ATTERR_INVALID_ATT_VAL_LENGTH 0x010D /**< ATT Error: Invalid value size. */ +#define BLE_GATT_STATUS_ATTERR_UNLIKELY_ERROR 0x010E /**< ATT Error: Very unlikely error. */ +#define BLE_GATT_STATUS_ATTERR_INSUF_ENCRYPTION 0x010F /**< ATT Error: Encrypted link required. */ +#define BLE_GATT_STATUS_ATTERR_UNSUPPORTED_GROUP_TYPE \ + 0x0110 /**< ATT Error: Attribute type is not a supported grouping attribute. */ +#define BLE_GATT_STATUS_ATTERR_INSUF_RESOURCES 0x0111 /**< ATT Error: Insufficient resources. */ +#define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_BEGIN 0x0112 /**< ATT Error: Reserved for Future Use range #1 begin. */ +#define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_END 0x017F /**< ATT Error: Reserved for Future Use range #1 end. */ +#define BLE_GATT_STATUS_ATTERR_APP_BEGIN 0x0180 /**< ATT Error: Application range begin. */ +#define BLE_GATT_STATUS_ATTERR_APP_END 0x019F /**< ATT Error: Application range end. */ +#define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_BEGIN 0x01A0 /**< ATT Error: Reserved for Future Use range #2 begin. */ +#define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_END 0x01DF /**< ATT Error: Reserved for Future Use range #2 end. */ +#define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_BEGIN 0x01E0 /**< ATT Error: Reserved for Future Use range #3 begin. */ +#define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_END 0x01FC /**< ATT Error: Reserved for Future Use range #3 end. */ +#define BLE_GATT_STATUS_ATTERR_CPS_WRITE_REQ_REJECTED \ + 0x01FC /**< ATT Common Profile and Service Error: Write request rejected. \ + */ +#define BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR \ + 0x01FD /**< ATT Common Profile and Service Error: Client Characteristic Configuration Descriptor improperly configured. */ +#define BLE_GATT_STATUS_ATTERR_CPS_PROC_ALR_IN_PROG \ + 0x01FE /**< ATT Common Profile and Service Error: Procedure Already in Progress. */ +#define BLE_GATT_STATUS_ATTERR_CPS_OUT_OF_RANGE 0x01FF /**< ATT Common Profile and Service Error: Out Of Range. */ +/** @} */ + +/** @defgroup BLE_GATT_CPF_FORMATS Characteristic Presentation Formats + * @note Found at + * http://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml + * @{ */ +#define BLE_GATT_CPF_FORMAT_RFU 0x00 /**< Reserved For Future Use. */ +#define BLE_GATT_CPF_FORMAT_BOOLEAN 0x01 /**< Boolean. */ +#define BLE_GATT_CPF_FORMAT_2BIT 0x02 /**< Unsigned 2-bit integer. */ +#define BLE_GATT_CPF_FORMAT_NIBBLE 0x03 /**< Unsigned 4-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT8 0x04 /**< Unsigned 8-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT12 0x05 /**< Unsigned 12-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT16 0x06 /**< Unsigned 16-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT24 0x07 /**< Unsigned 24-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT32 0x08 /**< Unsigned 32-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT48 0x09 /**< Unsigned 48-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT64 0x0A /**< Unsigned 64-bit integer. */ +#define BLE_GATT_CPF_FORMAT_UINT128 0x0B /**< Unsigned 128-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT8 0x0C /**< Signed 2-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT12 0x0D /**< Signed 12-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT16 0x0E /**< Signed 16-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT24 0x0F /**< Signed 24-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT32 0x10 /**< Signed 32-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT48 0x11 /**< Signed 48-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT64 0x12 /**< Signed 64-bit integer. */ +#define BLE_GATT_CPF_FORMAT_SINT128 0x13 /**< Signed 128-bit integer. */ +#define BLE_GATT_CPF_FORMAT_FLOAT32 0x14 /**< IEEE-754 32-bit floating point. */ +#define BLE_GATT_CPF_FORMAT_FLOAT64 0x15 /**< IEEE-754 64-bit floating point. */ +#define BLE_GATT_CPF_FORMAT_SFLOAT 0x16 /**< IEEE-11073 16-bit SFLOAT. */ +#define BLE_GATT_CPF_FORMAT_FLOAT 0x17 /**< IEEE-11073 32-bit FLOAT. */ +#define BLE_GATT_CPF_FORMAT_DUINT16 0x18 /**< IEEE-20601 format. */ +#define BLE_GATT_CPF_FORMAT_UTF8S 0x19 /**< UTF-8 string. */ +#define BLE_GATT_CPF_FORMAT_UTF16S 0x1A /**< UTF-16 string. */ +#define BLE_GATT_CPF_FORMAT_STRUCT 0x1B /**< Opaque Structure. */ +/** @} */ + +/** @defgroup BLE_GATT_CPF_NAMESPACES GATT Bluetooth Namespaces + * @{ + */ +#define BLE_GATT_CPF_NAMESPACE_BTSIG 0x01 /**< Bluetooth SIG defined Namespace. */ +#define BLE_GATT_CPF_NAMESPACE_DESCRIPTION_UNKNOWN 0x0000 /**< Namespace Description Unknown. */ +/** @} */ + +/** @} */ + +/** @addtogroup BLE_GATT_STRUCTURES Structures + * @{ */ + +/** + * @brief BLE GATT connection configuration parameters, set with @ref sd_ble_cfg_set. + * + * @retval ::NRF_ERROR_INVALID_PARAM att_mtu is smaller than @ref BLE_GATT_ATT_MTU_DEFAULT. + */ +typedef struct { + uint16_t att_mtu; /**< Maximum size of ATT packet the SoftDevice can send or receive. + The default and minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT. + @mscs + @mmsc{@ref BLE_GATTC_MTU_EXCHANGE} + @mmsc{@ref BLE_GATTS_MTU_EXCHANGE} + @endmscs + */ +} ble_gatt_conn_cfg_t; + +/**@brief GATT Characteristic Properties. */ +typedef struct { + /* Standard properties */ + uint8_t broadcast : 1; /**< Broadcasting of the value permitted. */ + uint8_t read : 1; /**< Reading the value permitted. */ + uint8_t write_wo_resp : 1; /**< Writing the value with Write Command permitted. */ + uint8_t write : 1; /**< Writing the value with Write Request permitted. */ + uint8_t notify : 1; /**< Notification of the value permitted. */ + uint8_t indicate : 1; /**< Indications of the value permitted. */ + uint8_t auth_signed_wr : 1; /**< Writing the value with Signed Write Command permitted. */ +} ble_gatt_char_props_t; + +/**@brief GATT Characteristic Extended Properties. */ +typedef struct { + /* Extended properties */ + uint8_t reliable_wr : 1; /**< Writing the value with Queued Write operations permitted. */ + uint8_t wr_aux : 1; /**< Writing the Characteristic User Description descriptor permitted. */ +} ble_gatt_char_ext_props_t; + +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // BLE_GATT_H__ + +/** @} */ diff --git a/variants/xiao_ble/softdevice/ble_gattc.h b/variants/xiao_ble/softdevice/ble_gattc.h new file mode 100644 index 000000000..f1df1782c --- /dev/null +++ b/variants/xiao_ble/softdevice/ble_gattc.h @@ -0,0 +1,764 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + @addtogroup BLE_GATTC Generic Attribute Profile (GATT) Client + @{ + @brief Definitions and prototypes for the GATT Client interface. + */ + +#ifndef BLE_GATTC_H__ +#define BLE_GATTC_H__ + +#include "ble_err.h" +#include "ble_gatt.h" +#include "ble_ranges.h" +#include "ble_types.h" +#include "nrf.h" +#include "nrf_error.h" +#include "nrf_svc.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup BLE_GATTC_ENUMERATIONS Enumerations + * @{ */ + +/**@brief GATTC API SVC numbers. */ +enum BLE_GATTC_SVCS { + SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER = BLE_GATTC_SVC_BASE, /**< Primary Service Discovery. */ + SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, /**< Relationship Discovery. */ + SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, /**< Characteristic Discovery. */ + SD_BLE_GATTC_DESCRIPTORS_DISCOVER, /**< Characteristic Descriptor Discovery. */ + SD_BLE_GATTC_ATTR_INFO_DISCOVER, /**< Attribute Information Discovery. */ + SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, /**< Read Characteristic Value by UUID. */ + SD_BLE_GATTC_READ, /**< Generic read. */ + SD_BLE_GATTC_CHAR_VALUES_READ, /**< Read multiple Characteristic Values. */ + SD_BLE_GATTC_WRITE, /**< Generic write. */ + SD_BLE_GATTC_HV_CONFIRM, /**< Handle Value Confirmation. */ + SD_BLE_GATTC_EXCHANGE_MTU_REQUEST, /**< Exchange MTU Request. */ +}; + +/** + * @brief GATT Client Event IDs. + */ +enum BLE_GATTC_EVTS { + BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP = BLE_GATTC_EVT_BASE, /**< Primary Service Discovery Response event. \n See @ref + ble_gattc_evt_prim_srvc_disc_rsp_t. */ + BLE_GATTC_EVT_REL_DISC_RSP, /**< Relationship Discovery Response event. \n See @ref ble_gattc_evt_rel_disc_rsp_t. + */ + BLE_GATTC_EVT_CHAR_DISC_RSP, /**< Characteristic Discovery Response event. \n See @ref + ble_gattc_evt_char_disc_rsp_t. */ + BLE_GATTC_EVT_DESC_DISC_RSP, /**< Descriptor Discovery Response event. \n See @ref + ble_gattc_evt_desc_disc_rsp_t. */ + BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, /**< Attribute Information Response event. \n See @ref + ble_gattc_evt_attr_info_disc_rsp_t. */ + BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP, /**< Read By UUID Response event. \n See @ref + ble_gattc_evt_char_val_by_uuid_read_rsp_t. */ + BLE_GATTC_EVT_READ_RSP, /**< Read Response event. \n See @ref ble_gattc_evt_read_rsp_t. */ + BLE_GATTC_EVT_CHAR_VALS_READ_RSP, /**< Read multiple Response event. \n See @ref + ble_gattc_evt_char_vals_read_rsp_t. */ + BLE_GATTC_EVT_WRITE_RSP, /**< Write Response event. \n See @ref ble_gattc_evt_write_rsp_t. */ + BLE_GATTC_EVT_HVX, /**< Handle Value Notification or Indication event. \n Confirm indication with @ref + sd_ble_gattc_hv_confirm. \n See @ref ble_gattc_evt_hvx_t. */ + BLE_GATTC_EVT_EXCHANGE_MTU_RSP, /**< Exchange MTU Response event. \n See @ref + ble_gattc_evt_exchange_mtu_rsp_t. */ + BLE_GATTC_EVT_TIMEOUT, /**< Timeout event. \n See @ref ble_gattc_evt_timeout_t. */ + BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE /**< Write without Response transmission complete. \n See @ref + ble_gattc_evt_write_cmd_tx_complete_t. */ +}; + +/**@brief GATTC Option IDs. + * IDs that uniquely identify a GATTC option. + */ +enum BLE_GATTC_OPTS { + BLE_GATTC_OPT_UUID_DISC = BLE_GATTC_OPT_BASE, /**< UUID discovery. @ref ble_gattc_opt_uuid_disc_t */ +}; + +/** @} */ + +/** @addtogroup BLE_GATTC_DEFINES Defines + * @{ */ + +/** @defgroup BLE_ERRORS_GATTC SVC return values specific to GATTC + * @{ */ +#define BLE_ERROR_GATTC_PROC_NOT_PERMITTED (NRF_GATTC_ERR_BASE + 0x000) /**< Procedure not Permitted. */ +/** @} */ + +/** @defgroup BLE_GATTC_ATTR_INFO_FORMAT Attribute Information Formats + * @{ */ +#define BLE_GATTC_ATTR_INFO_FORMAT_16BIT 1 /**< 16-bit Attribute Information Format. */ +#define BLE_GATTC_ATTR_INFO_FORMAT_128BIT 2 /**< 128-bit Attribute Information Format. */ +/** @} */ + +/** @defgroup BLE_GATTC_DEFAULTS GATT Client defaults + * @{ */ +#define BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT \ + 1 /**< Default number of Write without Response that can be queued for transmission. */ +/** @} */ + +/** @} */ + +/** @addtogroup BLE_GATTC_STRUCTURES Structures + * @{ */ + +/** + * @brief BLE GATTC connection configuration parameters, set with @ref sd_ble_cfg_set. + */ +typedef struct { + uint8_t write_cmd_tx_queue_size; /**< The guaranteed minimum number of Write without Response that can be queued for + transmission. The default value is @ref BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT */ +} ble_gattc_conn_cfg_t; + +/**@brief Operation Handle Range. */ +typedef struct { + uint16_t start_handle; /**< Start Handle. */ + uint16_t end_handle; /**< End Handle. */ +} ble_gattc_handle_range_t; + +/**@brief GATT service. */ +typedef struct { + ble_uuid_t uuid; /**< Service UUID. */ + ble_gattc_handle_range_t handle_range; /**< Service Handle Range. */ +} ble_gattc_service_t; + +/**@brief GATT include. */ +typedef struct { + uint16_t handle; /**< Include Handle. */ + ble_gattc_service_t included_srvc; /**< Handle of the included service. */ +} ble_gattc_include_t; + +/**@brief GATT characteristic. */ +typedef struct { + ble_uuid_t uuid; /**< Characteristic UUID. */ + ble_gatt_char_props_t char_props; /**< Characteristic Properties. */ + uint8_t char_ext_props : 1; /**< Extended properties present. */ + uint16_t handle_decl; /**< Handle of the Characteristic Declaration. */ + uint16_t handle_value; /**< Handle of the Characteristic Value. */ +} ble_gattc_char_t; + +/**@brief GATT descriptor. */ +typedef struct { + uint16_t handle; /**< Descriptor Handle. */ + ble_uuid_t uuid; /**< Descriptor UUID. */ +} ble_gattc_desc_t; + +/**@brief Write Parameters. */ +typedef struct { + uint8_t write_op; /**< Write Operation to be performed, see @ref BLE_GATT_WRITE_OPS. */ + uint8_t flags; /**< Flags, see @ref BLE_GATT_EXEC_WRITE_FLAGS. */ + uint16_t handle; /**< Handle to the attribute to be written. */ + uint16_t offset; /**< Offset in bytes. @note For WRITE_CMD and WRITE_REQ, offset must be 0. */ + uint16_t len; /**< Length of data in bytes. */ + uint8_t const *p_value; /**< Pointer to the value data. */ +} ble_gattc_write_params_t; + +/**@brief Attribute Information for 16-bit Attribute UUID. */ +typedef struct { + uint16_t handle; /**< Attribute handle. */ + ble_uuid_t uuid; /**< 16-bit Attribute UUID. */ +} ble_gattc_attr_info16_t; + +/**@brief Attribute Information for 128-bit Attribute UUID. */ +typedef struct { + uint16_t handle; /**< Attribute handle. */ + ble_uuid128_t uuid; /**< 128-bit Attribute UUID. */ +} ble_gattc_attr_info128_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP. */ +typedef struct { + uint16_t count; /**< Service count. */ + ble_gattc_service_t services[1]; /**< Service data. @note This is a variable length array. The size of 1 indicated is only a + placeholder for compilation. See @ref sd_ble_evt_get for more information on how to use + event structures with variable length array members. */ +} ble_gattc_evt_prim_srvc_disc_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_REL_DISC_RSP. */ +typedef struct { + uint16_t count; /**< Include count. */ + ble_gattc_include_t includes[1]; /**< Include data. @note This is a variable length array. The size of 1 indicated is only a + placeholder for compilation. See @ref sd_ble_evt_get for more information on how to use + event structures with variable length array members. */ +} ble_gattc_evt_rel_disc_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_DISC_RSP. */ +typedef struct { + uint16_t count; /**< Characteristic count. */ + ble_gattc_char_t chars[1]; /**< Characteristic data. @note This is a variable length array. The size of 1 indicated is only a + placeholder for compilation. See @ref sd_ble_evt_get for more information on how to use event + structures with variable length array members. */ +} ble_gattc_evt_char_disc_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_DESC_DISC_RSP. */ +typedef struct { + uint16_t count; /**< Descriptor count. */ + ble_gattc_desc_t descs[1]; /**< Descriptor data. @note This is a variable length array. The size of 1 indicated is only a + placeholder for compilation. See @ref sd_ble_evt_get for more information on how to use event + structures with variable length array members. */ +} ble_gattc_evt_desc_disc_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_ATTR_INFO_DISC_RSP. */ +typedef struct { + uint16_t count; /**< Attribute count. */ + uint8_t format; /**< Attribute information format, see @ref BLE_GATTC_ATTR_INFO_FORMAT. */ + union { + ble_gattc_attr_info16_t attr_info16[1]; /**< Attribute information for 16-bit Attribute UUID. + @note This is a variable length array. The size of 1 indicated is only a + placeholder for compilation. See @ref sd_ble_evt_get for more information on + how to use event structures with variable length array members. */ + ble_gattc_attr_info128_t attr_info128[1]; /**< Attribute information for 128-bit Attribute UUID. + @note This is a variable length array. The size of 1 indicated is only a + placeholder for compilation. See @ref sd_ble_evt_get for more information on + how to use event structures with variable length array members. */ + } info; /**< Attribute information union. */ +} ble_gattc_evt_attr_info_disc_rsp_t; + +/**@brief GATT read by UUID handle value pair. */ +typedef struct { + uint16_t handle; /**< Attribute Handle. */ + uint8_t *p_value; /**< Pointer to the Attribute Value, length is available in @ref + ble_gattc_evt_char_val_by_uuid_read_rsp_t::value_len. */ +} ble_gattc_handle_value_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP. */ +typedef struct { + uint16_t count; /**< Handle-Value Pair Count. */ + uint16_t value_len; /**< Length of the value in Handle-Value(s) list. */ + uint8_t handle_value[1]; /**< Handle-Value(s) list. To iterate through the list use @ref + sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter. + @note This is a variable length array. The size of 1 indicated is only a placeholder for + compilation. See @ref sd_ble_evt_get for more information on how to use event structures with + variable length array members. */ +} ble_gattc_evt_char_val_by_uuid_read_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_READ_RSP. */ +typedef struct { + uint16_t handle; /**< Attribute Handle. */ + uint16_t offset; /**< Offset of the attribute data. */ + uint16_t len; /**< Attribute data length. */ + uint8_t data[1]; /**< Attribute data. @note This is a variable length array. The size of 1 indicated is only a placeholder for + compilation. See @ref sd_ble_evt_get for more information on how to use event structures with variable + length array members. */ +} ble_gattc_evt_read_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP. */ +typedef struct { + uint16_t len; /**< Concatenated Attribute values length. */ + uint8_t values[1]; /**< Attribute values. @note This is a variable length array. The size of 1 indicated is only a placeholder + for compilation. See @ref sd_ble_evt_get for more information on how to use event structures with + variable length array members. */ +} ble_gattc_evt_char_vals_read_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_WRITE_RSP. */ +typedef struct { + uint16_t handle; /**< Attribute Handle. */ + uint8_t write_op; /**< Type of write operation, see @ref BLE_GATT_WRITE_OPS. */ + uint16_t offset; /**< Data offset. */ + uint16_t len; /**< Data length. */ + uint8_t data[1]; /**< Data. @note This is a variable length array. The size of 1 indicated is only a placeholder for + compilation. See @ref sd_ble_evt_get for more information on how to use event structures with variable + length array members. */ +} ble_gattc_evt_write_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_HVX. */ +typedef struct { + uint16_t handle; /**< Handle to which the HVx operation applies. */ + uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */ + uint16_t len; /**< Attribute data length. */ + uint8_t data[1]; /**< Attribute data. @note This is a variable length array. The size of 1 indicated is only a placeholder for + compilation. See @ref sd_ble_evt_get for more information on how to use event structures with variable + length array members. */ +} ble_gattc_evt_hvx_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP. */ +typedef struct { + uint16_t server_rx_mtu; /**< Server RX MTU size. */ +} ble_gattc_evt_exchange_mtu_rsp_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_TIMEOUT. */ +typedef struct { + uint8_t src; /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */ +} ble_gattc_evt_timeout_t; + +/**@brief Event structure for @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE. */ +typedef struct { + uint8_t count; /**< Number of write without response transmissions completed. */ +} ble_gattc_evt_write_cmd_tx_complete_t; + +/**@brief GATTC event structure. */ +typedef struct { + uint16_t conn_handle; /**< Connection Handle on which event occurred. */ + uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */ + uint16_t + error_handle; /**< In case of error: The handle causing the error. In all other cases @ref BLE_GATT_HANDLE_INVALID. */ + union { + ble_gattc_evt_prim_srvc_disc_rsp_t prim_srvc_disc_rsp; /**< Primary Service Discovery Response Event Parameters. */ + ble_gattc_evt_rel_disc_rsp_t rel_disc_rsp; /**< Relationship Discovery Response Event Parameters. */ + ble_gattc_evt_char_disc_rsp_t char_disc_rsp; /**< Characteristic Discovery Response Event Parameters. */ + ble_gattc_evt_desc_disc_rsp_t desc_disc_rsp; /**< Descriptor Discovery Response Event Parameters. */ + ble_gattc_evt_char_val_by_uuid_read_rsp_t + char_val_by_uuid_read_rsp; /**< Characteristic Value Read by UUID Response Event Parameters. */ + ble_gattc_evt_read_rsp_t read_rsp; /**< Read Response Event Parameters. */ + ble_gattc_evt_char_vals_read_rsp_t char_vals_read_rsp; /**< Characteristic Values Read Response Event Parameters. */ + ble_gattc_evt_write_rsp_t write_rsp; /**< Write Response Event Parameters. */ + ble_gattc_evt_hvx_t hvx; /**< Handle Value Notification/Indication Event Parameters. */ + ble_gattc_evt_exchange_mtu_rsp_t exchange_mtu_rsp; /**< Exchange MTU Response Event Parameters. */ + ble_gattc_evt_timeout_t timeout; /**< Timeout Event Parameters. */ + ble_gattc_evt_attr_info_disc_rsp_t attr_info_disc_rsp; /**< Attribute Information Discovery Event Parameters. */ + ble_gattc_evt_write_cmd_tx_complete_t + write_cmd_tx_complete; /**< Write without Response transmission complete Event Parameters. */ + } params; /**< Event Parameters. @note Only valid if @ref gatt_status == @ref BLE_GATT_STATUS_SUCCESS. */ +} ble_gattc_evt_t; + +/**@brief UUID discovery option. + * + * @details Used with @ref sd_ble_opt_set to enable and disable automatic insertion of discovered 128-bit UUIDs to the + * Vendor Specific UUID table. Disabled by default. + * - When disabled, if a procedure initiated by + * @ref sd_ble_gattc_primary_services_discover, + * @ref sd_ble_gattc_relationships_discover, + * @ref sd_ble_gattc_characteristics_discover, + * @ref sd_ble_gattc_descriptors_discover + * finds a 128-bit UUID which was not added by @ref sd_ble_uuid_vs_add, @ref ble_uuid_t::type will be set + * to @ref BLE_UUID_TYPE_UNKNOWN in the corresponding event. + * - When enabled, all found 128-bit UUIDs will be automatically added. The application can use + * @ref sd_ble_uuid_encode to retrieve the 128-bit UUID from @ref ble_uuid_t received in the corresponding + * event. If the total number of Vendor Specific UUIDs exceeds the table capacity, @ref ble_uuid_t::type will + * be set to @ref BLE_UUID_TYPE_UNKNOWN in the corresponding event. + * See also @ref ble_common_cfg_vs_uuid_t, @ref sd_ble_uuid_vs_remove. + * + * @note @ref sd_ble_opt_get is not supported for this option. + * + * @retval ::NRF_SUCCESS Set successfully. + * + */ +typedef struct { + uint8_t auto_add_vs_enable : 1; /**< Set to 1 to enable (or 0 to disable) automatic insertion of discovered 128-bit UUIDs. */ +} ble_gattc_opt_uuid_disc_t; + +/**@brief Option structure for GATTC options. */ +typedef union { + ble_gattc_opt_uuid_disc_t uuid_disc; /**< Parameters for the UUID discovery option. */ +} ble_gattc_opt_t; + +/** @} */ + +/** @addtogroup BLE_GATTC_FUNCTIONS Functions + * @{ */ + +/**@brief Initiate or continue a GATT Primary Service Discovery procedure. + * + * @details This function initiates or resumes a Primary Service discovery procedure, starting from the supplied handle. + * If the last service has not been reached, this function must be called again with an updated start handle value to + * continue the search. See also @ref ble_gattc_opt_uuid_disc_t. + * + * @events + * @event{@ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_PRIM_SRVC_DISC_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] start_handle Handle to start searching from. + * @param[in] p_srvc_uuid Pointer to the service UUID to be found. If it is NULL, all primary services will be returned. + * + * @retval ::NRF_SUCCESS Successfully started or resumed the Primary Service Discovery procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without + * reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER, uint32_t, + sd_ble_gattc_primary_services_discover(uint16_t conn_handle, uint16_t start_handle, ble_uuid_t const *p_srvc_uuid)); + +/**@brief Initiate or continue a GATT Relationship Discovery procedure. + * + * @details This function initiates or resumes the Find Included Services sub-procedure. If the last included service has not been + * reached, this must be called again with an updated handle range to continue the search. See also @ref + * ble_gattc_opt_uuid_disc_t. + * + * @events + * @event{@ref BLE_GATTC_EVT_REL_DISC_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_REL_DISC_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on. + * + * @retval ::NRF_SUCCESS Successfully started or resumed the Relationship Discovery procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without + * reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, uint32_t, + sd_ble_gattc_relationships_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range)); + +/**@brief Initiate or continue a GATT Characteristic Discovery procedure. + * + * @details This function initiates or resumes a Characteristic discovery procedure. If the last Characteristic has not been + * reached, this must be called again with an updated handle range to continue the discovery. See also @ref + * ble_gattc_opt_uuid_disc_t. + * + * @events + * @event{@ref BLE_GATTC_EVT_CHAR_DISC_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_CHAR_DISC_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on. + * + * @retval ::NRF_SUCCESS Successfully started or resumed the Characteristic Discovery procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without + * reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, uint32_t, + sd_ble_gattc_characteristics_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range)); + +/**@brief Initiate or continue a GATT Characteristic Descriptor Discovery procedure. + * + * @details This function initiates or resumes a Characteristic Descriptor discovery procedure. If the last Descriptor has not + * been reached, this must be called again with an updated handle range to continue the discovery. See also @ref + * ble_gattc_opt_uuid_disc_t. + * + * @events + * @event{@ref BLE_GATTC_EVT_DESC_DISC_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_DESC_DISC_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_handle_range A pointer to the range of handles of the Characteristic to perform this procedure on. + * + * @retval ::NRF_SUCCESS Successfully started or resumed the Descriptor Discovery procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without + * reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_DESCRIPTORS_DISCOVER, uint32_t, + sd_ble_gattc_descriptors_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range)); + +/**@brief Initiate or continue a GATT Read using Characteristic UUID procedure. + * + * @details This function initiates or resumes a Read using Characteristic UUID procedure. If the last Characteristic has not been + * reached, this must be called again with an updated handle range to continue the discovery. + * + * @events + * @event{@ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_READ_UUID_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_uuid Pointer to a Characteristic value UUID to read. + * @param[in] p_handle_range A pointer to the range of handles to perform this procedure on. + * + * @retval ::NRF_SUCCESS Successfully started or resumed the Read using Characteristic UUID procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without + * reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, uint32_t, + sd_ble_gattc_char_value_by_uuid_read(uint16_t conn_handle, ble_uuid_t const *p_uuid, + ble_gattc_handle_range_t const *p_handle_range)); + +/**@brief Initiate or continue a GATT Read (Long) Characteristic or Descriptor procedure. + * + * @details This function initiates or resumes a GATT Read (Long) Characteristic or Descriptor procedure. If the Characteristic or + * Descriptor to be read is longer than ATT_MTU - 1, this function must be called multiple times with appropriate offset to read + * the complete value. + * + * @events + * @event{@ref BLE_GATTC_EVT_READ_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_VALUE_READ_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] handle The handle of the attribute to be read. + * @param[in] offset Offset into the attribute value to be read. + * + * @retval ::NRF_SUCCESS Successfully started or resumed the Read (Long) procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without + * reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_READ, uint32_t, sd_ble_gattc_read(uint16_t conn_handle, uint16_t handle, uint16_t offset)); + +/**@brief Initiate a GATT Read Multiple Characteristic Values procedure. + * + * @details This function initiates a GATT Read Multiple Characteristic Values procedure. + * + * @events + * @event{@ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_READ_MULT_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_handles A pointer to the handle(s) of the attribute(s) to be read. + * @param[in] handle_count The number of handles in p_handles. + * + * @retval ::NRF_SUCCESS Successfully started the Read Multiple Characteristic Values procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without + * reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_CHAR_VALUES_READ, uint32_t, + sd_ble_gattc_char_values_read(uint16_t conn_handle, uint16_t const *p_handles, uint16_t handle_count)); + +/**@brief Perform a Write (Characteristic Value or Descriptor, with or without response, signed or not, long or reliable) + * procedure. + * + * @details This function can perform all write procedures described in GATT. + * + * @note Only one write with response procedure can be ongoing per connection at a time. + * If the application tries to write with response while another write with response procedure is ongoing, + * the function call will return @ref NRF_ERROR_BUSY. + * A @ref BLE_GATTC_EVT_WRITE_RSP event will be issued as soon as the write response arrives from the peer. + * + * @note The number of Write without Response that can be queued is configured by @ref + * ble_gattc_conn_cfg_t::write_cmd_tx_queue_size When the queue is full, the function call will return @ref NRF_ERROR_RESOURCES. + * A @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event will be issued as soon as the transmission of the write without + * response is complete. + * + * @note The application can keep track of the available queue element count for writes without responses by following the + * procedure below: + * - Store initial queue element count in a variable. + * - Decrement the variable, which stores the currently available queue element count, by one when a call to this + * function returns @ref NRF_SUCCESS. + * - Increment the variable, which stores the current available queue element count, by the count variable in @ref + * BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event. + * + * @events + * @event{@ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE, Write without response transmission complete.} + * @event{@ref BLE_GATTC_EVT_WRITE_RSP, Write response received from the peer.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_VALUE_WRITE_WITHOUT_RESP_MSC} + * @mmsc{@ref BLE_GATTC_VALUE_WRITE_MSC} + * @mmsc{@ref BLE_GATTC_VALUE_LONG_WRITE_MSC} + * @mmsc{@ref BLE_GATTC_VALUE_RELIABLE_WRITE_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_write_params A pointer to a write parameters structure. + * + * @retval ::NRF_SUCCESS Successfully started the Write procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. + * @retval ::NRF_ERROR_BUSY For write with response, procedure already in progress. Wait for a @ref BLE_GATTC_EVT_WRITE_RSP event + * and retry. + * @retval ::NRF_ERROR_RESOURCES Too many writes without responses queued. + * Wait for a @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event and retry. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without + * reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_WRITE, uint32_t, sd_ble_gattc_write(uint16_t conn_handle, ble_gattc_write_params_t const *p_write_params)); + +/**@brief Send a Handle Value Confirmation to the GATT Server. + * + * @mscs + * @mmsc{@ref BLE_GATTC_HVI_MSC} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] handle The handle of the attribute in the indication. + * + * @retval ::NRF_SUCCESS Successfully queued the Handle Value Confirmation for transmission. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no Indication pending to be confirmed. + * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without + * reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_HV_CONFIRM, uint32_t, sd_ble_gattc_hv_confirm(uint16_t conn_handle, uint16_t handle)); + +/**@brief Discovers information about a range of attributes on a GATT server. + * + * @events + * @event{@ref BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, Generated when information about a range of attributes has been received.} + * @endevents + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_handle_range The range of handles to request information about. + * + * @retval ::NRF_SUCCESS Successfully started an attribute information discovery procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid connection state + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without + * reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_ATTR_INFO_DISCOVER, uint32_t, + sd_ble_gattc_attr_info_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range)); + +/**@brief Start an ATT_MTU exchange by sending an Exchange MTU Request to the server. + * + * @details The SoftDevice sets ATT_MTU to the minimum of: + * - The Client RX MTU value, and + * - The Server RX MTU value from @ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP. + * + * However, the SoftDevice never sets ATT_MTU lower than @ref BLE_GATT_ATT_MTU_DEFAULT. + * + * @events + * @event{@ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_MTU_EXCHANGE} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] client_rx_mtu Client RX MTU size. + * - The minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT. + * - The maximum value is @ref ble_gatt_conn_cfg_t::att_mtu in the connection configuration + used for this connection. + * - The value must be equal to Server RX MTU size given in @ref sd_ble_gatts_exchange_mtu_reply + * if an ATT_MTU exchange has already been performed in the other direction. + * + * @retval ::NRF_SUCCESS Successfully sent request to the server. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid connection state or an ATT_MTU exchange was already requested once. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid Client RX MTU size supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without + reestablishing the connection. + */ +SVCALL(SD_BLE_GATTC_EXCHANGE_MTU_REQUEST, uint32_t, + sd_ble_gattc_exchange_mtu_request(uint16_t conn_handle, uint16_t client_rx_mtu)); + +/**@brief Iterate through Handle-Value(s) list in @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP event. + * + * @param[in] p_gattc_evt Pointer to event buffer containing @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP event. + * @note If the buffer contains different event, behavior is undefined. + * @param[in,out] p_iter Iterator, points to @ref ble_gattc_handle_value_t structure that will be filled in with + * the next Handle-Value pair in each iteration. If the function returns other than + * @ref NRF_SUCCESS, it will not be changed. + * - To start iteration, initialize the structure to zero. + * - To continue, pass the value from previous iteration. + * + * \code + * ble_gattc_handle_value_t iter; + * memset(&iter, 0, sizeof(ble_gattc_handle_value_t)); + * while (sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(&ble_evt.evt.gattc_evt, &iter) == NRF_SUCCESS) + * { + * app_handle = iter.handle; + * memcpy(app_value, iter.p_value, ble_evt.evt.gattc_evt.params.char_val_by_uuid_read_rsp.value_len); + * } + * \endcode + * + * @retval ::NRF_SUCCESS Successfully retrieved the next Handle-Value pair. + * @retval ::NRF_ERROR_NOT_FOUND No more Handle-Value pairs available in the list. + */ +__STATIC_INLINE uint32_t sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(ble_gattc_evt_t *p_gattc_evt, + ble_gattc_handle_value_t *p_iter); + +/** @} */ + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE uint32_t sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(ble_gattc_evt_t *p_gattc_evt, + ble_gattc_handle_value_t *p_iter) +{ + uint32_t value_len = p_gattc_evt->params.char_val_by_uuid_read_rsp.value_len; + uint8_t *p_first = p_gattc_evt->params.char_val_by_uuid_read_rsp.handle_value; + uint8_t *p_next = p_iter->p_value ? p_iter->p_value + value_len : p_first; + + if ((p_next - p_first) / (sizeof(uint16_t) + value_len) < p_gattc_evt->params.char_val_by_uuid_read_rsp.count) { + p_iter->handle = (uint16_t)p_next[1] << 8 | p_next[0]; + p_iter->p_value = p_next + sizeof(uint16_t); + return NRF_SUCCESS; + } else { + return NRF_ERROR_NOT_FOUND; + } +} + +#endif /* SUPPRESS_INLINE_IMPLEMENTATION */ + +#ifdef __cplusplus +} +#endif +#endif /* BLE_GATTC_H__ */ + +/** + @} +*/ diff --git a/variants/xiao_ble/softdevice/ble_gatts.h b/variants/xiao_ble/softdevice/ble_gatts.h new file mode 100644 index 000000000..dc94957cd --- /dev/null +++ b/variants/xiao_ble/softdevice/ble_gatts.h @@ -0,0 +1,904 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + @addtogroup BLE_GATTS Generic Attribute Profile (GATT) Server + @{ + @brief Definitions and prototypes for the GATTS interface. + */ + +#ifndef BLE_GATTS_H__ +#define BLE_GATTS_H__ + +#include "ble_err.h" +#include "ble_gap.h" +#include "ble_gatt.h" +#include "ble_hci.h" +#include "ble_ranges.h" +#include "ble_types.h" +#include "nrf_error.h" +#include "nrf_svc.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup BLE_GATTS_ENUMERATIONS Enumerations + * @{ */ + +/** + * @brief GATTS API SVC numbers. + */ +enum BLE_GATTS_SVCS { + SD_BLE_GATTS_SERVICE_ADD = BLE_GATTS_SVC_BASE, /**< Add a service. */ + SD_BLE_GATTS_INCLUDE_ADD, /**< Add an included service. */ + SD_BLE_GATTS_CHARACTERISTIC_ADD, /**< Add a characteristic. */ + SD_BLE_GATTS_DESCRIPTOR_ADD, /**< Add a generic attribute. */ + SD_BLE_GATTS_VALUE_SET, /**< Set an attribute value. */ + SD_BLE_GATTS_VALUE_GET, /**< Get an attribute value. */ + SD_BLE_GATTS_HVX, /**< Handle Value Notification or Indication. */ + SD_BLE_GATTS_SERVICE_CHANGED, /**< Perform a Service Changed Indication to one or more peers. */ + SD_BLE_GATTS_RW_AUTHORIZE_REPLY, /**< Reply to an authorization request for a read or write operation on one or more + attributes. */ + SD_BLE_GATTS_SYS_ATTR_SET, /**< Set the persistent system attributes for a connection. */ + SD_BLE_GATTS_SYS_ATTR_GET, /**< Retrieve the persistent system attributes. */ + SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, /**< Retrieve the first valid user handle. */ + SD_BLE_GATTS_ATTR_GET, /**< Retrieve the UUID and/or metadata of an attribute. */ + SD_BLE_GATTS_EXCHANGE_MTU_REPLY /**< Reply to Exchange MTU Request. */ +}; + +/** + * @brief GATT Server Event IDs. + */ +enum BLE_GATTS_EVTS { + BLE_GATTS_EVT_WRITE = BLE_GATTS_EVT_BASE, /**< Write operation performed. \n See + @ref ble_gatts_evt_write_t. */ + BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST, /**< Read/Write Authorization request. \n Reply with + @ref sd_ble_gatts_rw_authorize_reply. \n See @ref ble_gatts_evt_rw_authorize_request_t. + */ + BLE_GATTS_EVT_SYS_ATTR_MISSING, /**< A persistent system attribute access is pending. \n Respond with @ref + sd_ble_gatts_sys_attr_set. \n See @ref ble_gatts_evt_sys_attr_missing_t. */ + BLE_GATTS_EVT_HVC, /**< Handle Value Confirmation. \n See @ref ble_gatts_evt_hvc_t. + */ + BLE_GATTS_EVT_SC_CONFIRM, /**< Service Changed Confirmation. \n No additional event + structure applies. */ + BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST, /**< Exchange MTU Request. \n Reply with + @ref sd_ble_gatts_exchange_mtu_reply. \n See @ref ble_gatts_evt_exchange_mtu_request_t. + */ + BLE_GATTS_EVT_TIMEOUT, /**< Peer failed to respond to an ATT request in time. \n See @ref + ble_gatts_evt_timeout_t. */ + BLE_GATTS_EVT_HVN_TX_COMPLETE /**< Handle Value Notification transmission complete. \n See @ref + ble_gatts_evt_hvn_tx_complete_t. */ +}; + +/**@brief GATTS Configuration IDs. + * + * IDs that uniquely identify a GATTS configuration. + */ +enum BLE_GATTS_CFGS { + BLE_GATTS_CFG_SERVICE_CHANGED = BLE_GATTS_CFG_BASE, /**< Service changed configuration. */ + BLE_GATTS_CFG_ATTR_TAB_SIZE, /**< Attribute table size configuration. */ + BLE_GATTS_CFG_SERVICE_CHANGED_CCCD_PERM, /**< Service changed CCCD permission configuration. */ +}; + +/** @} */ + +/** @addtogroup BLE_GATTS_DEFINES Defines + * @{ */ + +/** @defgroup BLE_ERRORS_GATTS SVC return values specific to GATTS + * @{ */ +#define BLE_ERROR_GATTS_INVALID_ATTR_TYPE (NRF_GATTS_ERR_BASE + 0x000) /**< Invalid attribute type. */ +#define BLE_ERROR_GATTS_SYS_ATTR_MISSING (NRF_GATTS_ERR_BASE + 0x001) /**< System Attributes missing. */ +/** @} */ + +/** @defgroup BLE_GATTS_ATTR_LENS_MAX Maximum attribute lengths + * @{ */ +#define BLE_GATTS_FIX_ATTR_LEN_MAX (510) /**< Maximum length for fixed length Attribute Values. */ +#define BLE_GATTS_VAR_ATTR_LEN_MAX (512) /**< Maximum length for variable length Attribute Values. */ +/** @} */ + +/** @defgroup BLE_GATTS_SRVC_TYPES GATT Server Service Types + * @{ */ +#define BLE_GATTS_SRVC_TYPE_INVALID 0x00 /**< Invalid Service Type. */ +#define BLE_GATTS_SRVC_TYPE_PRIMARY 0x01 /**< Primary Service. */ +#define BLE_GATTS_SRVC_TYPE_SECONDARY 0x02 /**< Secondary Type. */ +/** @} */ + +/** @defgroup BLE_GATTS_ATTR_TYPES GATT Server Attribute Types + * @{ */ +#define BLE_GATTS_ATTR_TYPE_INVALID 0x00 /**< Invalid Attribute Type. */ +#define BLE_GATTS_ATTR_TYPE_PRIM_SRVC_DECL 0x01 /**< Primary Service Declaration. */ +#define BLE_GATTS_ATTR_TYPE_SEC_SRVC_DECL 0x02 /**< Secondary Service Declaration. */ +#define BLE_GATTS_ATTR_TYPE_INC_DECL 0x03 /**< Include Declaration. */ +#define BLE_GATTS_ATTR_TYPE_CHAR_DECL 0x04 /**< Characteristic Declaration. */ +#define BLE_GATTS_ATTR_TYPE_CHAR_VAL 0x05 /**< Characteristic Value. */ +#define BLE_GATTS_ATTR_TYPE_DESC 0x06 /**< Descriptor. */ +#define BLE_GATTS_ATTR_TYPE_OTHER 0x07 /**< Other, non-GATT specific type. */ +/** @} */ + +/** @defgroup BLE_GATTS_OPS GATT Server Operations + * @{ */ +#define BLE_GATTS_OP_INVALID 0x00 /**< Invalid Operation. */ +#define BLE_GATTS_OP_WRITE_REQ 0x01 /**< Write Request. */ +#define BLE_GATTS_OP_WRITE_CMD 0x02 /**< Write Command. */ +#define BLE_GATTS_OP_SIGN_WRITE_CMD 0x03 /**< Signed Write Command. */ +#define BLE_GATTS_OP_PREP_WRITE_REQ 0x04 /**< Prepare Write Request. */ +#define BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL 0x05 /**< Execute Write Request: Cancel all prepared writes. */ +#define BLE_GATTS_OP_EXEC_WRITE_REQ_NOW 0x06 /**< Execute Write Request: Immediately execute all prepared writes. */ +/** @} */ + +/** @defgroup BLE_GATTS_VLOCS GATT Value Locations + * @{ */ +#define BLE_GATTS_VLOC_INVALID 0x00 /**< Invalid Location. */ +#define BLE_GATTS_VLOC_STACK 0x01 /**< Attribute Value is located in stack memory, no user memory is required. */ +#define BLE_GATTS_VLOC_USER \ + 0x02 /**< Attribute Value is located in user memory. This requires the user to maintain a valid buffer through the lifetime \ + of the attribute, since the stack will read and write directly to the memory using the pointer provided in the APIs. \ + There are no alignment requirements for the buffer. */ +/** @} */ + +/** @defgroup BLE_GATTS_AUTHORIZE_TYPES GATT Server Authorization Types + * @{ */ +#define BLE_GATTS_AUTHORIZE_TYPE_INVALID 0x00 /**< Invalid Type. */ +#define BLE_GATTS_AUTHORIZE_TYPE_READ 0x01 /**< Authorize a Read Operation. */ +#define BLE_GATTS_AUTHORIZE_TYPE_WRITE 0x02 /**< Authorize a Write Request Operation. */ +/** @} */ + +/** @defgroup BLE_GATTS_SYS_ATTR_FLAGS System Attribute Flags + * @{ */ +#define BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS (1 << 0) /**< Restrict system attributes to system services only. */ +#define BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS (1 << 1) /**< Restrict system attributes to user services only. */ +/** @} */ + +/** @defgroup BLE_GATTS_SERVICE_CHANGED Service Changed Inclusion Values + * @{ + */ +#define BLE_GATTS_SERVICE_CHANGED_DEFAULT \ + (1) /**< Default is to include the Service Changed characteristic in the Attribute Table. */ +/** @} */ + +/** @defgroup BLE_GATTS_ATTR_TAB_SIZE Attribute Table size + * @{ + */ +#define BLE_GATTS_ATTR_TAB_SIZE_MIN (248) /**< Minimum Attribute Table size */ +#define BLE_GATTS_ATTR_TAB_SIZE_DEFAULT (1408) /**< Default Attribute Table size. */ +/** @} */ + +/** @defgroup BLE_GATTS_DEFAULTS GATT Server defaults + * @{ + */ +#define BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT \ + 1 /**< Default number of Handle Value Notifications that can be queued for transmission. */ +/** @} */ + +/** @} */ + +/** @addtogroup BLE_GATTS_STRUCTURES Structures + * @{ */ + +/** + * @brief BLE GATTS connection configuration parameters, set with @ref sd_ble_cfg_set. + */ +typedef struct { + uint8_t hvn_tx_queue_size; /**< Minimum guaranteed number of Handle Value Notifications that can be queued for transmission. + The default value is @ref BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT */ +} ble_gatts_conn_cfg_t; + +/**@brief Attribute metadata. */ +typedef struct { + ble_gap_conn_sec_mode_t read_perm; /**< Read permissions. */ + ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */ + uint8_t vlen : 1; /**< Variable length attribute. */ + uint8_t vloc : 2; /**< Value location, see @ref BLE_GATTS_VLOCS.*/ + uint8_t rd_auth : 1; /**< Read authorization and value will be requested from the application on every read operation. */ + uint8_t wr_auth : 1; /**< Write authorization will be requested from the application on every Write Request operation (but not + Write Command). */ +} ble_gatts_attr_md_t; + +/**@brief GATT Attribute. */ +typedef struct { + ble_uuid_t const *p_uuid; /**< Pointer to the attribute UUID. */ + ble_gatts_attr_md_t const *p_attr_md; /**< Pointer to the attribute metadata structure. */ + uint16_t init_len; /**< Initial attribute value length in bytes. */ + uint16_t init_offs; /**< Initial attribute value offset in bytes. If different from zero, the first init_offs bytes of the + attribute value will be left uninitialized. */ + uint16_t max_len; /**< Maximum attribute value length in bytes, see @ref BLE_GATTS_ATTR_LENS_MAX for maximum values. */ + uint8_t *p_value; /**< Pointer to the attribute data. Please note that if the @ref BLE_GATTS_VLOC_USER value location is + selected in the attribute metadata, this will have to point to a buffer that remains valid through the + lifetime of the attribute. This excludes usage of automatic variables that may go out of scope or any + other temporary location. The stack may access that memory directly without the application's + knowledge. For writable characteristics, this value must not be a location in flash memory.*/ +} ble_gatts_attr_t; + +/**@brief GATT Attribute Value. */ +typedef struct { + uint16_t len; /**< Length in bytes to be written or read. Length in bytes written or read after successful return.*/ + uint16_t offset; /**< Attribute value offset. */ + uint8_t *p_value; /**< Pointer to where value is stored or will be stored. + If value is stored in user memory, only the attribute length is updated when p_value == NULL. + Set to NULL when reading to obtain the complete length of the attribute value */ +} ble_gatts_value_t; + +/**@brief GATT Characteristic Presentation Format. */ +typedef struct { + uint8_t format; /**< Format of the value, see @ref BLE_GATT_CPF_FORMATS. */ + int8_t exponent; /**< Exponent for integer data types. */ + uint16_t unit; /**< Unit from Bluetooth Assigned Numbers. */ + uint8_t name_space; /**< Namespace from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */ + uint16_t desc; /**< Namespace description from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */ +} ble_gatts_char_pf_t; + +/**@brief GATT Characteristic metadata. */ +typedef struct { + ble_gatt_char_props_t char_props; /**< Characteristic Properties. */ + ble_gatt_char_ext_props_t char_ext_props; /**< Characteristic Extended Properties. */ + uint8_t const * + p_char_user_desc; /**< Pointer to a UTF-8 encoded string (non-NULL terminated), NULL if the descriptor is not required. */ + uint16_t char_user_desc_max_size; /**< The maximum size in bytes of the user description descriptor. */ + uint16_t char_user_desc_size; /**< The size of the user description, must be smaller or equal to char_user_desc_max_size. */ + ble_gatts_char_pf_t const + *p_char_pf; /**< Pointer to a presentation format structure or NULL if the CPF descriptor is not required. */ + ble_gatts_attr_md_t const + *p_user_desc_md; /**< Attribute metadata for the User Description descriptor, or NULL for default values. */ + ble_gatts_attr_md_t const + *p_cccd_md; /**< Attribute metadata for the Client Characteristic Configuration Descriptor, or NULL for default values. */ + ble_gatts_attr_md_t const + *p_sccd_md; /**< Attribute metadata for the Server Characteristic Configuration Descriptor, or NULL for default values. */ +} ble_gatts_char_md_t; + +/**@brief GATT Characteristic Definition Handles. */ +typedef struct { + uint16_t value_handle; /**< Handle to the characteristic value. */ + uint16_t user_desc_handle; /**< Handle to the User Description descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */ + uint16_t cccd_handle; /**< Handle to the Client Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if + not present. */ + uint16_t sccd_handle; /**< Handle to the Server Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if + not present. */ +} ble_gatts_char_handles_t; + +/**@brief GATT HVx parameters. */ +typedef struct { + uint16_t handle; /**< Characteristic Value Handle. */ + uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */ + uint16_t offset; /**< Offset within the attribute value. */ + uint16_t *p_len; /**< Length in bytes to be written, length in bytes written after return. */ + uint8_t const *p_data; /**< Actual data content, use NULL to use the current attribute value. */ +} ble_gatts_hvx_params_t; + +/**@brief GATT Authorization parameters. */ +typedef struct { + uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */ + uint8_t update : 1; /**< If set, data supplied in p_data will be used to update the attribute value. + Please note that for @ref BLE_GATTS_AUTHORIZE_TYPE_WRITE operations this bit must always be set, + as the data to be written needs to be stored and later provided by the application. */ + uint16_t offset; /**< Offset of the attribute value being updated. */ + uint16_t len; /**< Length in bytes of the value in p_data pointer, see @ref BLE_GATTS_ATTR_LENS_MAX. */ + uint8_t const *p_data; /**< Pointer to new value used to update the attribute value. */ +} ble_gatts_authorize_params_t; + +/**@brief GATT Read or Write Authorize Reply parameters. */ +typedef struct { + uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */ + union { + ble_gatts_authorize_params_t read; /**< Read authorization parameters. */ + ble_gatts_authorize_params_t write; /**< Write authorization parameters. */ + } params; /**< Reply Parameters. */ +} ble_gatts_rw_authorize_reply_params_t; + +/**@brief Service Changed Inclusion configuration parameters, set with @ref sd_ble_cfg_set. */ +typedef struct { + uint8_t service_changed : 1; /**< If 1, include the Service Changed characteristic in the Attribute Table. Default is @ref + BLE_GATTS_SERVICE_CHANGED_DEFAULT. */ +} ble_gatts_cfg_service_changed_t; + +/**@brief Service Changed CCCD permission configuration parameters, set with @ref sd_ble_cfg_set. + * + * @note @ref ble_gatts_attr_md_t::vlen is ignored and should be set to 0. + * + * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true: + * - @ref ble_gatts_attr_md_t::write_perm is out of range. + * - @ref ble_gatts_attr_md_t::write_perm is @ref BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS, that is + * not allowed by the Bluetooth Specification. + * - wrong @ref ble_gatts_attr_md_t::read_perm, only @ref BLE_GAP_CONN_SEC_MODE_SET_OPEN is + * allowed by the Bluetooth Specification. + * - wrong @ref ble_gatts_attr_md_t::vloc, only @ref BLE_GATTS_VLOC_STACK is allowed. + * @retval ::NRF_ERROR_NOT_SUPPORTED Security Mode 2 not supported + */ +typedef struct { + ble_gatts_attr_md_t + perm; /**< Permission for Service Changed CCCD. Default is @ref BLE_GAP_CONN_SEC_MODE_SET_OPEN, no authorization. */ +} ble_gatts_cfg_service_changed_cccd_perm_t; + +/**@brief Attribute table size configuration parameters, set with @ref sd_ble_cfg_set. + * + * @retval ::NRF_ERROR_INVALID_LENGTH One or more of the following is true: + * - The specified Attribute Table size is too small. + * The minimum acceptable size is defined by @ref BLE_GATTS_ATTR_TAB_SIZE_MIN. + * - The specified Attribute Table size is not a multiple of 4. + */ +typedef struct { + uint32_t attr_tab_size; /**< Attribute table size. Default is @ref BLE_GATTS_ATTR_TAB_SIZE_DEFAULT, minimum is @ref + BLE_GATTS_ATTR_TAB_SIZE_MIN. */ +} ble_gatts_cfg_attr_tab_size_t; + +/**@brief Config structure for GATTS configurations. */ +typedef union { + ble_gatts_cfg_service_changed_t + service_changed; /**< Include service changed characteristic, cfg_id is @ref BLE_GATTS_CFG_SERVICE_CHANGED. */ + ble_gatts_cfg_service_changed_cccd_perm_t service_changed_cccd_perm; /**< Service changed CCCD permission, cfg_id is @ref + BLE_GATTS_CFG_SERVICE_CHANGED_CCCD_PERM. */ + ble_gatts_cfg_attr_tab_size_t attr_tab_size; /**< Attribute table size, cfg_id is @ref BLE_GATTS_CFG_ATTR_TAB_SIZE. */ +} ble_gatts_cfg_t; + +/**@brief Event structure for @ref BLE_GATTS_EVT_WRITE. */ +typedef struct { + uint16_t handle; /**< Attribute Handle. */ + ble_uuid_t uuid; /**< Attribute UUID. */ + uint8_t op; /**< Type of write operation, see @ref BLE_GATTS_OPS. */ + uint8_t auth_required; /**< Writing operation deferred due to authorization requirement. Application may use @ref + sd_ble_gatts_value_set to finalize the writing operation. */ + uint16_t offset; /**< Offset for the write operation. */ + uint16_t len; /**< Length of the received data. */ + uint8_t data[1]; /**< Received data. @note This is a variable length array. The size of 1 indicated is only a placeholder for + compilation. See @ref sd_ble_evt_get for more information on how to use event structures with variable + length array members. */ +} ble_gatts_evt_write_t; + +/**@brief Event substructure for authorized read requests, see @ref ble_gatts_evt_rw_authorize_request_t. */ +typedef struct { + uint16_t handle; /**< Attribute Handle. */ + ble_uuid_t uuid; /**< Attribute UUID. */ + uint16_t offset; /**< Offset for the read operation. */ +} ble_gatts_evt_read_t; + +/**@brief Event structure for @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST. */ +typedef struct { + uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */ + union { + ble_gatts_evt_read_t read; /**< Attribute Read Parameters. */ + ble_gatts_evt_write_t write; /**< Attribute Write Parameters. */ + } request; /**< Request Parameters. */ +} ble_gatts_evt_rw_authorize_request_t; + +/**@brief Event structure for @ref BLE_GATTS_EVT_SYS_ATTR_MISSING. */ +typedef struct { + uint8_t hint; /**< Hint (currently unused). */ +} ble_gatts_evt_sys_attr_missing_t; + +/**@brief Event structure for @ref BLE_GATTS_EVT_HVC. */ +typedef struct { + uint16_t handle; /**< Attribute Handle. */ +} ble_gatts_evt_hvc_t; + +/**@brief Event structure for @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST. */ +typedef struct { + uint16_t client_rx_mtu; /**< Client RX MTU size. */ +} ble_gatts_evt_exchange_mtu_request_t; + +/**@brief Event structure for @ref BLE_GATTS_EVT_TIMEOUT. */ +typedef struct { + uint8_t src; /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */ +} ble_gatts_evt_timeout_t; + +/**@brief Event structure for @ref BLE_GATTS_EVT_HVN_TX_COMPLETE. */ +typedef struct { + uint8_t count; /**< Number of notification transmissions completed. */ +} ble_gatts_evt_hvn_tx_complete_t; + +/**@brief GATTS event structure. */ +typedef struct { + uint16_t conn_handle; /**< Connection Handle on which the event occurred. */ + union { + ble_gatts_evt_write_t write; /**< Write Event Parameters. */ + ble_gatts_evt_rw_authorize_request_t authorize_request; /**< Read or Write Authorize Request Parameters. */ + ble_gatts_evt_sys_attr_missing_t sys_attr_missing; /**< System attributes missing. */ + ble_gatts_evt_hvc_t hvc; /**< Handle Value Confirmation Event Parameters. */ + ble_gatts_evt_exchange_mtu_request_t exchange_mtu_request; /**< Exchange MTU Request Event Parameters. */ + ble_gatts_evt_timeout_t timeout; /**< Timeout Event. */ + ble_gatts_evt_hvn_tx_complete_t hvn_tx_complete; /**< Handle Value Notification transmission complete Event Parameters. */ + } params; /**< Event Parameters. */ +} ble_gatts_evt_t; + +/** @} */ + +/** @addtogroup BLE_GATTS_FUNCTIONS Functions + * @{ */ + +/**@brief Add a service declaration to the Attribute Table. + * + * @note Secondary Services are only relevant in the context of the entity that references them, it is therefore forbidden to + * add a secondary service declaration that is not referenced by another service later in the Attribute Table. + * + * @mscs + * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} + * @endmscs + * + * @param[in] type Toggles between primary and secondary services, see @ref BLE_GATTS_SRVC_TYPES. + * @param[in] p_uuid Pointer to service UUID. + * @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored. + * + * @retval ::NRF_SUCCESS Successfully added a service declaration. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, Vendor Specific UUIDs need to be present in the table. + * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. + */ +SVCALL(SD_BLE_GATTS_SERVICE_ADD, uint32_t, sd_ble_gatts_service_add(uint8_t type, ble_uuid_t const *p_uuid, uint16_t *p_handle)); + +/**@brief Add an include declaration to the Attribute Table. + * + * @note It is currently only possible to add an include declaration to the last added service (i.e. only sequential population is + * supported at this time). + * + * @note The included service must already be present in the Attribute Table prior to this call. + * + * @mscs + * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} + * @endmscs + * + * @param[in] service_handle Handle of the service where the included service is to be placed, if @ref BLE_GATT_HANDLE_INVALID + * is used, it will be placed sequentially. + * @param[in] inc_srvc_handle Handle of the included service. + * @param[out] p_include_handle Pointer to a 16-bit word where the assigned handle will be stored. + * + * @retval ::NRF_SUCCESS Successfully added an include declaration. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, handle values need to match previously added services. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a service context is required. + * @retval ::NRF_ERROR_NOT_SUPPORTED Feature is not supported, service_handle must be that of the last added service. + * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, self inclusions are not allowed. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. + * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. + */ +SVCALL(SD_BLE_GATTS_INCLUDE_ADD, uint32_t, + sd_ble_gatts_include_add(uint16_t service_handle, uint16_t inc_srvc_handle, uint16_t *p_include_handle)); + +/**@brief Add a characteristic declaration, a characteristic value declaration and optional characteristic descriptor declarations + * to the Attribute Table. + * + * @note It is currently only possible to add a characteristic to the last added service (i.e. only sequential population is + * supported at this time). + * + * @note Several restrictions apply to the parameters, such as matching permissions between the user description descriptor and + * the writable auxiliaries bits, readable (no security) and writable (selectable) CCCDs and SCCDs and valid presentation format + * values. + * + * @note If no metadata is provided for the optional descriptors, their permissions will be derived from the characteristic + * permissions. + * + * @mscs + * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} + * @endmscs + * + * @param[in] service_handle Handle of the service where the characteristic is to be placed, if @ref BLE_GATT_HANDLE_INVALID is + * used, it will be placed sequentially. + * @param[in] p_char_md Characteristic metadata. + * @param[in] p_attr_char_value Pointer to the attribute structure corresponding to the characteristic value. + * @param[out] p_handles Pointer to the structure where the assigned handles will be stored. + * + * @retval ::NRF_SUCCESS Successfully added a characteristic. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, service handle, Vendor Specific UUIDs, lengths, and + * permissions need to adhere to the constraints. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a service context is required. + * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX. + */ +SVCALL(SD_BLE_GATTS_CHARACTERISTIC_ADD, uint32_t, + sd_ble_gatts_characteristic_add(uint16_t service_handle, ble_gatts_char_md_t const *p_char_md, + ble_gatts_attr_t const *p_attr_char_value, ble_gatts_char_handles_t *p_handles)); + +/**@brief Add a descriptor to the Attribute Table. + * + * @note It is currently only possible to add a descriptor to the last added characteristic (i.e. only sequential population is + * supported at this time). + * + * @mscs + * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} + * @endmscs + * + * @param[in] char_handle Handle of the characteristic where the descriptor is to be placed, if @ref BLE_GATT_HANDLE_INVALID is + * used, it will be placed sequentially. + * @param[in] p_attr Pointer to the attribute structure. + * @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored. + * + * @retval ::NRF_SUCCESS Successfully added a descriptor. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, characteristic handle, Vendor Specific UUIDs, lengths, and + * permissions need to adhere to the constraints. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a characteristic context is required. + * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX. + */ +SVCALL(SD_BLE_GATTS_DESCRIPTOR_ADD, uint32_t, + sd_ble_gatts_descriptor_add(uint16_t char_handle, ble_gatts_attr_t const *p_attr, uint16_t *p_handle)); + +/**@brief Set the value of a given attribute. + * + * @note Values other than system attributes can be set at any time, regardless of whether any active connections exist. + * + * @mscs + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. Ignored if the value does not belong to a system attribute. + * @param[in] handle Attribute handle. + * @param[in,out] p_value Attribute value information. + * + * @retval ::NRF_SUCCESS Successfully set the value of the attribute. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. + * @retval ::NRF_ERROR_FORBIDDEN Forbidden handle supplied, certain attributes are not modifiable by the application. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied on a system attribute. + */ +SVCALL(SD_BLE_GATTS_VALUE_SET, uint32_t, + sd_ble_gatts_value_set(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value)); + +/**@brief Get the value of a given attribute. + * + * @note If the attribute value is longer than the size of the supplied buffer, + * @ref ble_gatts_value_t::len will return the total attribute value length (excluding offset), + * and not the number of bytes actually returned in @ref ble_gatts_value_t::p_value. + * The application may use this information to allocate a suitable buffer size. + * + * @note When retrieving system attribute values with this function, the connection handle + * may refer to an already disconnected connection. Refer to the documentation of + * @ref sd_ble_gatts_sys_attr_get for further information. + * + * @param[in] conn_handle Connection handle. Ignored if the value does not belong to a system attribute. + * @param[in] handle Attribute handle. + * @param[in,out] p_value Attribute value information. + * + * @retval ::NRF_SUCCESS Successfully retrieved the value of the attribute. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid attribute offset supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied on a system attribute. + * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known + * value. + */ +SVCALL(SD_BLE_GATTS_VALUE_GET, uint32_t, + sd_ble_gatts_value_get(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value)); + +/**@brief Notify or Indicate an attribute value. + * + * @details This function checks for the relevant Client Characteristic Configuration descriptor value to verify that the relevant + * operation (notification or indication) has been enabled by the client. It is also able to update the attribute value before + * issuing the PDU, so that the application can atomically perform a value update and a server initiated transaction with a single + * API call. + * + * @note The local attribute value may be updated even if an outgoing packet is not sent to the peer due to an error during + * execution. The Attribute Table has been updated if one of the following error codes is returned: @ref NRF_ERROR_INVALID_STATE, + * @ref NRF_ERROR_BUSY, + * @ref NRF_ERROR_FORBIDDEN, @ref BLE_ERROR_GATTS_SYS_ATTR_MISSING and @ref NRF_ERROR_RESOURCES. + * The caller can check whether the value has been updated by looking at the contents of *(@ref + * ble_gatts_hvx_params_t::p_len). + * + * @note Only one indication procedure can be ongoing per connection at a time. + * If the application tries to indicate an attribute value while another indication procedure is ongoing, + * the function call will return @ref NRF_ERROR_BUSY. + * A @ref BLE_GATTS_EVT_HVC event will be issued as soon as the confirmation arrives from the peer. + * + * @note The number of Handle Value Notifications that can be queued is configured by @ref + * ble_gatts_conn_cfg_t::hvn_tx_queue_size When the queue is full, the function call will return @ref NRF_ERROR_RESOURCES. A @ref + * BLE_GATTS_EVT_HVN_TX_COMPLETE event will be issued as soon as the transmission of the notification is complete. + * + * @note The application can keep track of the available queue element count for notifications by following the procedure + * below: + * - Store initial queue element count in a variable. + * - Decrement the variable, which stores the currently available queue element count, by one when a call to this + * function returns @ref NRF_SUCCESS. + * - Increment the variable, which stores the current available queue element count, by the count variable in @ref + * BLE_GATTS_EVT_HVN_TX_COMPLETE event. + * + * @events + * @event{@ref BLE_GATTS_EVT_HVN_TX_COMPLETE, Notification transmission complete.} + * @event{@ref BLE_GATTS_EVT_HVC, Confirmation received from the peer.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTS_HVX_SYS_ATTRS_MISSING_MSC} + * @mmsc{@ref BLE_GATTS_HVN_MSC} + * @mmsc{@ref BLE_GATTS_HVI_MSC} + * @mmsc{@ref BLE_GATTS_HVX_DISABLED_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in,out] p_hvx_params Pointer to an HVx parameters structure. If @ref ble_gatts_hvx_params_t::p_data + * contains a non-NULL pointer the attribute value will be updated with the contents + * pointed by it before sending the notification or indication. If the attribute value + * is updated, @ref ble_gatts_hvx_params_t::p_len is updated by the SoftDevice to + * contain the number of actual bytes written, else it will be set to 0. + * + * @retval ::NRF_SUCCESS Successfully queued a notification or indication for transmission, and optionally updated the attribute + * value. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE One or more of the following is true: + * - Invalid Connection State + * - Notifications and/or indications not enabled in the CCCD + * - An ATT_MTU exchange is ongoing + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied. Only attributes added directly by the application + * are available to notify and indicate. + * @retval ::BLE_ERROR_GATTS_INVALID_ATTR_TYPE Invalid attribute type(s) supplied, only characteristic values may be notified and + * indicated. + * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. + * @retval ::NRF_ERROR_FORBIDDEN The connection's current security level is lower than the one required by the write permissions + * of the CCCD associated with this characteristic. + * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. + * @retval ::NRF_ERROR_BUSY For @ref BLE_GATT_HVX_INDICATION Procedure already in progress. Wait for a @ref BLE_GATTS_EVT_HVC + * event and retry. + * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known + * value. + * @retval ::NRF_ERROR_RESOURCES Too many notifications queued. + * Wait for a @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event and retry. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without + * reestablishing the connection. + */ +SVCALL(SD_BLE_GATTS_HVX, uint32_t, sd_ble_gatts_hvx(uint16_t conn_handle, ble_gatts_hvx_params_t const *p_hvx_params)); + +/**@brief Indicate the Service Changed attribute value. + * + * @details This call will send a Handle Value Indication to one or more peers connected to inform them that the Attribute + * Table layout has changed. As soon as the peer has confirmed the indication, a @ref BLE_GATTS_EVT_SC_CONFIRM event will + * be issued. + * + * @note Some of the restrictions and limitations that apply to @ref sd_ble_gatts_hvx also apply here. + * + * @events + * @event{@ref BLE_GATTS_EVT_SC_CONFIRM, Confirmation of attribute table change received from peer.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTS_SC_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] start_handle Start of affected attribute handle range. + * @param[in] end_handle End of affected attribute handle range. + * + * @retval ::NRF_SUCCESS Successfully queued the Service Changed indication for transmission. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_NOT_SUPPORTED Service Changed not enabled at initialization. See @ref + * sd_ble_cfg_set and @ref ble_gatts_cfg_service_changed_t. + * @retval ::NRF_ERROR_INVALID_STATE One or more of the following is true: + * - Invalid Connection State + * - Notifications and/or indications not enabled in the CCCD + * - An ATT_MTU exchange is ongoing + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied, handles must be in the range populated by the + * application. + * @retval ::NRF_ERROR_BUSY Procedure already in progress. + * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known + * value. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without + * reestablishing the connection. + */ +SVCALL(SD_BLE_GATTS_SERVICE_CHANGED, uint32_t, + sd_ble_gatts_service_changed(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle)); + +/**@brief Respond to a Read/Write authorization request. + * + * @note This call should only be used as a response to a @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event issued to the application. + * + * @mscs + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC} + * @mmsc{@ref BLE_GATTS_READ_REQ_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_WRITE_REQ_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_PEER_CANCEL_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_rw_authorize_reply_params Pointer to a structure with the attribute provided by the application. + * + * @note @ref ble_gatts_authorize_params_t::p_data is ignored when this function is used to respond + * to a @ref BLE_GATTS_AUTHORIZE_TYPE_READ event if @ref ble_gatts_authorize_params_t::update + * is set to 0. + * + * @retval ::NRF_SUCCESS Successfully queued a response to the peer, and in the case of a write operation, Attribute + * Table updated. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no authorization request pending. + * @retval ::NRF_ERROR_INVALID_PARAM Authorization op invalid, + * handle supplied does not match requested handle, + * or invalid data to be written provided by the application. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without + * reestablishing the connection. + */ +SVCALL(SD_BLE_GATTS_RW_AUTHORIZE_REPLY, uint32_t, + sd_ble_gatts_rw_authorize_reply(uint16_t conn_handle, + ble_gatts_rw_authorize_reply_params_t const *p_rw_authorize_reply_params)); + +/**@brief Update persistent system attribute information. + * + * @details Supply information about persistent system attributes to the stack, + * previously obtained using @ref sd_ble_gatts_sys_attr_get. + * This call is only allowed for active connections, and is usually + * made immediately after a connection is established with an known bonded device, + * often as a response to a @ref BLE_GATTS_EVT_SYS_ATTR_MISSING. + * + * p_sysattrs may point directly to the application's stored copy of the system attributes + * obtained using @ref sd_ble_gatts_sys_attr_get. + * If the pointer is NULL, the system attribute info is initialized, assuming that + * the application does not have any previously saved system attribute data for this device. + * + * @note The state of persistent system attributes is reset upon connection establishment and then remembered for its duration. + * + * @note If this call returns with an error code different from @ref NRF_SUCCESS, the storage of persistent system attributes may + * have been completed only partially. This means that the state of the attribute table is undefined, and the application should + * either provide a new set of attributes using this same call or reset the SoftDevice to return to a known state. + * + * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system + * services will be modified. + * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user + * services will be modified. + * + * @mscs + * @mmsc{@ref BLE_GATTS_HVX_SYS_ATTRS_MISSING_MSC} + * @mmsc{@ref BLE_GATTS_SYS_ATTRS_UNK_PEER_MSC} + * @mmsc{@ref BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_sys_attr_data Pointer to a saved copy of system attributes supplied to the stack, or NULL. + * @param[in] len Size of data pointed by p_sys_attr_data, in octets. + * @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS + * + * @retval ::NRF_SUCCESS Successfully set the system attribute information. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid flags supplied. + * @retval ::NRF_ERROR_INVALID_DATA Invalid data supplied, the data should be exactly the same as retrieved with @ref + * sd_ble_gatts_sys_attr_get. + * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. + */ +SVCALL(SD_BLE_GATTS_SYS_ATTR_SET, uint32_t, + sd_ble_gatts_sys_attr_set(uint16_t conn_handle, uint8_t const *p_sys_attr_data, uint16_t len, uint32_t flags)); + +/**@brief Retrieve persistent system attribute information from the stack. + * + * @details This call is used to retrieve information about values to be stored persistently by the application + * during the lifetime of a connection or after it has been terminated. When a new connection is established with the + * same bonded device, the system attribute information retrieved with this function should be restored using using @ref + * sd_ble_gatts_sys_attr_set. If retrieved after disconnection, the data should be read before a new connection established. The + * connection handle for the previous, now disconnected, connection will remain valid until a new one is created to allow this API + * call to refer to it. Connection handles belonging to active connections can be used as well, but care should be taken since the + * system attributes may be written to at any time by the peer during a connection's lifetime. + * + * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system + * services will be returned. + * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user + * services will be returned. + * + * @mscs + * @mmsc{@ref BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle of the recently terminated connection. + * @param[out] p_sys_attr_data Pointer to a buffer where updated information about system attributes will be filled in. The + * format of the data is described in @ref BLE_GATTS_SYS_ATTRS_FORMAT. NULL can be provided to obtain the length of the data. + * @param[in,out] p_len Size of application buffer if p_sys_attr_data is not NULL. Unconditionally updated to actual + * length of system attribute data. + * @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS + * + * @retval ::NRF_SUCCESS Successfully retrieved the system attribute information. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid flags supplied. + * @retval ::NRF_ERROR_DATA_SIZE The system attribute information did not fit into the provided buffer. + * @retval ::NRF_ERROR_NOT_FOUND No system attributes found. + */ +SVCALL(SD_BLE_GATTS_SYS_ATTR_GET, uint32_t, + sd_ble_gatts_sys_attr_get(uint16_t conn_handle, uint8_t *p_sys_attr_data, uint16_t *p_len, uint32_t flags)); + +/**@brief Retrieve the first valid user attribute handle. + * + * @param[out] p_handle Pointer to an integer where the handle will be stored. + * + * @retval ::NRF_SUCCESS Successfully retrieved the handle. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + */ +SVCALL(SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, uint32_t, sd_ble_gatts_initial_user_handle_get(uint16_t *p_handle)); + +/**@brief Retrieve the attribute UUID and/or metadata. + * + * @param[in] handle Attribute handle + * @param[out] p_uuid UUID of the attribute. Use NULL to omit this field. + * @param[out] p_md Metadata of the attribute. Use NULL to omit this field. + * + * @retval ::NRF_SUCCESS Successfully retrieved the attribute metadata, + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameters supplied. Returned when both @c p_uuid and @c p_md are NULL. + * @retval ::NRF_ERROR_NOT_FOUND Attribute was not found. + */ +SVCALL(SD_BLE_GATTS_ATTR_GET, uint32_t, sd_ble_gatts_attr_get(uint16_t handle, ble_uuid_t *p_uuid, ble_gatts_attr_md_t *p_md)); + +/**@brief Reply to an ATT_MTU exchange request by sending an Exchange MTU Response to the client. + * + * @details This function is only used to reply to a @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST event. + * + * @details The SoftDevice sets ATT_MTU to the minimum of: + * - The Client RX MTU value from @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST, and + * - The Server RX MTU value. + * + * However, the SoftDevice never sets ATT_MTU lower than @ref BLE_GATT_ATT_MTU_DEFAULT. + * + * @mscs + * @mmsc{@ref BLE_GATTS_MTU_EXCHANGE} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] server_rx_mtu Server RX MTU size. + * - The minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT. + * - The maximum value is @ref ble_gatt_conn_cfg_t::att_mtu in the connection configuration + * used for this connection. + * - The value must be equal to Client RX MTU size given in @ref sd_ble_gattc_exchange_mtu_request + * if an ATT_MTU exchange has already been performed in the other direction. + * + * @retval ::NRF_SUCCESS Successfully sent response to the client. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no ATT_MTU exchange request pending. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid Server RX MTU size supplied. + * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without + * reestablishing the connection. + */ +SVCALL(SD_BLE_GATTS_EXCHANGE_MTU_REPLY, uint32_t, sd_ble_gatts_exchange_mtu_reply(uint16_t conn_handle, uint16_t server_rx_mtu)); +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // BLE_GATTS_H__ + +/** + @} +*/ diff --git a/variants/xiao_ble/softdevice/ble_hci.h b/variants/xiao_ble/softdevice/ble_hci.h new file mode 100644 index 000000000..27f85d52e --- /dev/null +++ b/variants/xiao_ble/softdevice/ble_hci.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + @addtogroup BLE_COMMON + @{ +*/ + +#ifndef BLE_HCI_H__ +#define BLE_HCI_H__ +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup BLE_HCI_STATUS_CODES Bluetooth status codes + * @{ */ + +#define BLE_HCI_STATUS_CODE_SUCCESS 0x00 /**< Success. */ +#define BLE_HCI_STATUS_CODE_UNKNOWN_BTLE_COMMAND 0x01 /**< Unknown BLE Command. */ +#define BLE_HCI_STATUS_CODE_UNKNOWN_CONNECTION_IDENTIFIER 0x02 /**< Unknown Connection Identifier. */ +/*0x03 Hardware Failure +0x04 Page Timeout +*/ +#define BLE_HCI_AUTHENTICATION_FAILURE 0x05 /**< Authentication Failure. */ +#define BLE_HCI_STATUS_CODE_PIN_OR_KEY_MISSING 0x06 /**< Pin or Key missing. */ +#define BLE_HCI_MEMORY_CAPACITY_EXCEEDED 0x07 /**< Memory Capacity Exceeded. */ +#define BLE_HCI_CONNECTION_TIMEOUT 0x08 /**< Connection Timeout. */ +/*0x09 Connection Limit Exceeded +0x0A Synchronous Connection Limit To A Device Exceeded +0x0B ACL Connection Already Exists*/ +#define BLE_HCI_STATUS_CODE_COMMAND_DISALLOWED 0x0C /**< Command Disallowed. */ +/*0x0D Connection Rejected due to Limited Resources +0x0E Connection Rejected Due To Security Reasons +0x0F Connection Rejected due to Unacceptable BD_ADDR +0x10 Connection Accept Timeout Exceeded +0x11 Unsupported Feature or Parameter Value*/ +#define BLE_HCI_STATUS_CODE_INVALID_BTLE_COMMAND_PARAMETERS 0x12 /**< Invalid BLE Command Parameters. */ +#define BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION 0x13 /**< Remote User Terminated Connection. */ +#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES \ + 0x14 /**< Remote Device Terminated Connection due to low \ + resources.*/ +#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF 0x15 /**< Remote Device Terminated Connection due to power off. */ +#define BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION 0x16 /**< Local Host Terminated Connection. */ +/* +0x17 Repeated Attempts +0x18 Pairing Not Allowed +0x19 Unknown LMP PDU +*/ +#define BLE_HCI_UNSUPPORTED_REMOTE_FEATURE 0x1A /**< Unsupported Remote Feature. */ +/* +0x1B SCO Offset Rejected +0x1C SCO Interval Rejected +0x1D SCO Air Mode Rejected*/ +#define BLE_HCI_STATUS_CODE_INVALID_LMP_PARAMETERS 0x1E /**< Invalid LMP Parameters. */ +#define BLE_HCI_STATUS_CODE_UNSPECIFIED_ERROR 0x1F /**< Unspecified Error. */ +/*0x20 Unsupported LMP Parameter Value +0x21 Role Change Not Allowed +*/ +#define BLE_HCI_STATUS_CODE_LMP_RESPONSE_TIMEOUT 0x22 /**< LMP Response Timeout. */ +#define BLE_HCI_STATUS_CODE_LMP_ERROR_TRANSACTION_COLLISION 0x23 /**< LMP Error Transaction Collision/LL Procedure Collision. */ +#define BLE_HCI_STATUS_CODE_LMP_PDU_NOT_ALLOWED 0x24 /**< LMP PDU Not Allowed. */ +/*0x25 Encryption Mode Not Acceptable +0x26 Link Key Can Not be Changed +0x27 Requested QoS Not Supported +*/ +#define BLE_HCI_INSTANT_PASSED 0x28 /**< Instant Passed. */ +#define BLE_HCI_PAIRING_WITH_UNIT_KEY_UNSUPPORTED 0x29 /**< Pairing with Unit Key Unsupported. */ +#define BLE_HCI_DIFFERENT_TRANSACTION_COLLISION 0x2A /**< Different Transaction Collision. */ +/* +0x2B Reserved +0x2C QoS Unacceptable Parameter +0x2D QoS Rejected +0x2E Channel Classification Not Supported +0x2F Insufficient Security +*/ +#define BLE_HCI_PARAMETER_OUT_OF_MANDATORY_RANGE 0x30 /**< Parameter Out Of Mandatory Range. */ +/* +0x31 Reserved +0x32 Role Switch Pending +0x33 Reserved +0x34 Reserved Slot Violation +0x35 Role Switch Failed +0x36 Extended Inquiry Response Too Large +0x37 Secure Simple Pairing Not Supported By Host. +0x38 Host Busy - Pairing +0x39 Connection Rejected due to No Suitable Channel Found*/ +#define BLE_HCI_CONTROLLER_BUSY 0x3A /**< Controller Busy. */ +#define BLE_HCI_CONN_INTERVAL_UNACCEPTABLE 0x3B /**< Connection Interval Unacceptable. */ +#define BLE_HCI_DIRECTED_ADVERTISER_TIMEOUT 0x3C /**< Directed Advertisement Timeout. */ +#define BLE_HCI_CONN_TERMINATED_DUE_TO_MIC_FAILURE 0x3D /**< Connection Terminated due to MIC Failure. */ +#define BLE_HCI_CONN_FAILED_TO_BE_ESTABLISHED 0x3E /**< Connection Failed to be Established. */ + +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // BLE_HCI_H__ + +/** @} */ diff --git a/variants/xiao_ble/softdevice/ble_l2cap.h b/variants/xiao_ble/softdevice/ble_l2cap.h new file mode 100644 index 000000000..5f4bd277d --- /dev/null +++ b/variants/xiao_ble/softdevice/ble_l2cap.h @@ -0,0 +1,495 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + @addtogroup BLE_L2CAP Logical Link Control and Adaptation Protocol (L2CAP) + @{ + @brief Definitions and prototypes for the L2CAP interface. + */ + +#ifndef BLE_L2CAP_H__ +#define BLE_L2CAP_H__ + +#include "ble_err.h" +#include "ble_ranges.h" +#include "ble_types.h" +#include "nrf_error.h" +#include "nrf_svc.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@addtogroup BLE_L2CAP_TERMINOLOGY Terminology + * @{ + * @details + * + * L2CAP SDU + * - A data unit that the application can send/receive to/from a peer. + * + * L2CAP PDU + * - A data unit that is exchanged between local and remote L2CAP entities. + * It consists of L2CAP protocol control information and payload fields. + * The payload field can contain an L2CAP SDU or a part of an L2CAP SDU. + * + * L2CAP MTU + * - The maximum length of an L2CAP SDU. + * + * L2CAP MPS + * - The maximum length of an L2CAP PDU payload field. + * + * Credits + * - A value indicating the number of L2CAP PDUs that the receiver of the credit can send to the peer. + * @} */ + +/**@addtogroup BLE_L2CAP_ENUMERATIONS Enumerations + * @{ */ + +/**@brief L2CAP API SVC numbers. */ +enum BLE_L2CAP_SVCS { + SD_BLE_L2CAP_CH_SETUP = BLE_L2CAP_SVC_BASE + 0, /**< Set up an L2CAP channel. */ + SD_BLE_L2CAP_CH_RELEASE = BLE_L2CAP_SVC_BASE + 1, /**< Release an L2CAP channel. */ + SD_BLE_L2CAP_CH_RX = BLE_L2CAP_SVC_BASE + 2, /**< Receive an SDU on an L2CAP channel. */ + SD_BLE_L2CAP_CH_TX = BLE_L2CAP_SVC_BASE + 3, /**< Transmit an SDU on an L2CAP channel. */ + SD_BLE_L2CAP_CH_FLOW_CONTROL = BLE_L2CAP_SVC_BASE + 4, /**< Advanced SDU reception flow control. */ +}; + +/**@brief L2CAP Event IDs. */ +enum BLE_L2CAP_EVTS { + BLE_L2CAP_EVT_CH_SETUP_REQUEST = BLE_L2CAP_EVT_BASE + 0, /**< L2CAP Channel Setup Request event. + \n Reply with @ref sd_ble_l2cap_ch_setup. + \n See @ref ble_l2cap_evt_ch_setup_request_t. */ + BLE_L2CAP_EVT_CH_SETUP_REFUSED = BLE_L2CAP_EVT_BASE + 1, /**< L2CAP Channel Setup Refused event. + \n See @ref ble_l2cap_evt_ch_setup_refused_t. */ + BLE_L2CAP_EVT_CH_SETUP = BLE_L2CAP_EVT_BASE + 2, /**< L2CAP Channel Setup Completed event. + \n See @ref ble_l2cap_evt_ch_setup_t. */ + BLE_L2CAP_EVT_CH_RELEASED = BLE_L2CAP_EVT_BASE + 3, /**< L2CAP Channel Released event. + \n No additional event structure applies. */ + BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED = BLE_L2CAP_EVT_BASE + 4, /**< L2CAP Channel SDU data buffer released event. + \n See @ref ble_l2cap_evt_ch_sdu_buf_released_t. */ + BLE_L2CAP_EVT_CH_CREDIT = BLE_L2CAP_EVT_BASE + 5, /**< L2CAP Channel Credit received. + \n See @ref ble_l2cap_evt_ch_credit_t. */ + BLE_L2CAP_EVT_CH_RX = BLE_L2CAP_EVT_BASE + 6, /**< L2CAP Channel SDU received. + \n See @ref ble_l2cap_evt_ch_rx_t. */ + BLE_L2CAP_EVT_CH_TX = BLE_L2CAP_EVT_BASE + 7, /**< L2CAP Channel SDU transmitted. + \n See @ref ble_l2cap_evt_ch_tx_t. */ +}; + +/** @} */ + +/**@addtogroup BLE_L2CAP_DEFINES Defines + * @{ */ + +/**@brief Maximum number of L2CAP channels per connection. */ +#define BLE_L2CAP_CH_COUNT_MAX (64) + +/**@brief Minimum L2CAP MTU, in bytes. */ +#define BLE_L2CAP_MTU_MIN (23) + +/**@brief Minimum L2CAP MPS, in bytes. */ +#define BLE_L2CAP_MPS_MIN (23) + +/**@brief Invalid CID. */ +#define BLE_L2CAP_CID_INVALID (0x0000) + +/**@brief Default number of credits for @ref sd_ble_l2cap_ch_flow_control. */ +#define BLE_L2CAP_CREDITS_DEFAULT (1) + +/**@defgroup BLE_L2CAP_CH_SETUP_REFUSED_SRCS L2CAP channel setup refused sources + * @{ */ +#define BLE_L2CAP_CH_SETUP_REFUSED_SRC_LOCAL (0x01) /**< Local. */ +#define BLE_L2CAP_CH_SETUP_REFUSED_SRC_REMOTE (0x02) /**< Remote. */ + /** @} */ + +/** @defgroup BLE_L2CAP_CH_STATUS_CODES L2CAP channel status codes + * @{ */ +#define BLE_L2CAP_CH_STATUS_CODE_SUCCESS (0x0000) /**< Success. */ +#define BLE_L2CAP_CH_STATUS_CODE_LE_PSM_NOT_SUPPORTED (0x0002) /**< LE_PSM not supported. */ +#define BLE_L2CAP_CH_STATUS_CODE_NO_RESOURCES (0x0004) /**< No resources available. */ +#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_AUTHENTICATION (0x0005) /**< Insufficient authentication. */ +#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_AUTHORIZATION (0x0006) /**< Insufficient authorization. */ +#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_ENC_KEY_SIZE (0x0007) /**< Insufficient encryption key size. */ +#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_ENC (0x0008) /**< Insufficient encryption. */ +#define BLE_L2CAP_CH_STATUS_CODE_INVALID_SCID (0x0009) /**< Invalid Source CID. */ +#define BLE_L2CAP_CH_STATUS_CODE_SCID_ALLOCATED (0x000A) /**< Source CID already allocated. */ +#define BLE_L2CAP_CH_STATUS_CODE_UNACCEPTABLE_PARAMS (0x000B) /**< Unacceptable parameters. */ +#define BLE_L2CAP_CH_STATUS_CODE_NOT_UNDERSTOOD \ + (0x8000) /**< Command Reject received instead of LE Credit Based Connection Response. */ +#define BLE_L2CAP_CH_STATUS_CODE_TIMEOUT (0xC000) /**< Operation timed out. */ +/** @} */ + +/** @} */ + +/**@addtogroup BLE_L2CAP_STRUCTURES Structures + * @{ */ + +/** + * @brief BLE L2CAP connection configuration parameters, set with @ref sd_ble_cfg_set. + * + * @note These parameters are set per connection, so all L2CAP channels created on this connection + * will have the same parameters. + * + * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true: + * - rx_mps is smaller than @ref BLE_L2CAP_MPS_MIN. + * - tx_mps is smaller than @ref BLE_L2CAP_MPS_MIN. + * - ch_count is greater than @ref BLE_L2CAP_CH_COUNT_MAX. + * @retval ::NRF_ERROR_NO_MEM rx_mps or tx_mps is set too high. + */ +typedef struct { + uint16_t rx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP shall + be able to receive on L2CAP channels on connections with this + configuration. The minimum value is @ref BLE_L2CAP_MPS_MIN. */ + uint16_t tx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP shall + be able to transmit on L2CAP channels on connections with this + configuration. The minimum value is @ref BLE_L2CAP_MPS_MIN. */ + uint8_t rx_queue_size; /**< Number of SDU data buffers that can be queued for reception per + L2CAP channel. The minimum value is one. */ + uint8_t tx_queue_size; /**< Number of SDU data buffers that can be queued for transmission + per L2CAP channel. The minimum value is one. */ + uint8_t ch_count; /**< Number of L2CAP channels the application can create per connection + with this configuration. The default value is zero, the maximum + value is @ref BLE_L2CAP_CH_COUNT_MAX. + @note if this parameter is set to zero, all other parameters in + @ref ble_l2cap_conn_cfg_t are ignored. */ +} ble_l2cap_conn_cfg_t; + +/**@brief L2CAP channel RX parameters. */ +typedef struct { + uint16_t rx_mtu; /**< The maximum L2CAP SDU size, in bytes, that L2CAP shall be able to + receive on this L2CAP channel. + - Must be equal to or greater than @ref BLE_L2CAP_MTU_MIN. */ + uint16_t rx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP shall be + able to receive on this L2CAP channel. + - Must be equal to or greater than @ref BLE_L2CAP_MPS_MIN. + - Must be equal to or less than @ref ble_l2cap_conn_cfg_t::rx_mps. */ + ble_data_t sdu_buf; /**< SDU data buffer for reception. + - If @ref ble_data_t::p_data is non-NULL, initial credits are + issued to the peer. + - If @ref ble_data_t::p_data is NULL, no initial credits are + issued to the peer. */ +} ble_l2cap_ch_rx_params_t; + +/**@brief L2CAP channel setup parameters. */ +typedef struct { + ble_l2cap_ch_rx_params_t rx_params; /**< L2CAP channel RX parameters. */ + uint16_t le_psm; /**< LE Protocol/Service Multiplexer. Used when requesting + setup of an L2CAP channel, ignored otherwise. */ + uint16_t status; /**< Status code, see @ref BLE_L2CAP_CH_STATUS_CODES. + Used when replying to a setup request of an L2CAP + channel, ignored otherwise. */ +} ble_l2cap_ch_setup_params_t; + +/**@brief L2CAP channel TX parameters. */ +typedef struct { + uint16_t tx_mtu; /**< The maximum L2CAP SDU size, in bytes, that L2CAP is able to + transmit on this L2CAP channel. */ + uint16_t peer_mps; /**< The maximum L2CAP PDU payload size, in bytes, that the peer is + able to receive on this L2CAP channel. */ + uint16_t tx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP is able + to transmit on this L2CAP channel. This is effective tx_mps, + selected by the SoftDevice as + MIN( @ref ble_l2cap_ch_tx_params_t::peer_mps, @ref ble_l2cap_conn_cfg_t::tx_mps ) */ + uint16_t credits; /**< Initial credits given by the peer. */ +} ble_l2cap_ch_tx_params_t; + +/**@brief L2CAP Channel Setup Request event. */ +typedef struct { + ble_l2cap_ch_tx_params_t tx_params; /**< L2CAP channel TX parameters. */ + uint16_t le_psm; /**< LE Protocol/Service Multiplexer. */ +} ble_l2cap_evt_ch_setup_request_t; + +/**@brief L2CAP Channel Setup Refused event. */ +typedef struct { + uint8_t source; /**< Source, see @ref BLE_L2CAP_CH_SETUP_REFUSED_SRCS */ + uint16_t status; /**< Status code, see @ref BLE_L2CAP_CH_STATUS_CODES */ +} ble_l2cap_evt_ch_setup_refused_t; + +/**@brief L2CAP Channel Setup Completed event. */ +typedef struct { + ble_l2cap_ch_tx_params_t tx_params; /**< L2CAP channel TX parameters. */ +} ble_l2cap_evt_ch_setup_t; + +/**@brief L2CAP Channel SDU Data Buffer Released event. */ +typedef struct { + ble_data_t sdu_buf; /**< Returned reception or transmission SDU data buffer. The SoftDevice + returns SDU data buffers supplied by the application, which have + not yet been returned previously via a @ref BLE_L2CAP_EVT_CH_RX or + @ref BLE_L2CAP_EVT_CH_TX event. */ +} ble_l2cap_evt_ch_sdu_buf_released_t; + +/**@brief L2CAP Channel Credit received event. */ +typedef struct { + uint16_t credits; /**< Additional credits given by the peer. */ +} ble_l2cap_evt_ch_credit_t; + +/**@brief L2CAP Channel received SDU event. */ +typedef struct { + uint16_t sdu_len; /**< Total SDU length, in bytes. */ + ble_data_t sdu_buf; /**< SDU data buffer. + @note If there is not enough space in the buffer + (sdu_buf.len < sdu_len) then the rest of the SDU will be + silently discarded by the SoftDevice. */ +} ble_l2cap_evt_ch_rx_t; + +/**@brief L2CAP Channel transmitted SDU event. */ +typedef struct { + ble_data_t sdu_buf; /**< SDU data buffer. */ +} ble_l2cap_evt_ch_tx_t; + +/**@brief L2CAP event structure. */ +typedef struct { + uint16_t conn_handle; /**< Connection Handle on which the event occured. */ + uint16_t local_cid; /**< Local Channel ID of the L2CAP channel, or + @ref BLE_L2CAP_CID_INVALID if not present. */ + union { + ble_l2cap_evt_ch_setup_request_t ch_setup_request; /**< L2CAP Channel Setup Request Event Parameters. */ + ble_l2cap_evt_ch_setup_refused_t ch_setup_refused; /**< L2CAP Channel Setup Refused Event Parameters. */ + ble_l2cap_evt_ch_setup_t ch_setup; /**< L2CAP Channel Setup Completed Event Parameters. */ + ble_l2cap_evt_ch_sdu_buf_released_t ch_sdu_buf_released; /**< L2CAP Channel SDU Data Buffer Released Event Parameters. */ + ble_l2cap_evt_ch_credit_t credit; /**< L2CAP Channel Credit Received Event Parameters. */ + ble_l2cap_evt_ch_rx_t rx; /**< L2CAP Channel SDU Received Event Parameters. */ + ble_l2cap_evt_ch_tx_t tx; /**< L2CAP Channel SDU Transmitted Event Parameters. */ + } params; /**< Event Parameters. */ +} ble_l2cap_evt_t; + +/** @} */ + +/**@addtogroup BLE_L2CAP_FUNCTIONS Functions + * @{ */ + +/**@brief Set up an L2CAP channel. + * + * @details This function is used to: + * - Request setup of an L2CAP channel: sends an LE Credit Based Connection Request packet to a peer. + * - Reply to a setup request of an L2CAP channel (if called in response to a + * @ref BLE_L2CAP_EVT_CH_SETUP_REQUEST event): sends an LE Credit Based Connection + * Response packet to a peer. + * + * @note A call to this function will require the application to keep the SDU data buffer alive + * until the SDU data buffer is returned in @ref BLE_L2CAP_EVT_CH_RX or + * @ref BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED event. + * + * @events + * @event{@ref BLE_L2CAP_EVT_CH_SETUP, Setup successful.} + * @event{@ref BLE_L2CAP_EVT_CH_SETUP_REFUSED, Setup failed.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_L2CAP_CH_SETUP_MSC} + * @endmscs + * + * @param[in] conn_handle Connection Handle. + * @param[in,out] p_local_cid Pointer to a uint16_t containing Local Channel ID of the L2CAP channel: + * - As input: @ref BLE_L2CAP_CID_INVALID when requesting setup of an L2CAP + * channel or local_cid provided in the @ref BLE_L2CAP_EVT_CH_SETUP_REQUEST + * event when replying to a setup request of an L2CAP channel. + * - As output: local_cid for this channel. + * @param[in] p_params L2CAP channel parameters. + * + * @retval ::NRF_SUCCESS Successfully queued request or response for transmission. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_LENGTH Supplied higher rx_mps than has been configured on this link. + * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (L2CAP channel already set up). + * @retval ::NRF_ERROR_NOT_FOUND CID not found. + * @retval ::NRF_ERROR_RESOURCES The limit has been reached for available L2CAP channels, + * see @ref ble_l2cap_conn_cfg_t::ch_count. + */ +SVCALL(SD_BLE_L2CAP_CH_SETUP, uint32_t, + sd_ble_l2cap_ch_setup(uint16_t conn_handle, uint16_t *p_local_cid, ble_l2cap_ch_setup_params_t const *p_params)); + +/**@brief Release an L2CAP channel. + * + * @details This sends a Disconnection Request packet to a peer. + * + * @events + * @event{@ref BLE_L2CAP_EVT_CH_RELEASED, Release complete.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_L2CAP_CH_RELEASE_MSC} + * @endmscs + * + * @param[in] conn_handle Connection Handle. + * @param[in] local_cid Local Channel ID of the L2CAP channel. + * + * @retval ::NRF_SUCCESS Successfully queued request for transmission. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is + * in progress for the L2CAP channel). + * @retval ::NRF_ERROR_NOT_FOUND CID not found. + */ +SVCALL(SD_BLE_L2CAP_CH_RELEASE, uint32_t, sd_ble_l2cap_ch_release(uint16_t conn_handle, uint16_t local_cid)); + +/**@brief Receive an SDU on an L2CAP channel. + * + * @details This may issue additional credits to the peer using an LE Flow Control Credit packet. + * + * @note A call to this function will require the application to keep the memory pointed by + * @ref ble_data_t::p_data alive until the SDU data buffer is returned in @ref BLE_L2CAP_EVT_CH_RX + * or @ref BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED event. + * + * @note The SoftDevice can queue up to @ref ble_l2cap_conn_cfg_t::rx_queue_size SDU data buffers + * for reception per L2CAP channel. + * + * @events + * @event{@ref BLE_L2CAP_EVT_CH_RX, The SDU is received.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_L2CAP_CH_RX_MSC} + * @endmscs + * + * @param[in] conn_handle Connection Handle. + * @param[in] local_cid Local Channel ID of the L2CAP channel. + * @param[in] p_sdu_buf Pointer to the SDU data buffer. + * + * @retval ::NRF_SUCCESS Buffer accepted. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is + * in progress for an L2CAP channel). + * @retval ::NRF_ERROR_NOT_FOUND CID not found. + * @retval ::NRF_ERROR_RESOURCES Too many SDU data buffers supplied. Wait for a + * @ref BLE_L2CAP_EVT_CH_RX event and retry. + */ +SVCALL(SD_BLE_L2CAP_CH_RX, uint32_t, sd_ble_l2cap_ch_rx(uint16_t conn_handle, uint16_t local_cid, ble_data_t const *p_sdu_buf)); + +/**@brief Transmit an SDU on an L2CAP channel. + * + * @note A call to this function will require the application to keep the memory pointed by + * @ref ble_data_t::p_data alive until the SDU data buffer is returned in @ref BLE_L2CAP_EVT_CH_TX + * or @ref BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED event. + * + * @note The SoftDevice can queue up to @ref ble_l2cap_conn_cfg_t::tx_queue_size SDUs for + * transmission per L2CAP channel. + * + * @note The application can keep track of the available credits for transmission by following + * the procedure below: + * - Store initial credits given by the peer in a variable. + * (Initial credits are provided in a @ref BLE_L2CAP_EVT_CH_SETUP event.) + * - Decrement the variable, which stores the currently available credits, by + * ceiling((@ref ble_data_t::len + 2) / tx_mps) when a call to this function returns + * @ref NRF_SUCCESS. (tx_mps is provided in a @ref BLE_L2CAP_EVT_CH_SETUP event.) + * - Increment the variable, which stores the currently available credits, by additional + * credits given by the peer in a @ref BLE_L2CAP_EVT_CH_CREDIT event. + * + * @events + * @event{@ref BLE_L2CAP_EVT_CH_TX, The SDU is transmitted.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_L2CAP_CH_TX_MSC} + * @endmscs + * + * @param[in] conn_handle Connection Handle. + * @param[in] local_cid Local Channel ID of the L2CAP channel. + * @param[in] p_sdu_buf Pointer to the SDU data buffer. + * + * @retval ::NRF_SUCCESS Successfully queued L2CAP SDU for transmission. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is + * in progress for the L2CAP channel). + * @retval ::NRF_ERROR_NOT_FOUND CID not found. + * @retval ::NRF_ERROR_DATA_SIZE Invalid SDU length supplied, must not be more than + * @ref ble_l2cap_ch_tx_params_t::tx_mtu provided in + * @ref BLE_L2CAP_EVT_CH_SETUP event. + * @retval ::NRF_ERROR_RESOURCES Too many SDUs queued for transmission. Wait for a + * @ref BLE_L2CAP_EVT_CH_TX event and retry. + */ +SVCALL(SD_BLE_L2CAP_CH_TX, uint32_t, sd_ble_l2cap_ch_tx(uint16_t conn_handle, uint16_t local_cid, ble_data_t const *p_sdu_buf)); + +/**@brief Advanced SDU reception flow control. + * + * @details Adjust the way the SoftDevice issues credits to the peer. + * This may issue additional credits to the peer using an LE Flow Control Credit packet. + * + * @mscs + * @mmsc{@ref BLE_L2CAP_CH_FLOW_CONTROL_MSC} + * @endmscs + * + * @param[in] conn_handle Connection Handle. + * @param[in] local_cid Local Channel ID of the L2CAP channel or @ref BLE_L2CAP_CID_INVALID to set + * the value that will be used for newly created channels. + * @param[in] credits Number of credits that the SoftDevice will make sure the peer has every + * time it starts using a new reception buffer. + * - @ref BLE_L2CAP_CREDITS_DEFAULT is the default value the SoftDevice will + * use if this function is not called. + * - If set to zero, the SoftDevice will stop issuing credits for new reception + * buffers the application provides or has provided. SDU reception that is + * currently ongoing will be allowed to complete. + * @param[out] p_credits NULL or pointer to a uint16_t. If a valid pointer is provided, it will be + * written by the SoftDevice with the number of credits that is or will be + * available to the peer. If the value written by the SoftDevice is 0 when + * credits parameter was set to 0, the peer will not be able to send more + * data until more credits are provided by calling this function again with + * credits > 0. This parameter is ignored when local_cid is set to + * @ref BLE_L2CAP_CID_INVALID. + * + * @note Application should take care when setting number of credits higher than default value. In + * this case the application must make sure that the SoftDevice always has reception buffers + * available (see @ref sd_ble_l2cap_ch_rx) for that channel. If the SoftDevice does not have + * such buffers available, packets may be NACKed on the Link Layer and all Bluetooth traffic + * on the connection handle may be stalled until the SoftDevice again has an available + * reception buffer. This applies even if the application has used this call to set the + * credits back to default, or zero. + * + * @retval ::NRF_SUCCESS Flow control parameters accepted. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is + * in progress for an L2CAP channel). + * @retval ::NRF_ERROR_NOT_FOUND CID not found. + */ +SVCALL(SD_BLE_L2CAP_CH_FLOW_CONTROL, uint32_t, + sd_ble_l2cap_ch_flow_control(uint16_t conn_handle, uint16_t local_cid, uint16_t credits, uint16_t *p_credits)); + +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // BLE_L2CAP_H__ + +/** + @} +*/ diff --git a/variants/xiao_ble/softdevice/ble_ranges.h b/variants/xiao_ble/softdevice/ble_ranges.h new file mode 100644 index 000000000..2768e4996 --- /dev/null +++ b/variants/xiao_ble/softdevice/ble_ranges.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + @addtogroup BLE_COMMON + @{ + @defgroup ble_ranges Module specific SVC, event and option number subranges + @{ + + @brief Definition of SVC, event and option number subranges for each API module. + + @note + SVCs, event and option numbers are split into subranges for each API module. + Each module receives its entire allocated range of SVC calls, whether implemented or not, + but return BLE_ERROR_NOT_SUPPORTED for unimplemented or undefined calls in its range. + + Note that the symbols BLE__SVC_LAST is the end of the allocated SVC range, + rather than the last SVC function call actually defined and implemented. + + Specific SVC, event and option values are defined in each module's ble_.h file, + which defines names of each individual SVC code based on the range start value. +*/ + +#ifndef BLE_RANGES_H__ +#define BLE_RANGES_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define BLE_SVC_BASE 0x60 /**< Common BLE SVC base. */ +#define BLE_SVC_LAST 0x6B /**< Common BLE SVC last. */ + +#define BLE_GAP_SVC_BASE 0x6C /**< GAP BLE SVC base. */ +#define BLE_GAP_SVC_LAST 0x9A /**< GAP BLE SVC last. */ + +#define BLE_GATTC_SVC_BASE 0x9B /**< GATTC BLE SVC base. */ +#define BLE_GATTC_SVC_LAST 0xA7 /**< GATTC BLE SVC last. */ + +#define BLE_GATTS_SVC_BASE 0xA8 /**< GATTS BLE SVC base. */ +#define BLE_GATTS_SVC_LAST 0xB7 /**< GATTS BLE SVC last. */ + +#define BLE_L2CAP_SVC_BASE 0xB8 /**< L2CAP BLE SVC base. */ +#define BLE_L2CAP_SVC_LAST 0xBF /**< L2CAP BLE SVC last. */ + +#define BLE_EVT_INVALID 0x00 /**< Invalid BLE Event. */ + +#define BLE_EVT_BASE 0x01 /**< Common BLE Event base. */ +#define BLE_EVT_LAST 0x0F /**< Common BLE Event last. */ + +#define BLE_GAP_EVT_BASE 0x10 /**< GAP BLE Event base. */ +#define BLE_GAP_EVT_LAST 0x2F /**< GAP BLE Event last. */ + +#define BLE_GATTC_EVT_BASE 0x30 /**< GATTC BLE Event base. */ +#define BLE_GATTC_EVT_LAST 0x4F /**< GATTC BLE Event last. */ + +#define BLE_GATTS_EVT_BASE 0x50 /**< GATTS BLE Event base. */ +#define BLE_GATTS_EVT_LAST 0x6F /**< GATTS BLE Event last. */ + +#define BLE_L2CAP_EVT_BASE 0x70 /**< L2CAP BLE Event base. */ +#define BLE_L2CAP_EVT_LAST 0x8F /**< L2CAP BLE Event last. */ + +#define BLE_OPT_INVALID 0x00 /**< Invalid BLE Option. */ + +#define BLE_OPT_BASE 0x01 /**< Common BLE Option base. */ +#define BLE_OPT_LAST 0x1F /**< Common BLE Option last. */ + +#define BLE_GAP_OPT_BASE 0x20 /**< GAP BLE Option base. */ +#define BLE_GAP_OPT_LAST 0x3F /**< GAP BLE Option last. */ + +#define BLE_GATT_OPT_BASE 0x40 /**< GATT BLE Option base. */ +#define BLE_GATT_OPT_LAST 0x5F /**< GATT BLE Option last. */ + +#define BLE_GATTC_OPT_BASE 0x60 /**< GATTC BLE Option base. */ +#define BLE_GATTC_OPT_LAST 0x7F /**< GATTC BLE Option last. */ + +#define BLE_GATTS_OPT_BASE 0x80 /**< GATTS BLE Option base. */ +#define BLE_GATTS_OPT_LAST 0x9F /**< GATTS BLE Option last. */ + +#define BLE_L2CAP_OPT_BASE 0xA0 /**< L2CAP BLE Option base. */ +#define BLE_L2CAP_OPT_LAST 0xBF /**< L2CAP BLE Option last. */ + +#define BLE_CFG_INVALID 0x00 /**< Invalid BLE configuration. */ + +#define BLE_CFG_BASE 0x01 /**< Common BLE configuration base. */ +#define BLE_CFG_LAST 0x1F /**< Common BLE configuration last. */ + +#define BLE_CONN_CFG_BASE 0x20 /**< BLE connection configuration base. */ +#define BLE_CONN_CFG_LAST 0x3F /**< BLE connection configuration last. */ + +#define BLE_GAP_CFG_BASE 0x40 /**< GAP BLE configuration base. */ +#define BLE_GAP_CFG_LAST 0x5F /**< GAP BLE configuration last. */ + +#define BLE_GATT_CFG_BASE 0x60 /**< GATT BLE configuration base. */ +#define BLE_GATT_CFG_LAST 0x7F /**< GATT BLE configuration last. */ + +#define BLE_GATTC_CFG_BASE 0x80 /**< GATTC BLE configuration base. */ +#define BLE_GATTC_CFG_LAST 0x9F /**< GATTC BLE configuration last. */ + +#define BLE_GATTS_CFG_BASE 0xA0 /**< GATTS BLE configuration base. */ +#define BLE_GATTS_CFG_LAST 0xBF /**< GATTS BLE configuration last. */ + +#define BLE_L2CAP_CFG_BASE 0xC0 /**< L2CAP BLE configuration base. */ +#define BLE_L2CAP_CFG_LAST 0xDF /**< L2CAP BLE configuration last. */ + +#ifdef __cplusplus +} +#endif +#endif /* BLE_RANGES_H__ */ + +/** + @} + @} +*/ diff --git a/variants/xiao_ble/softdevice/ble_types.h b/variants/xiao_ble/softdevice/ble_types.h new file mode 100644 index 000000000..db3656cfd --- /dev/null +++ b/variants/xiao_ble/softdevice/ble_types.h @@ -0,0 +1,217 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + @addtogroup BLE_COMMON + @{ + @defgroup ble_types Common types and macro definitions + @{ + + @brief Common types and macro definitions for the BLE SoftDevice. + */ + +#ifndef BLE_TYPES_H__ +#define BLE_TYPES_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup BLE_TYPES_DEFINES Defines + * @{ */ + +/** @defgroup BLE_CONN_HANDLES BLE Connection Handles + * @{ */ +#define BLE_CONN_HANDLE_INVALID 0xFFFF /**< Invalid Connection Handle. */ +#define BLE_CONN_HANDLE_ALL 0xFFFE /**< Applies to all Connection Handles. */ +/** @} */ + +/** @defgroup BLE_UUID_VALUES Assigned Values for BLE UUIDs + * @{ */ +/* Generic UUIDs, applicable to all services */ +#define BLE_UUID_UNKNOWN 0x0000 /**< Reserved UUID. */ +#define BLE_UUID_SERVICE_PRIMARY 0x2800 /**< Primary Service. */ +#define BLE_UUID_SERVICE_SECONDARY 0x2801 /**< Secondary Service. */ +#define BLE_UUID_SERVICE_INCLUDE 0x2802 /**< Include. */ +#define BLE_UUID_CHARACTERISTIC 0x2803 /**< Characteristic. */ +#define BLE_UUID_DESCRIPTOR_CHAR_EXT_PROP 0x2900 /**< Characteristic Extended Properties Descriptor. */ +#define BLE_UUID_DESCRIPTOR_CHAR_USER_DESC 0x2901 /**< Characteristic User Description Descriptor. */ +#define BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG 0x2902 /**< Client Characteristic Configuration Descriptor. */ +#define BLE_UUID_DESCRIPTOR_SERVER_CHAR_CONFIG 0x2903 /**< Server Characteristic Configuration Descriptor. */ +#define BLE_UUID_DESCRIPTOR_CHAR_PRESENTATION_FORMAT 0x2904 /**< Characteristic Presentation Format Descriptor. */ +#define BLE_UUID_DESCRIPTOR_CHAR_AGGREGATE_FORMAT 0x2905 /**< Characteristic Aggregate Format Descriptor. */ +/* GATT specific UUIDs */ +#define BLE_UUID_GATT 0x1801 /**< Generic Attribute Profile. */ +#define BLE_UUID_GATT_CHARACTERISTIC_SERVICE_CHANGED 0x2A05 /**< Service Changed Characteristic. */ +/* GAP specific UUIDs */ +#define BLE_UUID_GAP 0x1800 /**< Generic Access Profile. */ +#define BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME 0x2A00 /**< Device Name Characteristic. */ +#define BLE_UUID_GAP_CHARACTERISTIC_APPEARANCE 0x2A01 /**< Appearance Characteristic. */ +#define BLE_UUID_GAP_CHARACTERISTIC_RECONN_ADDR 0x2A03 /**< Reconnection Address Characteristic. */ +#define BLE_UUID_GAP_CHARACTERISTIC_PPCP 0x2A04 /**< Peripheral Preferred Connection Parameters Characteristic. */ +#define BLE_UUID_GAP_CHARACTERISTIC_CAR 0x2AA6 /**< Central Address Resolution Characteristic. */ +#define BLE_UUID_GAP_CHARACTERISTIC_RPA_ONLY 0x2AC9 /**< Resolvable Private Address Only Characteristic. */ +/** @} */ + +/** @defgroup BLE_UUID_TYPES Types of UUID + * @{ */ +#define BLE_UUID_TYPE_UNKNOWN 0x00 /**< Invalid UUID type. */ +#define BLE_UUID_TYPE_BLE 0x01 /**< Bluetooth SIG UUID (16-bit). */ +#define BLE_UUID_TYPE_VENDOR_BEGIN 0x02 /**< Vendor UUID types start at this index (128-bit). */ +/** @} */ + +/** @defgroup BLE_APPEARANCES Bluetooth Appearance values + * @note Retrieved from + * http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml + * @{ */ +#define BLE_APPEARANCE_UNKNOWN 0 /**< Unknown. */ +#define BLE_APPEARANCE_GENERIC_PHONE 64 /**< Generic Phone. */ +#define BLE_APPEARANCE_GENERIC_COMPUTER 128 /**< Generic Computer. */ +#define BLE_APPEARANCE_GENERIC_WATCH 192 /**< Generic Watch. */ +#define BLE_APPEARANCE_WATCH_SPORTS_WATCH 193 /**< Watch: Sports Watch. */ +#define BLE_APPEARANCE_GENERIC_CLOCK 256 /**< Generic Clock. */ +#define BLE_APPEARANCE_GENERIC_DISPLAY 320 /**< Generic Display. */ +#define BLE_APPEARANCE_GENERIC_REMOTE_CONTROL 384 /**< Generic Remote Control. */ +#define BLE_APPEARANCE_GENERIC_EYE_GLASSES 448 /**< Generic Eye-glasses. */ +#define BLE_APPEARANCE_GENERIC_TAG 512 /**< Generic Tag. */ +#define BLE_APPEARANCE_GENERIC_KEYRING 576 /**< Generic Keyring. */ +#define BLE_APPEARANCE_GENERIC_MEDIA_PLAYER 640 /**< Generic Media Player. */ +#define BLE_APPEARANCE_GENERIC_BARCODE_SCANNER 704 /**< Generic Barcode Scanner. */ +#define BLE_APPEARANCE_GENERIC_THERMOMETER 768 /**< Generic Thermometer. */ +#define BLE_APPEARANCE_THERMOMETER_EAR 769 /**< Thermometer: Ear. */ +#define BLE_APPEARANCE_GENERIC_HEART_RATE_SENSOR 832 /**< Generic Heart rate Sensor. */ +#define BLE_APPEARANCE_HEART_RATE_SENSOR_HEART_RATE_BELT 833 /**< Heart Rate Sensor: Heart Rate Belt. */ +#define BLE_APPEARANCE_GENERIC_BLOOD_PRESSURE 896 /**< Generic Blood Pressure. */ +#define BLE_APPEARANCE_BLOOD_PRESSURE_ARM 897 /**< Blood Pressure: Arm. */ +#define BLE_APPEARANCE_BLOOD_PRESSURE_WRIST 898 /**< Blood Pressure: Wrist. */ +#define BLE_APPEARANCE_GENERIC_HID 960 /**< Human Interface Device (HID). */ +#define BLE_APPEARANCE_HID_KEYBOARD 961 /**< Keyboard (HID Subtype). */ +#define BLE_APPEARANCE_HID_MOUSE 962 /**< Mouse (HID Subtype). */ +#define BLE_APPEARANCE_HID_JOYSTICK 963 /**< Joystick (HID Subtype). */ +#define BLE_APPEARANCE_HID_GAMEPAD 964 /**< Gamepad (HID Subtype). */ +#define BLE_APPEARANCE_HID_DIGITIZERSUBTYPE 965 /**< Digitizer Tablet (HID Subtype). */ +#define BLE_APPEARANCE_HID_CARD_READER 966 /**< Card Reader (HID Subtype). */ +#define BLE_APPEARANCE_HID_DIGITAL_PEN 967 /**< Digital Pen (HID Subtype). */ +#define BLE_APPEARANCE_HID_BARCODE 968 /**< Barcode Scanner (HID Subtype). */ +#define BLE_APPEARANCE_GENERIC_GLUCOSE_METER 1024 /**< Generic Glucose Meter. */ +#define BLE_APPEARANCE_GENERIC_RUNNING_WALKING_SENSOR 1088 /**< Generic Running Walking Sensor. */ +#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_IN_SHOE 1089 /**< Running Walking Sensor: In-Shoe. */ +#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_SHOE 1090 /**< Running Walking Sensor: On-Shoe. */ +#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_HIP 1091 /**< Running Walking Sensor: On-Hip. */ +#define BLE_APPEARANCE_GENERIC_CYCLING 1152 /**< Generic Cycling. */ +#define BLE_APPEARANCE_CYCLING_CYCLING_COMPUTER 1153 /**< Cycling: Cycling Computer. */ +#define BLE_APPEARANCE_CYCLING_SPEED_SENSOR 1154 /**< Cycling: Speed Sensor. */ +#define BLE_APPEARANCE_CYCLING_CADENCE_SENSOR 1155 /**< Cycling: Cadence Sensor. */ +#define BLE_APPEARANCE_CYCLING_POWER_SENSOR 1156 /**< Cycling: Power Sensor. */ +#define BLE_APPEARANCE_CYCLING_SPEED_CADENCE_SENSOR 1157 /**< Cycling: Speed and Cadence Sensor. */ +#define BLE_APPEARANCE_GENERIC_PULSE_OXIMETER 3136 /**< Generic Pulse Oximeter. */ +#define BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP 3137 /**< Fingertip (Pulse Oximeter subtype). */ +#define BLE_APPEARANCE_PULSE_OXIMETER_WRIST_WORN 3138 /**< Wrist Worn(Pulse Oximeter subtype). */ +#define BLE_APPEARANCE_GENERIC_WEIGHT_SCALE 3200 /**< Generic Weight Scale. */ +#define BLE_APPEARANCE_GENERIC_OUTDOOR_SPORTS_ACT 5184 /**< Generic Outdoor Sports Activity. */ +#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_DISP 5185 /**< Location Display Device (Outdoor Sports Activity subtype). */ +#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_DISP \ + 5186 /**< Location and Navigation Display Device (Outdoor Sports Activity subtype). */ +#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_POD 5187 /**< Location Pod (Outdoor Sports Activity subtype). */ +#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_POD \ + 5188 /**< Location and Navigation Pod (Outdoor Sports Activity subtype). */ +/** @} */ + +/** @brief Set .type and .uuid fields of ble_uuid_struct to specified UUID value. */ +#define BLE_UUID_BLE_ASSIGN(instance, value) \ + do { \ + instance.type = BLE_UUID_TYPE_BLE; \ + instance.uuid = value; \ + } while (0) + +/** @brief Copy type and uuid members from src to dst ble_uuid_t pointer. Both pointers must be valid/non-null. */ +#define BLE_UUID_COPY_PTR(dst, src) \ + do { \ + (dst)->type = (src)->type; \ + (dst)->uuid = (src)->uuid; \ + } while (0) + +/** @brief Copy type and uuid members from src to dst ble_uuid_t struct. */ +#define BLE_UUID_COPY_INST(dst, src) \ + do { \ + (dst).type = (src).type; \ + (dst).uuid = (src).uuid; \ + } while (0) + +/** @brief Compare for equality both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */ +#define BLE_UUID_EQ(p_uuid1, p_uuid2) (((p_uuid1)->type == (p_uuid2)->type) && ((p_uuid1)->uuid == (p_uuid2)->uuid)) + +/** @brief Compare for difference both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */ +#define BLE_UUID_NEQ(p_uuid1, p_uuid2) (((p_uuid1)->type != (p_uuid2)->type) || ((p_uuid1)->uuid != (p_uuid2)->uuid)) + +/** @} */ + +/** @addtogroup BLE_TYPES_STRUCTURES Structures + * @{ */ + +/** @brief 128 bit UUID values. */ +typedef struct { + uint8_t uuid128[16]; /**< Little-Endian UUID bytes. */ +} ble_uuid128_t; + +/** @brief Bluetooth Low Energy UUID type, encapsulates both 16-bit and 128-bit UUIDs. */ +typedef struct { + uint16_t uuid; /**< 16-bit UUID value or octets 12-13 of 128-bit UUID. */ + uint8_t + type; /**< UUID type, see @ref BLE_UUID_TYPES. If type is @ref BLE_UUID_TYPE_UNKNOWN, the value of uuid is undefined. */ +} ble_uuid_t; + +/**@brief Data structure. */ +typedef struct { + uint8_t *p_data; /**< Pointer to the data buffer provided to/from the application. */ + uint16_t len; /**< Length of the data buffer, in bytes. */ +} ble_data_t; + +/** @} */ +#ifdef __cplusplus +} +#endif + +#endif /* BLE_TYPES_H__ */ + +/** + @} + @} +*/ diff --git a/variants/xiao_ble/softdevice/nrf52/nrf_mbr.h b/variants/xiao_ble/softdevice/nrf52/nrf_mbr.h new file mode 100644 index 000000000..4e0bd752a --- /dev/null +++ b/variants/xiao_ble/softdevice/nrf52/nrf_mbr.h @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + @defgroup nrf_mbr_api Master Boot Record API + @{ + + @brief APIs for updating SoftDevice and BootLoader + +*/ + +#ifndef NRF_MBR_H__ +#define NRF_MBR_H__ + +#include "nrf_svc.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup NRF_MBR_DEFINES Defines + * @{ */ + +/**@brief MBR SVC Base number. */ +#define MBR_SVC_BASE (0x18) + +/**@brief Page size in words. */ +#define MBR_PAGE_SIZE_IN_WORDS (1024) + +/** @brief The size that must be reserved for the MBR when a SoftDevice is written to flash. +This is the offset where the first byte of the SoftDevice hex file is written. */ +#define MBR_SIZE (0x1000) + +/** @brief Location (in the flash memory) of the bootloader address. */ +#define MBR_BOOTLOADER_ADDR (0xFF8) + +/** @brief Location (in UICR) of the bootloader address. */ +#define MBR_UICR_BOOTLOADER_ADDR (&(NRF_UICR->NRFFW[0])) + +/** @brief Location (in the flash memory) of the address of the MBR parameter page. */ +#define MBR_PARAM_PAGE_ADDR (0xFFC) + +/** @brief Location (in UICR) of the address of the MBR parameter page. */ +#define MBR_UICR_PARAM_PAGE_ADDR (&(NRF_UICR->NRFFW[1])) + +/** @} */ + +/** @addtogroup NRF_MBR_ENUMS Enumerations + * @{ */ + +/**@brief nRF Master Boot Record API SVC numbers. */ +enum NRF_MBR_SVCS { + SD_MBR_COMMAND = MBR_SVC_BASE, /**< ::sd_mbr_command */ +}; + +/**@brief Possible values for ::sd_mbr_command_t.command */ +enum NRF_MBR_COMMANDS { + SD_MBR_COMMAND_COPY_BL, /**< Copy a new BootLoader. @see ::sd_mbr_command_copy_bl_t*/ + SD_MBR_COMMAND_COPY_SD, /**< Copy a new SoftDevice. @see ::sd_mbr_command_copy_sd_t*/ + SD_MBR_COMMAND_INIT_SD, /**< Initialize forwarding interrupts to SD, and run reset function in SD. Does not require any + parameters in ::sd_mbr_command_t params.*/ + SD_MBR_COMMAND_COMPARE, /**< This command works like memcmp. @see ::sd_mbr_command_compare_t*/ + SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET, /**< Change the address the MBR starts after a reset. @see + ::sd_mbr_command_vector_table_base_set_t*/ + SD_MBR_COMMAND_RESERVED, + SD_MBR_COMMAND_IRQ_FORWARD_ADDRESS_SET, /**< Start forwarding all interrupts to this address. @see + ::sd_mbr_command_irq_forward_address_set_t*/ +}; + +/** @} */ + +/** @addtogroup NRF_MBR_TYPES Types + * @{ */ + +/**@brief This command copies part of a new SoftDevice + * + * The destination area is erased before copying. + * If dst is in the middle of a flash page, that whole flash page will be erased. + * If (dst+len) is in the middle of a flash page, that whole flash page will be erased. + * + * The user of this function is responsible for setting the BPROT registers. + * + * @retval ::NRF_SUCCESS indicates that the contents of the memory blocks where copied correctly. + * @retval ::NRF_ERROR_INTERNAL indicates that the contents of the memory blocks where not verified correctly after copying. + */ +typedef struct { + uint32_t *src; /**< Pointer to the source of data to be copied.*/ + uint32_t *dst; /**< Pointer to the destination where the content is to be copied.*/ + uint32_t len; /**< Number of 32 bit words to copy. Must be a multiple of @ref MBR_PAGE_SIZE_IN_WORDS words.*/ +} sd_mbr_command_copy_sd_t; + +/**@brief This command works like memcmp, but takes the length in words. + * + * @retval ::NRF_SUCCESS indicates that the contents of both memory blocks are equal. + * @retval ::NRF_ERROR_NULL indicates that the contents of the memory blocks are not equal. + */ +typedef struct { + uint32_t *ptr1; /**< Pointer to block of memory. */ + uint32_t *ptr2; /**< Pointer to block of memory. */ + uint32_t len; /**< Number of 32 bit words to compare.*/ +} sd_mbr_command_compare_t; + +/**@brief This command copies a new BootLoader. + * + * The MBR assumes that either @ref MBR_BOOTLOADER_ADDR or @ref MBR_UICR_BOOTLOADER_ADDR is set to + * the address where the bootloader will be copied. If both addresses are set, the MBR will prioritize + * @ref MBR_BOOTLOADER_ADDR. + * + * The bootloader destination is erased by this function. + * If (destination+bl_len) is in the middle of a flash page, that whole flash page will be erased. + * + * This command requires that @ref MBR_PARAM_PAGE_ADDR or @ref MBR_UICR_PARAM_PAGE_ADDR is set, + * see @ref sd_mbr_command. + * + * This command will use the flash protect peripheral (BPROT or ACL) to protect the flash that is + * not intended to be written. + * + * On success, this function will not return. It will start the new bootloader from reset-vector as normal. + * + * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen. + * @retval ::NRF_ERROR_FORBIDDEN if the bootloader address is not set. + * @retval ::NRF_ERROR_INVALID_LENGTH if parameters attempts to read or write outside flash area. + * @retval ::NRF_ERROR_NO_MEM No MBR parameter page is provided. See @ref sd_mbr_command. + */ +typedef struct { + uint32_t *bl_src; /**< Pointer to the source of the bootloader to be be copied.*/ + uint32_t bl_len; /**< Number of 32 bit words to copy for BootLoader. */ +} sd_mbr_command_copy_bl_t; + +/**@brief Change the address the MBR starts after a reset + * + * Once this function has been called, this address is where the MBR will start to forward + * interrupts to after a reset. + * + * To restore default forwarding, this function should be called with @ref address set to 0. If a + * bootloader is present, interrupts will be forwarded to the bootloader. If not, interrupts will + * be forwarded to the SoftDevice. + * + * The location of a bootloader can be specified in @ref MBR_BOOTLOADER_ADDR or + * @ref MBR_UICR_BOOTLOADER_ADDR. If both addresses are set, the MBR will prioritize + * @ref MBR_BOOTLOADER_ADDR. + * + * This command requires that @ref MBR_PARAM_PAGE_ADDR or @ref MBR_UICR_PARAM_PAGE_ADDR is set, + * see @ref sd_mbr_command. + * + * On success, this function will not return. It will reset the device. + * + * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen. + * @retval ::NRF_ERROR_INVALID_ADDR if parameter address is outside of the flash size. + * @retval ::NRF_ERROR_NO_MEM No MBR parameter page is provided. See @ref sd_mbr_command. + */ +typedef struct { + uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/ +} sd_mbr_command_vector_table_base_set_t; + +/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the MBR + * + * Unlike sd_mbr_command_vector_table_base_set_t, this function does not reset, and it does not + * change where the MBR starts after reset. + * + * @retval ::NRF_SUCCESS + */ +typedef struct { + uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/ +} sd_mbr_command_irq_forward_address_set_t; + +/**@brief Input structure containing data used when calling ::sd_mbr_command + * + * Depending on what command value that is set, the corresponding params value type must also be + * set. See @ref NRF_MBR_COMMANDS for command types and corresponding params value type. If command + * @ref SD_MBR_COMMAND_INIT_SD is set, it is not necessary to set any values under params. + */ +typedef struct { + uint32_t command; /**< Type of command to be issued. See @ref NRF_MBR_COMMANDS. */ + union { + sd_mbr_command_copy_sd_t copy_sd; /**< Parameters for copy SoftDevice.*/ + sd_mbr_command_compare_t compare; /**< Parameters for verify.*/ + sd_mbr_command_copy_bl_t copy_bl; /**< Parameters for copy BootLoader. Requires parameter page. */ + sd_mbr_command_vector_table_base_set_t base_set; /**< Parameters for vector table base set. Requires parameter page.*/ + sd_mbr_command_irq_forward_address_set_t irq_forward_address_set; /**< Parameters for irq forward address set*/ + } params; /**< Command parameters. */ +} sd_mbr_command_t; + +/** @} */ + +/** @addtogroup NRF_MBR_FUNCTIONS Functions + * @{ */ + +/**@brief Issue Master Boot Record commands + * + * Commands used when updating a SoftDevice and bootloader. + * + * The @ref SD_MBR_COMMAND_COPY_BL and @ref SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET requires + * parameters to be retained by the MBR when resetting the IC. This is done in a separate flash + * page. The location of the flash page should be provided by the application in either + * @ref MBR_PARAM_PAGE_ADDR or @ref MBR_UICR_PARAM_PAGE_ADDR. If both addresses are set, the MBR + * will prioritize @ref MBR_PARAM_PAGE_ADDR. This page will be cleared by the MBR and is used to + * store the command before reset. When an address is specified, the page it refers to must not be + * used by the application. If no address is provided by the application, i.e. both + * @ref MBR_PARAM_PAGE_ADDR and @ref MBR_UICR_PARAM_PAGE_ADDR is 0xFFFFFFFF, MBR commands which use + * flash will be unavailable and return @ref NRF_ERROR_NO_MEM. + * + * @param[in] param Pointer to a struct describing the command. + * + * @note For a complete set of return values, see ::sd_mbr_command_copy_sd_t, + * ::sd_mbr_command_copy_bl_t, ::sd_mbr_command_compare_t, + * ::sd_mbr_command_vector_table_base_set_t, ::sd_mbr_command_irq_forward_address_set_t + * + * @retval ::NRF_ERROR_NO_MEM No MBR parameter page provided + * @retval ::NRF_ERROR_INVALID_PARAM if an invalid command is given. + */ +SVCALL(SD_MBR_COMMAND, uint32_t, sd_mbr_command(sd_mbr_command_t *param)); + +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // NRF_MBR_H__ + +/** + @} +*/ diff --git a/variants/xiao_ble/softdevice/nrf_error.h b/variants/xiao_ble/softdevice/nrf_error.h new file mode 100644 index 000000000..fb2831e19 --- /dev/null +++ b/variants/xiao_ble/softdevice/nrf_error.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + @defgroup nrf_error SoftDevice Global Error Codes + @{ + + @brief Global Error definitions +*/ + +/* Header guard */ +#ifndef NRF_ERROR_H__ +#define NRF_ERROR_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup NRF_ERRORS_BASE Error Codes Base number definitions + * @{ */ +#define NRF_ERROR_BASE_NUM (0x0) ///< Global error base +#define NRF_ERROR_SDM_BASE_NUM (0x1000) ///< SDM error base +#define NRF_ERROR_SOC_BASE_NUM (0x2000) ///< SoC error base +#define NRF_ERROR_STK_BASE_NUM (0x3000) ///< STK error base +/** @} */ + +#define NRF_SUCCESS (NRF_ERROR_BASE_NUM + 0) ///< Successful command +#define NRF_ERROR_SVC_HANDLER_MISSING (NRF_ERROR_BASE_NUM + 1) ///< SVC handler is missing +#define NRF_ERROR_SOFTDEVICE_NOT_ENABLED (NRF_ERROR_BASE_NUM + 2) ///< SoftDevice has not been enabled +#define NRF_ERROR_INTERNAL (NRF_ERROR_BASE_NUM + 3) ///< Internal Error +#define NRF_ERROR_NO_MEM (NRF_ERROR_BASE_NUM + 4) ///< No Memory for operation +#define NRF_ERROR_NOT_FOUND (NRF_ERROR_BASE_NUM + 5) ///< Not found +#define NRF_ERROR_NOT_SUPPORTED (NRF_ERROR_BASE_NUM + 6) ///< Not supported +#define NRF_ERROR_INVALID_PARAM (NRF_ERROR_BASE_NUM + 7) ///< Invalid Parameter +#define NRF_ERROR_INVALID_STATE (NRF_ERROR_BASE_NUM + 8) ///< Invalid state, operation disallowed in this state +#define NRF_ERROR_INVALID_LENGTH (NRF_ERROR_BASE_NUM + 9) ///< Invalid Length +#define NRF_ERROR_INVALID_FLAGS (NRF_ERROR_BASE_NUM + 10) ///< Invalid Flags +#define NRF_ERROR_INVALID_DATA (NRF_ERROR_BASE_NUM + 11) ///< Invalid Data +#define NRF_ERROR_DATA_SIZE (NRF_ERROR_BASE_NUM + 12) ///< Invalid Data size +#define NRF_ERROR_TIMEOUT (NRF_ERROR_BASE_NUM + 13) ///< Operation timed out +#define NRF_ERROR_NULL (NRF_ERROR_BASE_NUM + 14) ///< Null Pointer +#define NRF_ERROR_FORBIDDEN (NRF_ERROR_BASE_NUM + 15) ///< Forbidden Operation +#define NRF_ERROR_INVALID_ADDR (NRF_ERROR_BASE_NUM + 16) ///< Bad Memory Address +#define NRF_ERROR_BUSY (NRF_ERROR_BASE_NUM + 17) ///< Busy +#define NRF_ERROR_CONN_COUNT (NRF_ERROR_BASE_NUM + 18) ///< Maximum connection count exceeded. +#define NRF_ERROR_RESOURCES (NRF_ERROR_BASE_NUM + 19) ///< Not enough resources for operation + +#ifdef __cplusplus +} +#endif +#endif // NRF_ERROR_H__ + +/** + @} +*/ diff --git a/variants/xiao_ble/softdevice/nrf_error_sdm.h b/variants/xiao_ble/softdevice/nrf_error_sdm.h new file mode 100644 index 000000000..2fd621057 --- /dev/null +++ b/variants/xiao_ble/softdevice/nrf_error_sdm.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + @addtogroup nrf_sdm_api + @{ + @defgroup nrf_sdm_error SoftDevice Manager Error Codes + @{ + + @brief Error definitions for the SDM API +*/ + +/* Header guard */ +#ifndef NRF_ERROR_SDM_H__ +#define NRF_ERROR_SDM_H__ + +#include "nrf_error.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN (NRF_ERROR_SDM_BASE_NUM + 0) ///< Unknown LFCLK source. +#define NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION \ + (NRF_ERROR_SDM_BASE_NUM + 1) ///< Incorrect interrupt configuration (can be caused by using illegal priority levels, or having + ///< enabled SoftDevice interrupts). +#define NRF_ERROR_SDM_INCORRECT_CLENR0 \ + (NRF_ERROR_SDM_BASE_NUM + 2) ///< Incorrect CLENR0 (can be caused by erroneous SoftDevice flashing). + +#ifdef __cplusplus +} +#endif +#endif // NRF_ERROR_SDM_H__ + +/** + @} + @} +*/ diff --git a/variants/xiao_ble/softdevice/nrf_error_soc.h b/variants/xiao_ble/softdevice/nrf_error_soc.h new file mode 100644 index 000000000..cbd0ba8ac --- /dev/null +++ b/variants/xiao_ble/softdevice/nrf_error_soc.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + @addtogroup nrf_soc_api + @{ + @defgroup nrf_soc_error SoC Library Error Codes + @{ + + @brief Error definitions for the SoC library + +*/ + +/* Header guard */ +#ifndef NRF_ERROR_SOC_H__ +#define NRF_ERROR_SOC_H__ + +#include "nrf_error.h" +#ifdef __cplusplus +extern "C" { +#endif + +/* Mutex Errors */ +#define NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN (NRF_ERROR_SOC_BASE_NUM + 0) ///< Mutex already taken + +/* NVIC errors */ +#define NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE (NRF_ERROR_SOC_BASE_NUM + 1) ///< NVIC interrupt not available +#define NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED (NRF_ERROR_SOC_BASE_NUM + 2) ///< NVIC interrupt priority not allowed +#define NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 3) ///< NVIC should not return + +/* Power errors */ +#define NRF_ERROR_SOC_POWER_MODE_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 4) ///< Power mode unknown +#define NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 5) ///< Power POF threshold unknown +#define NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 6) ///< Power off should not return + +/* Rand errors */ +#define NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES (NRF_ERROR_SOC_BASE_NUM + 7) ///< RAND not enough values + +/* PPI errors */ +#define NRF_ERROR_SOC_PPI_INVALID_CHANNEL (NRF_ERROR_SOC_BASE_NUM + 8) ///< Invalid PPI Channel +#define NRF_ERROR_SOC_PPI_INVALID_GROUP (NRF_ERROR_SOC_BASE_NUM + 9) ///< Invalid PPI Group + +#ifdef __cplusplus +} +#endif +#endif // NRF_ERROR_SOC_H__ +/** + @} + @} +*/ diff --git a/variants/xiao_ble/softdevice/nrf_nvic.h b/variants/xiao_ble/softdevice/nrf_nvic.h new file mode 100644 index 000000000..d4ab204d9 --- /dev/null +++ b/variants/xiao_ble/softdevice/nrf_nvic.h @@ -0,0 +1,449 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup nrf_nvic_api SoftDevice NVIC API + * @{ + * + * @note In order to use this module, the following code has to be added to a .c file: + * \code + * nrf_nvic_state_t nrf_nvic_state = {0}; + * \endcode + * + * @note Definitions and declarations starting with __ (double underscore) in this header file are + * not intended for direct use by the application. + * + * @brief APIs for the accessing NVIC when using a SoftDevice. + * + */ + +#ifndef NRF_NVIC_H__ +#define NRF_NVIC_H__ + +#include "nrf.h" +#include "nrf_error.h" +#include "nrf_error_soc.h" +#include "nrf_svc.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@addtogroup NRF_NVIC_DEFINES Defines + * @{ */ + +/**@defgroup NRF_NVIC_ISER_DEFINES SoftDevice NVIC internal definitions + * @{ */ + +#define __NRF_NVIC_NVMC_IRQn \ + (30) /**< The peripheral ID of the NVMC. IRQ numbers are used to identify peripherals, but the NVMC doesn't have an IRQ \ + number in the MDK. */ + +#define __NRF_NVIC_ISER_COUNT (2) /**< The number of ISER/ICER registers in the NVIC that are used. */ + +/**@brief Interrupt priority levels used by the SoftDevice. */ +#define __NRF_NVIC_SD_IRQ_PRIOS \ + ((uint8_t)((1U << 0) /**< Priority level high .*/ \ + | (1U << 1) /**< Priority level medium. */ \ + | (1U << 4) /**< Priority level low. */ \ + )) + +/**@brief Interrupt priority levels available to the application. */ +#define __NRF_NVIC_APP_IRQ_PRIOS ((uint8_t)~__NRF_NVIC_SD_IRQ_PRIOS) + +/**@brief Interrupts used by the SoftDevice, with IRQn in the range 0-31. */ +#define __NRF_NVIC_SD_IRQS_0 \ + ((uint32_t)((1U << POWER_CLOCK_IRQn) | (1U << RADIO_IRQn) | (1U << RTC0_IRQn) | (1U << TIMER0_IRQn) | (1U << RNG_IRQn) | \ + (1U << ECB_IRQn) | (1U << CCM_AAR_IRQn) | (1U << TEMP_IRQn) | (1U << __NRF_NVIC_NVMC_IRQn) | \ + (1U << (uint32_t)SWI5_IRQn))) + +/**@brief Interrupts used by the SoftDevice, with IRQn in the range 32-63. */ +#define __NRF_NVIC_SD_IRQS_1 ((uint32_t)0) + +/**@brief Interrupts available for to application, with IRQn in the range 0-31. */ +#define __NRF_NVIC_APP_IRQS_0 (~__NRF_NVIC_SD_IRQS_0) + +/**@brief Interrupts available for to application, with IRQn in the range 32-63. */ +#define __NRF_NVIC_APP_IRQS_1 (~__NRF_NVIC_SD_IRQS_1) + +/**@} */ + +/**@} */ + +/**@addtogroup NRF_NVIC_VARIABLES Variables + * @{ */ + +/**@brief Type representing the state struct for the SoftDevice NVIC module. */ +typedef struct { + uint32_t volatile __irq_masks[__NRF_NVIC_ISER_COUNT]; /**< IRQs enabled by the application in the NVIC. */ + uint32_t volatile __cr_flag; /**< Non-zero if already in a critical region */ +} nrf_nvic_state_t; + +/**@brief Variable keeping the state for the SoftDevice NVIC module. This must be declared in an + * application source file. */ +extern nrf_nvic_state_t nrf_nvic_state; + +/**@} */ + +/**@addtogroup NRF_NVIC_INTERNAL_FUNCTIONS SoftDevice NVIC internal functions + * @{ */ + +/**@brief Disables IRQ interrupts globally, including the SoftDevice's interrupts. + * + * @retval The value of PRIMASK prior to disabling the interrupts. + */ +__STATIC_INLINE int __sd_nvic_irq_disable(void); + +/**@brief Enables IRQ interrupts globally, including the SoftDevice's interrupts. + */ +__STATIC_INLINE void __sd_nvic_irq_enable(void); + +/**@brief Checks if IRQn is available to application + * @param[in] IRQn IRQ to check + * + * @retval 1 (true) if the IRQ to check is available to the application + */ +__STATIC_INLINE uint32_t __sd_nvic_app_accessible_irq(IRQn_Type IRQn); + +/**@brief Checks if priority is available to application + * @param[in] priority priority to check + * + * @retval 1 (true) if the priority to check is available to the application + */ +__STATIC_INLINE uint32_t __sd_nvic_is_app_accessible_priority(uint32_t priority); + +/**@} */ + +/**@addtogroup NRF_NVIC_FUNCTIONS SoftDevice NVIC public functions + * @{ */ + +/**@brief Enable External Interrupt. + * @note Corresponds to NVIC_EnableIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_EnableIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt was enabled. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt has a priority not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn); + +/**@brief Disable External Interrupt. + * @note Corresponds to NVIC_DisableIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_DisableIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt was disabled. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn); + +/**@brief Get Pending Interrupt. + * @note Corresponds to NVIC_GetPendingIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_GetPendingIRQ documentation in CMSIS. + * @param[out] p_pending_irq Return value from NVIC_GetPendingIRQ. + * + * @retval ::NRF_SUCCESS The interrupt is available for the application. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t *p_pending_irq); + +/**@brief Set Pending Interrupt. + * @note Corresponds to NVIC_SetPendingIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_SetPendingIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt is set pending. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn); + +/**@brief Clear Pending Interrupt. + * @note Corresponds to NVIC_ClearPendingIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_ClearPendingIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt pending flag is cleared. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn); + +/**@brief Set Interrupt Priority. + * @note Corresponds to NVIC_SetPriority in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * @pre Priority is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_SetPriority documentation in CMSIS. + * @param[in] priority A valid IRQ priority for use by the application. + * + * @retval ::NRF_SUCCESS The interrupt and priority level is available for the application. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt priority is not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority); + +/**@brief Get Interrupt Priority. + * @note Corresponds to NVIC_GetPriority in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_GetPriority documentation in CMSIS. + * @param[out] p_priority Return value from NVIC_GetPriority. + * + * @retval ::NRF_SUCCESS The interrupt priority is returned in p_priority. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE - IRQn is not available for the application. + */ +__STATIC_INLINE uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t *p_priority); + +/**@brief System Reset. + * @note Corresponds to NVIC_SystemReset in CMSIS. + * + * @retval ::NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN + */ +__STATIC_INLINE uint32_t sd_nvic_SystemReset(void); + +/**@brief Enter critical region. + * + * @post Application interrupts will be disabled. + * @note sd_nvic_critical_region_enter() and ::sd_nvic_critical_region_exit() must be called in matching pairs inside each + * execution context + * @sa sd_nvic_critical_region_exit + * + * @param[out] p_is_nested_critical_region If 1, the application is now in a nested critical region. + * + * @retval ::NRF_SUCCESS + */ +__STATIC_INLINE uint32_t sd_nvic_critical_region_enter(uint8_t *p_is_nested_critical_region); + +/**@brief Exit critical region. + * + * @pre Application has entered a critical region using ::sd_nvic_critical_region_enter. + * @post If not in a nested critical region, the application interrupts will restored to the state before + * ::sd_nvic_critical_region_enter was called. + * + * @param[in] is_nested_critical_region If this is set to 1, the critical region won't be exited. @sa + * sd_nvic_critical_region_enter. + * + * @retval ::NRF_SUCCESS + */ +__STATIC_INLINE uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region); + +/**@} */ + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE int __sd_nvic_irq_disable(void) +{ + int pm = __get_PRIMASK(); + __disable_irq(); + return pm; +} + +__STATIC_INLINE void __sd_nvic_irq_enable(void) +{ + __enable_irq(); +} + +__STATIC_INLINE uint32_t __sd_nvic_app_accessible_irq(IRQn_Type IRQn) +{ + if (IRQn < 32) { + return ((1UL << IRQn) & __NRF_NVIC_APP_IRQS_0) != 0; + } else if (IRQn < 64) { + return ((1UL << (IRQn - 32)) & __NRF_NVIC_APP_IRQS_1) != 0; + } else { + return 1; + } +} + +__STATIC_INLINE uint32_t __sd_nvic_is_app_accessible_priority(uint32_t priority) +{ + if ((priority >= (1 << __NVIC_PRIO_BITS)) || (((1 << priority) & __NRF_NVIC_APP_IRQ_PRIOS) == 0)) { + return 0; + } + return 1; +} + +__STATIC_INLINE uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn) +{ + if (!__sd_nvic_app_accessible_irq(IRQn)) { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } + if (!__sd_nvic_is_app_accessible_priority(NVIC_GetPriority(IRQn))) { + return NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED; + } + + if (nrf_nvic_state.__cr_flag) { + nrf_nvic_state.__irq_masks[(uint32_t)((int32_t)IRQn) >> 5] |= + (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F)); + } else { + NVIC_EnableIRQ(IRQn); + } + return NRF_SUCCESS; +} + +__STATIC_INLINE uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn) +{ + if (!__sd_nvic_app_accessible_irq(IRQn)) { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } + + if (nrf_nvic_state.__cr_flag) { + nrf_nvic_state.__irq_masks[(uint32_t)((int32_t)IRQn) >> 5] &= ~(1UL << ((uint32_t)(IRQn)&0x1F)); + } else { + NVIC_DisableIRQ(IRQn); + } + + return NRF_SUCCESS; +} + +__STATIC_INLINE uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t *p_pending_irq) +{ + if (__sd_nvic_app_accessible_irq(IRQn)) { + *p_pending_irq = NVIC_GetPendingIRQ(IRQn); + return NRF_SUCCESS; + } else { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } +} + +__STATIC_INLINE uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn) +{ + if (__sd_nvic_app_accessible_irq(IRQn)) { + NVIC_SetPendingIRQ(IRQn); + return NRF_SUCCESS; + } else { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } +} + +__STATIC_INLINE uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn) +{ + if (__sd_nvic_app_accessible_irq(IRQn)) { + NVIC_ClearPendingIRQ(IRQn); + return NRF_SUCCESS; + } else { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } +} + +__STATIC_INLINE uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if (!__sd_nvic_app_accessible_irq(IRQn)) { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } + + if (!__sd_nvic_is_app_accessible_priority(priority)) { + return NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED; + } + + NVIC_SetPriority(IRQn, (uint32_t)priority); + return NRF_SUCCESS; +} + +__STATIC_INLINE uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t *p_priority) +{ + if (__sd_nvic_app_accessible_irq(IRQn)) { + *p_priority = (NVIC_GetPriority(IRQn) & 0xFF); + return NRF_SUCCESS; + } else { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } +} + +__STATIC_INLINE uint32_t sd_nvic_SystemReset(void) +{ + NVIC_SystemReset(); + return NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN; +} + +__STATIC_INLINE uint32_t sd_nvic_critical_region_enter(uint8_t *p_is_nested_critical_region) +{ + int was_masked = __sd_nvic_irq_disable(); + if (!nrf_nvic_state.__cr_flag) { + nrf_nvic_state.__cr_flag = 1; + nrf_nvic_state.__irq_masks[0] = (NVIC->ICER[0] & __NRF_NVIC_APP_IRQS_0); + NVIC->ICER[0] = __NRF_NVIC_APP_IRQS_0; + nrf_nvic_state.__irq_masks[1] = (NVIC->ICER[1] & __NRF_NVIC_APP_IRQS_1); + NVIC->ICER[1] = __NRF_NVIC_APP_IRQS_1; + *p_is_nested_critical_region = 0; + } else { + *p_is_nested_critical_region = 1; + } + if (!was_masked) { + __sd_nvic_irq_enable(); + } + return NRF_SUCCESS; +} + +__STATIC_INLINE uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region) +{ + if (nrf_nvic_state.__cr_flag && (is_nested_critical_region == 0)) { + int was_masked = __sd_nvic_irq_disable(); + NVIC->ISER[0] = nrf_nvic_state.__irq_masks[0]; + NVIC->ISER[1] = nrf_nvic_state.__irq_masks[1]; + nrf_nvic_state.__cr_flag = 0; + if (!was_masked) { + __sd_nvic_irq_enable(); + } + } + + return NRF_SUCCESS; +} + +#endif /* SUPPRESS_INLINE_IMPLEMENTATION */ + +#ifdef __cplusplus +} +#endif + +#endif // NRF_NVIC_H__ + +/**@} */ diff --git a/variants/xiao_ble/softdevice/nrf_sdm.h b/variants/xiao_ble/softdevice/nrf_sdm.h new file mode 100644 index 000000000..2786a86a4 --- /dev/null +++ b/variants/xiao_ble/softdevice/nrf_sdm.h @@ -0,0 +1,380 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + @defgroup nrf_sdm_api SoftDevice Manager API + @{ + + @brief APIs for SoftDevice management. + +*/ + +#ifndef NRF_SDM_H__ +#define NRF_SDM_H__ + +#include "nrf.h" +#include "nrf_error.h" +#include "nrf_error_sdm.h" +#include "nrf_soc.h" +#include "nrf_svc.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup NRF_SDM_DEFINES Defines + * @{ */ +#ifdef NRFSOC_DOXYGEN +/// Declared in nrf_mbr.h +#define MBR_SIZE 0 +#warning test +#endif + +/** @brief The major version for the SoftDevice binary distributed with this header file. */ +#define SD_MAJOR_VERSION (7) + +/** @brief The minor version for the SoftDevice binary distributed with this header file. */ +#define SD_MINOR_VERSION (3) + +/** @brief The bugfix version for the SoftDevice binary distributed with this header file. */ +#define SD_BUGFIX_VERSION (0) + +/** @brief The SoftDevice variant of this firmware. */ +#define SD_VARIANT_ID 140 + +/** @brief The full version number for the SoftDevice binary this header file was distributed + * with, as a decimal number in the form Mmmmbbb, where: + * - M is major version (one or more digits) + * - mmm is minor version (three digits) + * - bbb is bugfix version (three digits). */ +#define SD_VERSION (SD_MAJOR_VERSION * 1000000 + SD_MINOR_VERSION * 1000 + SD_BUGFIX_VERSION) + +/** @brief SoftDevice Manager SVC Base number. */ +#define SDM_SVC_BASE 0x10 + +/** @brief SoftDevice unique string size in bytes. */ +#define SD_UNIQUE_STR_SIZE 20 + +/** @brief Invalid info field. Returned when an info field does not exist. */ +#define SDM_INFO_FIELD_INVALID (0) + +/** @brief Defines the SoftDevice Information Structure location (address) as an offset from +the start of the SoftDevice (without MBR)*/ +#define SOFTDEVICE_INFO_STRUCT_OFFSET (0x2000) + +/** @brief Defines the absolute SoftDevice Information Structure location (address) when the + * SoftDevice is installed just above the MBR (the usual case). */ +#define SOFTDEVICE_INFO_STRUCT_ADDRESS (SOFTDEVICE_INFO_STRUCT_OFFSET + MBR_SIZE) + +/** @brief Defines the offset for the SoftDevice Information Structure size value relative to the + * SoftDevice base address. The size value is of type uint8_t. */ +#define SD_INFO_STRUCT_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET) + +/** @brief Defines the offset for the SoftDevice size value relative to the SoftDevice base address. + * The size value is of type uint32_t. */ +#define SD_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x08) + +/** @brief Defines the offset for FWID value relative to the SoftDevice base address. The FWID value + * is of type uint16_t. */ +#define SD_FWID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x0C) + +/** @brief Defines the offset for the SoftDevice ID relative to the SoftDevice base address. The ID + * is of type uint32_t. */ +#define SD_ID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x10) + +/** @brief Defines the offset for the SoftDevice version relative to the SoftDevice base address in + * the same format as @ref SD_VERSION, stored as an uint32_t. */ +#define SD_VERSION_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x14) + +/** @brief Defines the offset for the SoftDevice unique string relative to the SoftDevice base address. + * The SD_UNIQUE_STR is stored as an array of uint8_t. The size of array is @ref SD_UNIQUE_STR_SIZE. + */ +#define SD_UNIQUE_STR_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x18) + +/** @brief Defines a macro for retrieving the actual SoftDevice Information Structure size value + * from a given base address. Use @ref MBR_SIZE as the argument when the SoftDevice is + * installed just above the MBR (the usual case). */ +#define SD_INFO_STRUCT_SIZE_GET(baseaddr) (*((uint8_t *)((baseaddr) + SD_INFO_STRUCT_SIZE_OFFSET))) + +/** @brief Defines a macro for retrieving the actual SoftDevice size value from a given base + * address. Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above + * the MBR (the usual case). */ +#define SD_SIZE_GET(baseaddr) (*((uint32_t *)((baseaddr) + SD_SIZE_OFFSET))) + +/** @brief Defines the amount of flash that is used by the SoftDevice. + * Add @ref MBR_SIZE to find the first available flash address when the SoftDevice is installed + * just above the MBR (the usual case). + */ +#define SD_FLASH_SIZE 0x26000 + +/** @brief Defines a macro for retrieving the actual FWID value from a given base address. Use + * @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR (the usual + * case). */ +#define SD_FWID_GET(baseaddr) (*((uint16_t *)((baseaddr) + SD_FWID_OFFSET))) + +/** @brief Defines a macro for retrieving the actual SoftDevice ID from a given base address. Use + * @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR (the + * usual case). */ +#define SD_ID_GET(baseaddr) \ + ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_ID_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \ + ? (*((uint32_t *)((baseaddr) + SD_ID_OFFSET))) \ + : SDM_INFO_FIELD_INVALID) + +/** @brief Defines a macro for retrieving the actual SoftDevice version from a given base address. + * Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR + * (the usual case). */ +#define SD_VERSION_GET(baseaddr) \ + ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_VERSION_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \ + ? (*((uint32_t *)((baseaddr) + SD_VERSION_OFFSET))) \ + : SDM_INFO_FIELD_INVALID) + +/** @brief Defines a macro for retrieving the address of SoftDevice unique str based on a given base address. + * Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR + * (the usual case). */ +#define SD_UNIQUE_STR_ADDR_GET(baseaddr) \ + ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_UNIQUE_STR_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \ + ? (((uint8_t *)((baseaddr) + SD_UNIQUE_STR_OFFSET))) \ + : SDM_INFO_FIELD_INVALID) + +/**@defgroup NRF_FAULT_ID_RANGES Fault ID ranges + * @{ */ +#define NRF_FAULT_ID_SD_RANGE_START 0x00000000 /**< SoftDevice ID range start. */ +#define NRF_FAULT_ID_APP_RANGE_START 0x00001000 /**< Application ID range start. */ +/**@} */ + +/**@defgroup NRF_FAULT_IDS Fault ID types + * @{ */ +#define NRF_FAULT_ID_SD_ASSERT \ + (NRF_FAULT_ID_SD_RANGE_START + 1) /**< SoftDevice assertion. The info parameter is reserved for future used. */ +#define NRF_FAULT_ID_APP_MEMACC \ + (NRF_FAULT_ID_APP_RANGE_START + 1) /**< Application invalid memory access. The info parameter will contain 0x00000000, \ + in case of SoftDevice RAM access violation. In case of SoftDevice peripheral \ + register violation the info parameter will contain the sub-region number of \ + PREGION[0], on whose address range the disallowed write access caused the \ + memory access fault. */ +/**@} */ + +/** @} */ + +/** @addtogroup NRF_SDM_ENUMS Enumerations + * @{ */ + +/**@brief nRF SoftDevice Manager API SVC numbers. */ +enum NRF_SD_SVCS { + SD_SOFTDEVICE_ENABLE = SDM_SVC_BASE, /**< ::sd_softdevice_enable */ + SD_SOFTDEVICE_DISABLE, /**< ::sd_softdevice_disable */ + SD_SOFTDEVICE_IS_ENABLED, /**< ::sd_softdevice_is_enabled */ + SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, /**< ::sd_softdevice_vector_table_base_set */ + SVC_SDM_LAST /**< Placeholder for last SDM SVC */ +}; + +/** @} */ + +/** @addtogroup NRF_SDM_DEFINES Defines + * @{ */ + +/**@defgroup NRF_CLOCK_LF_ACCURACY Clock accuracy + * @{ */ + +#define NRF_CLOCK_LF_ACCURACY_250_PPM (0) /**< Default: 250 ppm */ +#define NRF_CLOCK_LF_ACCURACY_500_PPM (1) /**< 500 ppm */ +#define NRF_CLOCK_LF_ACCURACY_150_PPM (2) /**< 150 ppm */ +#define NRF_CLOCK_LF_ACCURACY_100_PPM (3) /**< 100 ppm */ +#define NRF_CLOCK_LF_ACCURACY_75_PPM (4) /**< 75 ppm */ +#define NRF_CLOCK_LF_ACCURACY_50_PPM (5) /**< 50 ppm */ +#define NRF_CLOCK_LF_ACCURACY_30_PPM (6) /**< 30 ppm */ +#define NRF_CLOCK_LF_ACCURACY_20_PPM (7) /**< 20 ppm */ +#define NRF_CLOCK_LF_ACCURACY_10_PPM (8) /**< 10 ppm */ +#define NRF_CLOCK_LF_ACCURACY_5_PPM (9) /**< 5 ppm */ +#define NRF_CLOCK_LF_ACCURACY_2_PPM (10) /**< 2 ppm */ +#define NRF_CLOCK_LF_ACCURACY_1_PPM (11) /**< 1 ppm */ + +/** @} */ + +/**@defgroup NRF_CLOCK_LF_SRC Possible LFCLK oscillator sources + * @{ */ + +#define NRF_CLOCK_LF_SRC_RC (0) /**< LFCLK RC oscillator. */ +#define NRF_CLOCK_LF_SRC_XTAL (1) /**< LFCLK crystal oscillator. */ +#define NRF_CLOCK_LF_SRC_SYNTH (2) /**< LFCLK Synthesized from HFCLK. */ + +/** @} */ + +/** @} */ + +/** @addtogroup NRF_SDM_TYPES Types + * @{ */ + +/**@brief Type representing LFCLK oscillator source. */ +typedef struct { + uint8_t source; /**< LF oscillator clock source, see @ref NRF_CLOCK_LF_SRC. */ + uint8_t rc_ctiv; /**< Only for ::NRF_CLOCK_LF_SRC_RC: Calibration timer interval in 1/4 second + units (nRF52: 1-32). + @note To avoid excessive clock drift, 0.5 degrees Celsius is the + maximum temperature change allowed in one calibration timer + interval. The interval should be selected to ensure this. + + @note Must be 0 if source is not ::NRF_CLOCK_LF_SRC_RC. */ + uint8_t rc_temp_ctiv; /**< Only for ::NRF_CLOCK_LF_SRC_RC: How often (in number of calibration + intervals) the RC oscillator shall be calibrated if the temperature + hasn't changed. + 0: Always calibrate even if the temperature hasn't changed. + 1: Only calibrate if the temperature has changed (legacy - nRF51 only). + 2-33: Check the temperature and only calibrate if it has changed, + however calibration will take place every rc_temp_ctiv + intervals in any case. + + @note Must be 0 if source is not ::NRF_CLOCK_LF_SRC_RC. + + @note For nRF52, the application must ensure calibration at least once + every 8 seconds to ensure +/-500 ppm clock stability. The + recommended configuration for ::NRF_CLOCK_LF_SRC_RC on nRF52 is + rc_ctiv=16 and rc_temp_ctiv=2. This will ensure calibration at + least once every 8 seconds and for temperature changes of 0.5 + degrees Celsius every 4 seconds. See the Product Specification + for the nRF52 device being used for more information.*/ + uint8_t accuracy; /**< External clock accuracy used in the LL to compute timing + windows, see @ref NRF_CLOCK_LF_ACCURACY.*/ +} nrf_clock_lf_cfg_t; + +/**@brief Fault Handler type. + * + * When certain unrecoverable errors occur within the application or SoftDevice the fault handler will be called back. + * The protocol stack will be in an undefined state when this happens and the only way to recover will be to + * perform a reset, using e.g. CMSIS NVIC_SystemReset(). + * If the application returns from the fault handler the SoftDevice will call NVIC_SystemReset(). + * + * @note It is recommended to either perform a reset in the fault handler or to let the SoftDevice reset the device. + * Otherwise SoC peripherals may behave in an undefined way. For example, the RADIO peripherial may + * continously transmit packets. + * + * @note This callback is executed in HardFault context, thus SVC functions cannot be called from the fault callback. + * + * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS. + * @param[in] pc The program counter of the instruction that triggered the fault. + * @param[in] info Optional additional information regarding the fault. Refer to each Fault identifier for details. + * + * @note When id is set to @ref NRF_FAULT_ID_APP_MEMACC, pc will contain the address of the instruction being executed at the time + * when the fault is detected by the CPU. The CPU program counter may have advanced up to 2 instructions (no branching) after the + * one that triggered the fault. + */ +typedef void (*nrf_fault_handler_t)(uint32_t id, uint32_t pc, uint32_t info); + +/** @} */ + +/** @addtogroup NRF_SDM_FUNCTIONS Functions + * @{ */ + +/**@brief Enables the SoftDevice and by extension the protocol stack. + * + * @note Some care must be taken if a low frequency clock source is already running when calling this function: + * If the LF clock has a different source then the one currently running, it will be stopped. Then, the new + * clock source will be started. + * + * @note This function has no effect when returning with an error. + * + * @post If return code is ::NRF_SUCCESS + * - SoC library and protocol stack APIs are made available. + * - A portion of RAM will be unavailable (see relevant SDS documentation). + * - Some peripherals will be unavailable or available only through the SoC API (see relevant SDS documentation). + * - Interrupts will not arrive from protected peripherals or interrupts. + * - nrf_nvic_ functions must be used instead of CMSIS NVIC_ functions for reliable usage of the SoftDevice. + * - Interrupt latency may be affected by the SoftDevice (see relevant SDS documentation). + * - Chosen low frequency clock source will be running. + * + * @param p_clock_lf_cfg Low frequency clock source and accuracy. + If NULL the clock will be configured as an RC source with rc_ctiv = 16 and .rc_temp_ctiv = 2 + In the case of XTAL source, the PPM accuracy of the chosen clock source must be greater than or equal to + the actual characteristics of your XTAL clock. + * @param fault_handler Callback to be invoked in case of fault, cannot be NULL. + * + * @retval ::NRF_SUCCESS + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or NULL pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE SoftDevice is already enabled, and the clock source and fault handler cannot be updated. + * @retval ::NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION SoftDevice interrupt is already enabled, or an enabled interrupt has + an illegal priority level. + * @retval ::NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN Unknown low frequency clock source selected. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid clock source configuration supplied in p_clock_lf_cfg. + */ +SVCALL(SD_SOFTDEVICE_ENABLE, uint32_t, + sd_softdevice_enable(nrf_clock_lf_cfg_t const *p_clock_lf_cfg, nrf_fault_handler_t fault_handler)); + +/**@brief Disables the SoftDevice and by extension the protocol stack. + * + * Idempotent function to disable the SoftDevice. + * + * @post SoC library and protocol stack APIs are made unavailable. + * @post All interrupts that was protected by the SoftDevice will be disabled and initialized to priority 0 (highest). + * @post All peripherals used by the SoftDevice will be reset to default values. + * @post All of RAM become available. + * @post All interrupts are forwarded to the application. + * @post LFCLK source chosen in ::sd_softdevice_enable will be left running. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_SOFTDEVICE_DISABLE, uint32_t, sd_softdevice_disable(void)); + +/**@brief Check if the SoftDevice is enabled. + * + * @param[out] p_softdevice_enabled If the SoftDevice is enabled: 1 else 0. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_SOFTDEVICE_IS_ENABLED, uint32_t, sd_softdevice_is_enabled(uint8_t *p_softdevice_enabled)); + +/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the SoftDevice + * + * This function is only intended to be called when a bootloader is enabled. + * + * @param[in] address The base address of the interrupt vector table for forwarded interrupts. + + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, uint32_t, sd_softdevice_vector_table_base_set(uint32_t address)); + +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // NRF_SDM_H__ + +/** + @} +*/ diff --git a/variants/xiao_ble/softdevice/nrf_soc.h b/variants/xiao_ble/softdevice/nrf_soc.h new file mode 100644 index 000000000..c649ca836 --- /dev/null +++ b/variants/xiao_ble/softdevice/nrf_soc.h @@ -0,0 +1,1046 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @defgroup nrf_soc_api SoC Library API + * @{ + * + * @brief APIs for the SoC library. + * + */ + +#ifndef NRF_SOC_H__ +#define NRF_SOC_H__ + +#include "nrf.h" +#include "nrf_error.h" +#include "nrf_error_soc.h" +#include "nrf_svc.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@addtogroup NRF_SOC_DEFINES Defines + * @{ */ + +/**@brief The number of the lowest SVC number reserved for the SoC library. */ +#define SOC_SVC_BASE (0x20) /**< Base value for SVCs that are available when the SoftDevice is disabled. */ +#define SOC_SVC_BASE_NOT_AVAILABLE (0x2C) /**< Base value for SVCs that are not available when the SoftDevice is disabled. */ + +/**@brief Guaranteed time for application to process radio inactive notification. */ +#define NRF_RADIO_NOTIFICATION_INACTIVE_GUARANTEED_TIME_US (62) + +/**@brief The minimum allowed timeslot extension time. */ +#define NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US (200) + +/**@brief The maximum processing time to handle a timeslot extension. */ +#define NRF_RADIO_MAX_EXTENSION_PROCESSING_TIME_US (20) + +/**@brief The latest time before the end of a timeslot the timeslot can be extended. */ +#define NRF_RADIO_MIN_EXTENSION_MARGIN_US (82) + +#define SOC_ECB_KEY_LENGTH (16) /**< ECB key length. */ +#define SOC_ECB_CLEARTEXT_LENGTH (16) /**< ECB cleartext length. */ +#define SOC_ECB_CIPHERTEXT_LENGTH (SOC_ECB_CLEARTEXT_LENGTH) /**< ECB ciphertext length. */ + +#define SD_EVT_IRQn (SWI2_IRQn) /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */ +#define SD_EVT_IRQHandler \ + (SWI2_IRQHandler) /**< SoftDevice Event IRQ handler. Used for both protocol events and SoC events. \ + The default interrupt priority for this handler is set to 6 */ +#define RADIO_NOTIFICATION_IRQn (SWI1_IRQn) /**< The radio notification IRQ number. */ +#define RADIO_NOTIFICATION_IRQHandler \ + (SWI1_IRQHandler) /**< The radio notification IRQ handler. \ + The default interrupt priority for this handler is set to 6 */ +#define NRF_RADIO_LENGTH_MIN_US (100) /**< The shortest allowed radio timeslot, in microseconds. */ +#define NRF_RADIO_LENGTH_MAX_US (100000) /**< The longest allowed radio timeslot, in microseconds. */ + +#define NRF_RADIO_DISTANCE_MAX_US \ + (128000000UL - 1UL) /**< The longest timeslot distance, in microseconds, allowed for the distance parameter (see @ref \ + nrf_radio_request_normal_t) in the request. */ + +#define NRF_RADIO_EARLIEST_TIMEOUT_MAX_US \ + (128000000UL - 1UL) /**< The longest timeout, in microseconds, allowed when requesting the earliest possible timeslot. */ + +#define NRF_RADIO_START_JITTER_US \ + (2) /**< The maximum jitter in @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START relative to the requested start time. */ + +/**@brief Mask of PPI channels reserved by the SoftDevice when the SoftDevice is disabled. */ +#define NRF_SOC_SD_PPI_CHANNELS_SD_DISABLED_MSK ((uint32_t)(0)) + +/**@brief Mask of PPI channels reserved by the SoftDevice when the SoftDevice is enabled. */ +#define NRF_SOC_SD_PPI_CHANNELS_SD_ENABLED_MSK \ + ((uint32_t)((1U << 17) | (1U << 18) | (1U << 19) | (1U << 20) | (1U << 21) | (1U << 22) | (1U << 23) | (1U << 24) | \ + (1U << 25) | (1U << 26) | (1U << 27) | (1U << 28) | (1U << 29) | (1U << 30) | (1U << 31))) + +/**@brief Mask of PPI groups reserved by the SoftDevice when the SoftDevice is disabled. */ +#define NRF_SOC_SD_PPI_GROUPS_SD_DISABLED_MSK ((uint32_t)(0)) + +/**@brief Mask of PPI groups reserved by the SoftDevice when the SoftDevice is enabled. */ +#define NRF_SOC_SD_PPI_GROUPS_SD_ENABLED_MSK ((uint32_t)((1U << 4) | (1U << 5))) + +/**@} */ + +/**@addtogroup NRF_SOC_ENUMS Enumerations + * @{ */ + +/**@brief The SVC numbers used by the SVC functions in the SoC library. */ +enum NRF_SOC_SVCS { + SD_PPI_CHANNEL_ENABLE_GET = SOC_SVC_BASE, + SD_PPI_CHANNEL_ENABLE_SET = SOC_SVC_BASE + 1, + SD_PPI_CHANNEL_ENABLE_CLR = SOC_SVC_BASE + 2, + SD_PPI_CHANNEL_ASSIGN = SOC_SVC_BASE + 3, + SD_PPI_GROUP_TASK_ENABLE = SOC_SVC_BASE + 4, + SD_PPI_GROUP_TASK_DISABLE = SOC_SVC_BASE + 5, + SD_PPI_GROUP_ASSIGN = SOC_SVC_BASE + 6, + SD_PPI_GROUP_GET = SOC_SVC_BASE + 7, + SD_FLASH_PAGE_ERASE = SOC_SVC_BASE + 8, + SD_FLASH_WRITE = SOC_SVC_BASE + 9, + SD_PROTECTED_REGISTER_WRITE = SOC_SVC_BASE + 11, + SD_MUTEX_NEW = SOC_SVC_BASE_NOT_AVAILABLE, + SD_MUTEX_ACQUIRE = SOC_SVC_BASE_NOT_AVAILABLE + 1, + SD_MUTEX_RELEASE = SOC_SVC_BASE_NOT_AVAILABLE + 2, + SD_RAND_APPLICATION_POOL_CAPACITY_GET = SOC_SVC_BASE_NOT_AVAILABLE + 3, + SD_RAND_APPLICATION_BYTES_AVAILABLE_GET = SOC_SVC_BASE_NOT_AVAILABLE + 4, + SD_RAND_APPLICATION_VECTOR_GET = SOC_SVC_BASE_NOT_AVAILABLE + 5, + SD_POWER_MODE_SET = SOC_SVC_BASE_NOT_AVAILABLE + 6, + SD_POWER_SYSTEM_OFF = SOC_SVC_BASE_NOT_AVAILABLE + 7, + SD_POWER_RESET_REASON_GET = SOC_SVC_BASE_NOT_AVAILABLE + 8, + SD_POWER_RESET_REASON_CLR = SOC_SVC_BASE_NOT_AVAILABLE + 9, + SD_POWER_POF_ENABLE = SOC_SVC_BASE_NOT_AVAILABLE + 10, + SD_POWER_POF_THRESHOLD_SET = SOC_SVC_BASE_NOT_AVAILABLE + 11, + SD_POWER_POF_THRESHOLDVDDH_SET = SOC_SVC_BASE_NOT_AVAILABLE + 12, + SD_POWER_RAM_POWER_SET = SOC_SVC_BASE_NOT_AVAILABLE + 13, + SD_POWER_RAM_POWER_CLR = SOC_SVC_BASE_NOT_AVAILABLE + 14, + SD_POWER_RAM_POWER_GET = SOC_SVC_BASE_NOT_AVAILABLE + 15, + SD_POWER_GPREGRET_SET = SOC_SVC_BASE_NOT_AVAILABLE + 16, + SD_POWER_GPREGRET_CLR = SOC_SVC_BASE_NOT_AVAILABLE + 17, + SD_POWER_GPREGRET_GET = SOC_SVC_BASE_NOT_AVAILABLE + 18, + SD_POWER_DCDC_MODE_SET = SOC_SVC_BASE_NOT_AVAILABLE + 19, + SD_POWER_DCDC0_MODE_SET = SOC_SVC_BASE_NOT_AVAILABLE + 20, + SD_APP_EVT_WAIT = SOC_SVC_BASE_NOT_AVAILABLE + 21, + SD_CLOCK_HFCLK_REQUEST = SOC_SVC_BASE_NOT_AVAILABLE + 22, + SD_CLOCK_HFCLK_RELEASE = SOC_SVC_BASE_NOT_AVAILABLE + 23, + SD_CLOCK_HFCLK_IS_RUNNING = SOC_SVC_BASE_NOT_AVAILABLE + 24, + SD_RADIO_NOTIFICATION_CFG_SET = SOC_SVC_BASE_NOT_AVAILABLE + 25, + SD_ECB_BLOCK_ENCRYPT = SOC_SVC_BASE_NOT_AVAILABLE + 26, + SD_ECB_BLOCKS_ENCRYPT = SOC_SVC_BASE_NOT_AVAILABLE + 27, + SD_RADIO_SESSION_OPEN = SOC_SVC_BASE_NOT_AVAILABLE + 28, + SD_RADIO_SESSION_CLOSE = SOC_SVC_BASE_NOT_AVAILABLE + 29, + SD_RADIO_REQUEST = SOC_SVC_BASE_NOT_AVAILABLE + 30, + SD_EVT_GET = SOC_SVC_BASE_NOT_AVAILABLE + 31, + SD_TEMP_GET = SOC_SVC_BASE_NOT_AVAILABLE + 32, + SD_POWER_USBPWRRDY_ENABLE = SOC_SVC_BASE_NOT_AVAILABLE + 33, + SD_POWER_USBDETECTED_ENABLE = SOC_SVC_BASE_NOT_AVAILABLE + 34, + SD_POWER_USBREMOVED_ENABLE = SOC_SVC_BASE_NOT_AVAILABLE + 35, + SD_POWER_USBREGSTATUS_GET = SOC_SVC_BASE_NOT_AVAILABLE + 36, + SVC_SOC_LAST = SOC_SVC_BASE_NOT_AVAILABLE + 37 +}; + +/**@brief Possible values of a ::nrf_mutex_t. */ +enum NRF_MUTEX_VALUES { NRF_MUTEX_FREE, NRF_MUTEX_TAKEN }; + +/**@brief Power modes. */ +enum NRF_POWER_MODES { + NRF_POWER_MODE_CONSTLAT, /**< Constant latency mode. See power management in the reference manual. */ + NRF_POWER_MODE_LOWPWR /**< Low power mode. See power management in the reference manual. */ +}; + +/**@brief Power failure thresholds */ +enum NRF_POWER_THRESHOLDS { + NRF_POWER_THRESHOLD_V17 = 4UL, /**< 1.7 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V18, /**< 1.8 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V19, /**< 1.9 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V20, /**< 2.0 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V21, /**< 2.1 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V22, /**< 2.2 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V23, /**< 2.3 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V24, /**< 2.4 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V25, /**< 2.5 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V26, /**< 2.6 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V27, /**< 2.7 Volts power failure threshold. */ + NRF_POWER_THRESHOLD_V28 /**< 2.8 Volts power failure threshold. */ +}; + +/**@brief Power failure thresholds for high voltage */ +enum NRF_POWER_THRESHOLDVDDHS { + NRF_POWER_THRESHOLDVDDH_V27, /**< 2.7 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V28, /**< 2.8 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V29, /**< 2.9 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V30, /**< 3.0 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V31, /**< 3.1 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V32, /**< 3.2 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V33, /**< 3.3 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V34, /**< 3.4 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V35, /**< 3.5 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V36, /**< 3.6 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V37, /**< 3.7 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V38, /**< 3.8 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V39, /**< 3.9 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V40, /**< 4.0 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V41, /**< 4.1 Volts power failure threshold. */ + NRF_POWER_THRESHOLDVDDH_V42 /**< 4.2 Volts power failure threshold. */ +}; + +/**@brief DC/DC converter modes. */ +enum NRF_POWER_DCDC_MODES { + NRF_POWER_DCDC_DISABLE, /**< The DCDC is disabled. */ + NRF_POWER_DCDC_ENABLE /**< The DCDC is enabled. */ +}; + +/**@brief Radio notification distances. */ +enum NRF_RADIO_NOTIFICATION_DISTANCES { + NRF_RADIO_NOTIFICATION_DISTANCE_NONE = 0, /**< The event does not have a notification. */ + NRF_RADIO_NOTIFICATION_DISTANCE_800US, /**< The distance from the active notification to start of radio activity. */ + NRF_RADIO_NOTIFICATION_DISTANCE_1740US, /**< The distance from the active notification to start of radio activity. */ + NRF_RADIO_NOTIFICATION_DISTANCE_2680US, /**< The distance from the active notification to start of radio activity. */ + NRF_RADIO_NOTIFICATION_DISTANCE_3620US, /**< The distance from the active notification to start of radio activity. */ + NRF_RADIO_NOTIFICATION_DISTANCE_4560US, /**< The distance from the active notification to start of radio activity. */ + NRF_RADIO_NOTIFICATION_DISTANCE_5500US /**< The distance from the active notification to start of radio activity. */ +}; + +/**@brief Radio notification types. */ +enum NRF_RADIO_NOTIFICATION_TYPES { + NRF_RADIO_NOTIFICATION_TYPE_NONE = 0, /**< The event does not have a radio notification signal. */ + NRF_RADIO_NOTIFICATION_TYPE_INT_ON_ACTIVE, /**< Using interrupt for notification when the radio will be enabled. */ + NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE, /**< Using interrupt for notification when the radio has been disabled. */ + NRF_RADIO_NOTIFICATION_TYPE_INT_ON_BOTH, /**< Using interrupt for notification both when the radio will be enabled and + disabled. */ +}; + +/**@brief The Radio signal callback types. */ +enum NRF_RADIO_CALLBACK_SIGNAL_TYPE { + NRF_RADIO_CALLBACK_SIGNAL_TYPE_START, /**< This signal indicates the start of the radio timeslot. */ + NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0, /**< This signal indicates the NRF_TIMER0 interrupt. */ + NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO, /**< This signal indicates the NRF_RADIO interrupt. */ + NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_FAILED, /**< This signal indicates extend action failed. */ + NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED /**< This signal indicates extend action succeeded. */ +}; + +/**@brief The actions requested by the signal callback. + * + * This code gives the SOC instructions about what action to take when the signal callback has + * returned. + */ +enum NRF_RADIO_SIGNAL_CALLBACK_ACTION { + NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE, /**< Return without action. */ + NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND, /**< Request an extension of the current + timeslot. Maximum execution time for this action: + @ref NRF_RADIO_MAX_EXTENSION_PROCESSING_TIME_US. + This action must be started at least + @ref NRF_RADIO_MIN_EXTENSION_MARGIN_US before + the end of the timeslot. */ + NRF_RADIO_SIGNAL_CALLBACK_ACTION_END, /**< End the current radio timeslot. */ + NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END /**< Request a new radio timeslot and end the current timeslot. */ +}; + +/**@brief Radio timeslot high frequency clock source configuration. */ +enum NRF_RADIO_HFCLK_CFG { + NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED, /**< The SoftDevice will guarantee that the high frequency clock source is the + external crystal for the whole duration of the timeslot. This should be the + preferred option for events that use the radio or require high timing accuracy. + @note The SoftDevice will automatically turn on and off the external crystal, + at the beginning and end of the timeslot, respectively. The crystal may also + intentionally be left running after the timeslot, in cases where it is needed + by the SoftDevice shortly after the end of the timeslot. */ + NRF_RADIO_HFCLK_CFG_NO_GUARANTEE /**< This configuration allows for earlier and tighter scheduling of timeslots. + The RC oscillator may be the clock source in part or for the whole duration of the + timeslot. The RC oscillator's accuracy must therefore be taken into consideration. + @note If the application will use the radio peripheral in timeslots with this + configuration, it must make sure that the crystal is running and stable before + starting the radio. */ +}; + +/**@brief Radio timeslot priorities. */ +enum NRF_RADIO_PRIORITY { + NRF_RADIO_PRIORITY_HIGH, /**< High (equal priority as the normal connection priority of the SoftDevice stack(s)). */ + NRF_RADIO_PRIORITY_NORMAL, /**< Normal (equal priority as the priority of secondary activities of the SoftDevice stack(s)). */ +}; + +/**@brief Radio timeslot request type. */ +enum NRF_RADIO_REQUEST_TYPE { + NRF_RADIO_REQ_TYPE_EARLIEST, /**< Request radio timeslot as early as possible. This should always be used for the first + request in a session. */ + NRF_RADIO_REQ_TYPE_NORMAL /**< Normal radio timeslot request. */ +}; + +/**@brief SoC Events. */ +enum NRF_SOC_EVTS { + NRF_EVT_HFCLKSTARTED, /**< Event indicating that the HFCLK has started. */ + NRF_EVT_POWER_FAILURE_WARNING, /**< Event indicating that a power failure warning has occurred. */ + NRF_EVT_FLASH_OPERATION_SUCCESS, /**< Event indicating that the ongoing flash operation has completed successfully. */ + NRF_EVT_FLASH_OPERATION_ERROR, /**< Event indicating that the ongoing flash operation has timed out with an error. */ + NRF_EVT_RADIO_BLOCKED, /**< Event indicating that a radio timeslot was blocked. */ + NRF_EVT_RADIO_CANCELED, /**< Event indicating that a radio timeslot was canceled by SoftDevice. */ + NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN, /**< Event indicating that a radio timeslot signal callback handler return was + invalid. */ + NRF_EVT_RADIO_SESSION_IDLE, /**< Event indicating that a radio timeslot session is idle. */ + NRF_EVT_RADIO_SESSION_CLOSED, /**< Event indicating that a radio timeslot session is closed. */ + NRF_EVT_POWER_USB_POWER_READY, /**< Event indicating that a USB 3.3 V supply is ready. */ + NRF_EVT_POWER_USB_DETECTED, /**< Event indicating that voltage supply is detected on VBUS. */ + NRF_EVT_POWER_USB_REMOVED, /**< Event indicating that voltage supply is removed from VBUS. */ + NRF_EVT_NUMBER_OF_EVTS +}; + +/**@} */ + +/**@addtogroup NRF_SOC_STRUCTURES Structures + * @{ */ + +/**@brief Represents a mutex for use with the nrf_mutex functions. + * @note Accessing the value directly is not safe, use the mutex functions! + */ +typedef volatile uint8_t nrf_mutex_t; + +/**@brief Parameters for a request for a timeslot as early as possible. */ +typedef struct { + uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */ + uint8_t priority; /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */ + uint32_t length_us; /**< The radio timeslot length (in the range 100 to 100,000] microseconds). */ + uint32_t timeout_us; /**< Longest acceptable delay until the start of the requested timeslot (up to @ref + NRF_RADIO_EARLIEST_TIMEOUT_MAX_US microseconds). */ +} nrf_radio_request_earliest_t; + +/**@brief Parameters for a normal radio timeslot request. */ +typedef struct { + uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */ + uint8_t priority; /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */ + uint32_t distance_us; /**< Distance from the start of the previous radio timeslot (up to @ref NRF_RADIO_DISTANCE_MAX_US + microseconds). */ + uint32_t length_us; /**< The radio timeslot length (in the range [100..100,000] microseconds). */ +} nrf_radio_request_normal_t; + +/**@brief Radio timeslot request parameters. */ +typedef struct { + uint8_t request_type; /**< Type of request, see @ref NRF_RADIO_REQUEST_TYPE. */ + union { + nrf_radio_request_earliest_t earliest; /**< Parameters for requesting a radio timeslot as early as possible. */ + nrf_radio_request_normal_t normal; /**< Parameters for requesting a normal radio timeslot. */ + } params; /**< Parameter union. */ +} nrf_radio_request_t; + +/**@brief Return parameters of the radio timeslot signal callback. */ +typedef struct { + uint8_t callback_action; /**< The action requested by the application when returning from the signal callback, see @ref + NRF_RADIO_SIGNAL_CALLBACK_ACTION. */ + union { + struct { + nrf_radio_request_t *p_next; /**< The request parameters for the next radio timeslot. */ + } request; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END. */ + struct { + uint32_t length_us; /**< Requested extension of the radio timeslot duration (microseconds) (for minimum time see @ref + NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US). */ + } extend; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND. */ + } params; /**< Parameter union. */ +} nrf_radio_signal_callback_return_param_t; + +/**@brief The radio timeslot signal callback type. + * + * @note In case of invalid return parameters, the radio timeslot will automatically end + * immediately after returning from the signal callback and the + * @ref NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN event will be sent. + * @note The returned struct pointer must remain valid after the signal callback + * function returns. For instance, this means that it must not point to a stack variable. + * + * @param[in] signal_type Type of signal, see @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE. + * + * @return Pointer to structure containing action requested by the application. + */ +typedef nrf_radio_signal_callback_return_param_t *(*nrf_radio_signal_callback_t)(uint8_t signal_type); + +/**@brief AES ECB parameter typedefs */ +typedef uint8_t soc_ecb_key_t[SOC_ECB_KEY_LENGTH]; /**< Encryption key type. */ +typedef uint8_t soc_ecb_cleartext_t[SOC_ECB_CLEARTEXT_LENGTH]; /**< Cleartext data type. */ +typedef uint8_t soc_ecb_ciphertext_t[SOC_ECB_CIPHERTEXT_LENGTH]; /**< Ciphertext data type. */ + +/**@brief AES ECB data structure */ +typedef struct { + soc_ecb_key_t key; /**< Encryption key. */ + soc_ecb_cleartext_t cleartext; /**< Cleartext data. */ + soc_ecb_ciphertext_t ciphertext; /**< Ciphertext data. */ +} nrf_ecb_hal_data_t; + +/**@brief AES ECB block. Used to provide multiple blocks in a single call + to @ref sd_ecb_blocks_encrypt.*/ +typedef struct { + soc_ecb_key_t const *p_key; /**< Pointer to the Encryption key. */ + soc_ecb_cleartext_t const *p_cleartext; /**< Pointer to the Cleartext data. */ + soc_ecb_ciphertext_t *p_ciphertext; /**< Pointer to the Ciphertext data. */ +} nrf_ecb_hal_data_block_t; + +/**@} */ + +/**@addtogroup NRF_SOC_FUNCTIONS Functions + * @{ */ + +/**@brief Initialize a mutex. + * + * @param[in] p_mutex Pointer to the mutex to initialize. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_MUTEX_NEW, uint32_t, sd_mutex_new(nrf_mutex_t *p_mutex)); + +/**@brief Attempt to acquire a mutex. + * + * @param[in] p_mutex Pointer to the mutex to acquire. + * + * @retval ::NRF_SUCCESS The mutex was successfully acquired. + * @retval ::NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN The mutex could not be acquired. + */ +SVCALL(SD_MUTEX_ACQUIRE, uint32_t, sd_mutex_acquire(nrf_mutex_t *p_mutex)); + +/**@brief Release a mutex. + * + * @param[in] p_mutex Pointer to the mutex to release. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_MUTEX_RELEASE, uint32_t, sd_mutex_release(nrf_mutex_t *p_mutex)); + +/**@brief Query the capacity of the application random pool. + * + * @param[out] p_pool_capacity The capacity of the pool. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_RAND_APPLICATION_POOL_CAPACITY_GET, uint32_t, sd_rand_application_pool_capacity_get(uint8_t *p_pool_capacity)); + +/**@brief Get number of random bytes available to the application. + * + * @param[out] p_bytes_available The number of bytes currently available in the pool. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_RAND_APPLICATION_BYTES_AVAILABLE_GET, uint32_t, sd_rand_application_bytes_available_get(uint8_t *p_bytes_available)); + +/**@brief Get random bytes from the application pool. + * + * @param[out] p_buff Pointer to unit8_t buffer for storing the bytes. + * @param[in] length Number of bytes to take from pool and place in p_buff. + * + * @retval ::NRF_SUCCESS The requested bytes were written to p_buff. + * @retval ::NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES No bytes were written to the buffer, because there were not enough bytes + * available. + */ +SVCALL(SD_RAND_APPLICATION_VECTOR_GET, uint32_t, sd_rand_application_vector_get(uint8_t *p_buff, uint8_t length)); + +/**@brief Gets the reset reason register. + * + * @param[out] p_reset_reason Contents of the NRF_POWER->RESETREAS register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_RESET_REASON_GET, uint32_t, sd_power_reset_reason_get(uint32_t *p_reset_reason)); + +/**@brief Clears the bits of the reset reason register. + * + * @param[in] reset_reason_clr_msk Contains the bits to clear from the reset reason register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_RESET_REASON_CLR, uint32_t, sd_power_reset_reason_clr(uint32_t reset_reason_clr_msk)); + +/**@brief Sets the power mode when in CPU sleep. + * + * @param[in] power_mode The power mode to use when in CPU sleep, see @ref NRF_POWER_MODES. @sa sd_app_evt_wait + * + * @retval ::NRF_SUCCESS The power mode was set. + * @retval ::NRF_ERROR_SOC_POWER_MODE_UNKNOWN The power mode was unknown. + */ +SVCALL(SD_POWER_MODE_SET, uint32_t, sd_power_mode_set(uint8_t power_mode)); + +/**@brief Puts the chip in System OFF mode. + * + * @retval ::NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN + */ +SVCALL(SD_POWER_SYSTEM_OFF, uint32_t, sd_power_system_off(void)); + +/**@brief Enables or disables the power-fail comparator. + * + * Enabling this will give a SoftDevice event (NRF_EVT_POWER_FAILURE_WARNING) when the power failure warning occurs. + * The event can be retrieved with sd_evt_get(); + * + * @param[in] pof_enable True if the power-fail comparator should be enabled, false if it should be disabled. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_POF_ENABLE, uint32_t, sd_power_pof_enable(uint8_t pof_enable)); + +/**@brief Enables or disables the USB power ready event. + * + * Enabling this will give a SoftDevice event (NRF_EVT_POWER_USB_POWER_READY) when a USB 3.3 V supply is ready. + * The event can be retrieved with sd_evt_get(); + * + * @param[in] usbpwrrdy_enable True if the power ready event should be enabled, false if it should be disabled. + * + * @note Calling this function on a chip without USBD peripheral will result in undefined behaviour. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_USBPWRRDY_ENABLE, uint32_t, sd_power_usbpwrrdy_enable(uint8_t usbpwrrdy_enable)); + +/**@brief Enables or disables the power USB-detected event. + * + * Enabling this will give a SoftDevice event (NRF_EVT_POWER_USB_DETECTED) when a voltage supply is detected on VBUS. + * The event can be retrieved with sd_evt_get(); + * + * @param[in] usbdetected_enable True if the power ready event should be enabled, false if it should be disabled. + * + * @note Calling this function on a chip without USBD peripheral will result in undefined behaviour. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_USBDETECTED_ENABLE, uint32_t, sd_power_usbdetected_enable(uint8_t usbdetected_enable)); + +/**@brief Enables or disables the power USB-removed event. + * + * Enabling this will give a SoftDevice event (NRF_EVT_POWER_USB_REMOVED) when a voltage supply is removed from VBUS. + * The event can be retrieved with sd_evt_get(); + * + * @param[in] usbremoved_enable True if the power ready event should be enabled, false if it should be disabled. + * + * @note Calling this function on a chip without USBD peripheral will result in undefined behaviour. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_USBREMOVED_ENABLE, uint32_t, sd_power_usbremoved_enable(uint8_t usbremoved_enable)); + +/**@brief Get USB supply status register content. + * + * @param[out] usbregstatus The content of USBREGSTATUS register. + * + * @note Calling this function on a chip without USBD peripheral will result in undefined behaviour. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_USBREGSTATUS_GET, uint32_t, sd_power_usbregstatus_get(uint32_t *usbregstatus)); + +/**@brief Sets the power failure comparator threshold value. + * + * @note: Power failure comparator threshold setting. This setting applies both for normal voltage + * mode (supply connected to both VDD and VDDH) and high voltage mode (supply connected to + * VDDH only). + * + * @param[in] threshold The power-fail threshold value to use, see @ref NRF_POWER_THRESHOLDS. + * + * @retval ::NRF_SUCCESS The power failure threshold was set. + * @retval ::NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN The power failure threshold is unknown. + */ +SVCALL(SD_POWER_POF_THRESHOLD_SET, uint32_t, sd_power_pof_threshold_set(uint8_t threshold)); + +/**@brief Sets the power failure comparator threshold value for high voltage. + * + * @note: Power failure comparator threshold setting for high voltage mode (supply connected to + * VDDH only). This setting does not apply for normal voltage mode (supply connected to both + * VDD and VDDH). + * + * @param[in] threshold The power-fail threshold value to use, see @ref NRF_POWER_THRESHOLDVDDHS. + * + * @retval ::NRF_SUCCESS The power failure threshold was set. + * @retval ::NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN The power failure threshold is unknown. + */ +SVCALL(SD_POWER_POF_THRESHOLDVDDH_SET, uint32_t, sd_power_pof_thresholdvddh_set(uint8_t threshold)); + +/**@brief Writes the NRF_POWER->RAM[index].POWERSET register. + * + * @param[in] index Contains the index in the NRF_POWER->RAM[index].POWERSET register to write to. + * @param[in] ram_powerset Contains the word to write to the NRF_POWER->RAM[index].POWERSET register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_RAM_POWER_SET, uint32_t, sd_power_ram_power_set(uint8_t index, uint32_t ram_powerset)); + +/**@brief Writes the NRF_POWER->RAM[index].POWERCLR register. + * + * @param[in] index Contains the index in the NRF_POWER->RAM[index].POWERCLR register to write to. + * @param[in] ram_powerclr Contains the word to write to the NRF_POWER->RAM[index].POWERCLR register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_RAM_POWER_CLR, uint32_t, sd_power_ram_power_clr(uint8_t index, uint32_t ram_powerclr)); + +/**@brief Get contents of NRF_POWER->RAM[index].POWER register, indicates power status of RAM[index] blocks. + * + * @param[in] index Contains the index in the NRF_POWER->RAM[index].POWER register to read from. + * @param[out] p_ram_power Content of NRF_POWER->RAM[index].POWER register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_RAM_POWER_GET, uint32_t, sd_power_ram_power_get(uint8_t index, uint32_t *p_ram_power)); + +/**@brief Set bits in the general purpose retention registers (NRF_POWER->GPREGRET*). + * + * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2. + * @param[in] gpregret_msk Bits to be set in the GPREGRET register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_GPREGRET_SET, uint32_t, sd_power_gpregret_set(uint32_t gpregret_id, uint32_t gpregret_msk)); + +/**@brief Clear bits in the general purpose retention registers (NRF_POWER->GPREGRET*). + * + * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2. + * @param[in] gpregret_msk Bits to be clear in the GPREGRET register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_GPREGRET_CLR, uint32_t, sd_power_gpregret_clr(uint32_t gpregret_id, uint32_t gpregret_msk)); + +/**@brief Get contents of the general purpose retention registers (NRF_POWER->GPREGRET*). + * + * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2. + * @param[out] p_gpregret Contents of the GPREGRET register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_POWER_GPREGRET_GET, uint32_t, sd_power_gpregret_get(uint32_t gpregret_id, uint32_t *p_gpregret)); + +/**@brief Enable or disable the DC/DC regulator for the regulator stage 1 (REG1). + * + * @param[in] dcdc_mode The mode of the DCDC, see @ref NRF_POWER_DCDC_MODES. + * + * @retval ::NRF_SUCCESS + * @retval ::NRF_ERROR_INVALID_PARAM The DCDC mode is invalid. + */ +SVCALL(SD_POWER_DCDC_MODE_SET, uint32_t, sd_power_dcdc_mode_set(uint8_t dcdc_mode)); + +/**@brief Enable or disable the DC/DC regulator for the regulator stage 0 (REG0). + * + * For more details on the REG0 stage, please see product specification. + * + * @param[in] dcdc_mode The mode of the DCDC0, see @ref NRF_POWER_DCDC_MODES. + * + * @retval ::NRF_SUCCESS + * @retval ::NRF_ERROR_INVALID_PARAM The dcdc_mode is invalid. + */ +SVCALL(SD_POWER_DCDC0_MODE_SET, uint32_t, sd_power_dcdc0_mode_set(uint8_t dcdc_mode)); + +/**@brief Request the high frequency crystal oscillator. + * + * Will start the high frequency crystal oscillator, the startup time of the crystal varies + * and the ::sd_clock_hfclk_is_running function can be polled to check if it has started. + * + * @see sd_clock_hfclk_is_running + * @see sd_clock_hfclk_release + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_CLOCK_HFCLK_REQUEST, uint32_t, sd_clock_hfclk_request(void)); + +/**@brief Releases the high frequency crystal oscillator. + * + * Will stop the high frequency crystal oscillator, this happens immediately. + * + * @see sd_clock_hfclk_is_running + * @see sd_clock_hfclk_request + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_CLOCK_HFCLK_RELEASE, uint32_t, sd_clock_hfclk_release(void)); + +/**@brief Checks if the high frequency crystal oscillator is running. + * + * @see sd_clock_hfclk_request + * @see sd_clock_hfclk_release + * + * @param[out] p_is_running 1 if the external crystal oscillator is running, 0 if not. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_CLOCK_HFCLK_IS_RUNNING, uint32_t, sd_clock_hfclk_is_running(uint32_t *p_is_running)); + +/**@brief Waits for an application event. + * + * An application event is either an application interrupt or a pended interrupt when the interrupt + * is disabled. + * + * When the application waits for an application event by calling this function, an interrupt that + * is enabled will be taken immediately on pending since this function will wait in thread mode, + * then the execution will return in the application's main thread. + * + * In order to wake up from disabled interrupts, the SEVONPEND flag has to be set in the Cortex-M + * MCU's System Control Register (SCR), CMSIS_SCB. In that case, when a disabled interrupt gets + * pended, this function will return to the application's main thread. + * + * @note The application must ensure that the pended flag is cleared using ::sd_nvic_ClearPendingIRQ + * in order to sleep using this function. This is only necessary for disabled interrupts, as + * the interrupt handler will clear the pending flag automatically for enabled interrupts. + * + * @note If an application interrupt has happened since the last time sd_app_evt_wait was + * called this function will return immediately and not go to sleep. This is to avoid race + * conditions that can occur when a flag is updated in the interrupt handler and processed + * in the main loop. + * + * @post An application interrupt has happened or a interrupt pending flag is set. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_APP_EVT_WAIT, uint32_t, sd_app_evt_wait(void)); + +/**@brief Get PPI channel enable register contents. + * + * @param[out] p_channel_enable The contents of the PPI CHEN register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_CHANNEL_ENABLE_GET, uint32_t, sd_ppi_channel_enable_get(uint32_t *p_channel_enable)); + +/**@brief Set PPI channel enable register. + * + * @param[in] channel_enable_set_msk Mask containing the bits to set in the PPI CHEN register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_CHANNEL_ENABLE_SET, uint32_t, sd_ppi_channel_enable_set(uint32_t channel_enable_set_msk)); + +/**@brief Clear PPI channel enable register. + * + * @param[in] channel_enable_clr_msk Mask containing the bits to clear in the PPI CHEN register. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_CHANNEL_ENABLE_CLR, uint32_t, sd_ppi_channel_enable_clr(uint32_t channel_enable_clr_msk)); + +/**@brief Assign endpoints to a PPI channel. + * + * @param[in] channel_num Number of the PPI channel to assign. + * @param[in] evt_endpoint Event endpoint of the PPI channel. + * @param[in] task_endpoint Task endpoint of the PPI channel. + * + * @retval ::NRF_ERROR_SOC_PPI_INVALID_CHANNEL The channel number is invalid. + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_CHANNEL_ASSIGN, uint32_t, + sd_ppi_channel_assign(uint8_t channel_num, const volatile void *evt_endpoint, const volatile void *task_endpoint)); + +/**@brief Task to enable a channel group. + * + * @param[in] group_num Number of the channel group. + * + * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_GROUP_TASK_ENABLE, uint32_t, sd_ppi_group_task_enable(uint8_t group_num)); + +/**@brief Task to disable a channel group. + * + * @param[in] group_num Number of the PPI group. + * + * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid. + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_GROUP_TASK_DISABLE, uint32_t, sd_ppi_group_task_disable(uint8_t group_num)); + +/**@brief Assign PPI channels to a channel group. + * + * @param[in] group_num Number of the channel group. + * @param[in] channel_msk Mask of the channels to assign to the group. + * + * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid. + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_GROUP_ASSIGN, uint32_t, sd_ppi_group_assign(uint8_t group_num, uint32_t channel_msk)); + +/**@brief Gets the PPI channels of a channel group. + * + * @param[in] group_num Number of the channel group. + * @param[out] p_channel_msk Mask of the channels assigned to the group. + * + * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid. + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_PPI_GROUP_GET, uint32_t, sd_ppi_group_get(uint8_t group_num, uint32_t *p_channel_msk)); + +/**@brief Configures the Radio Notification signal. + * + * @note + * - The notification signal latency depends on the interrupt priority settings of SWI used + * for notification signal. + * - To ensure that the radio notification signal behaves in a consistent way, the radio + * notifications must be configured when there is no protocol stack or other SoftDevice + * activity in progress. It is recommended that the radio notification signal is + * configured directly after the SoftDevice has been enabled. + * - In the period between the ACTIVE signal and the start of the Radio Event, the SoftDevice + * will interrupt the application to do Radio Event preparation. + * - Using the Radio Notification feature may limit the bandwidth, as the SoftDevice may have + * to shorten the connection events to have time for the Radio Notification signals. + * + * @param[in] type Type of notification signal, see @ref NRF_RADIO_NOTIFICATION_TYPES. + * @ref NRF_RADIO_NOTIFICATION_TYPE_NONE shall be used to turn off radio + * notification. Using @ref NRF_RADIO_NOTIFICATION_DISTANCE_NONE is + * recommended (but not required) to be used with + * @ref NRF_RADIO_NOTIFICATION_TYPE_NONE. + * + * @param[in] distance Distance between the notification signal and start of radio activity, see @ref + * NRF_RADIO_NOTIFICATION_DISTANCES. This parameter is ignored when @ref NRF_RADIO_NOTIFICATION_TYPE_NONE or + * @ref NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE is used. + * + * @retval ::NRF_ERROR_INVALID_PARAM The group number is invalid. + * @retval ::NRF_ERROR_INVALID_STATE A protocol stack or other SoftDevice is running. Stop all + * running activities and retry. + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_RADIO_NOTIFICATION_CFG_SET, uint32_t, sd_radio_notification_cfg_set(uint8_t type, uint8_t distance)); + +/**@brief Encrypts a block according to the specified parameters. + * + * 128-bit AES encryption. + * + * @note: + * - The application may set the SEVONPEND bit in the SCR to 1 to make the SoftDevice sleep while + * the ECB is running. The SEVONPEND bit should only be cleared (set to 0) from application + * main or low interrupt level. + * + * @param[in, out] p_ecb_data Pointer to the ECB parameters' struct (two input + * parameters and one output parameter). + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_ECB_BLOCK_ENCRYPT, uint32_t, sd_ecb_block_encrypt(nrf_ecb_hal_data_t *p_ecb_data)); + +/**@brief Encrypts multiple data blocks provided as an array of data block structures. + * + * @details: Performs 128-bit AES encryption on multiple data blocks + * + * @note: + * - The application may set the SEVONPEND bit in the SCR to 1 to make the SoftDevice sleep while + * the ECB is running. The SEVONPEND bit should only be cleared (set to 0) from application + * main or low interrupt level. + * + * @param[in] block_count Count of blocks in the p_data_blocks array. + * @param[in,out] p_data_blocks Pointer to the first entry in a contiguous array of + * @ref nrf_ecb_hal_data_block_t structures. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_ECB_BLOCKS_ENCRYPT, uint32_t, sd_ecb_blocks_encrypt(uint8_t block_count, nrf_ecb_hal_data_block_t *p_data_blocks)); + +/**@brief Gets any pending events generated by the SoC API. + * + * The application should keep calling this function to get events, until ::NRF_ERROR_NOT_FOUND is returned. + * + * @param[out] p_evt_id Set to one of the values in @ref NRF_SOC_EVTS, if any events are pending. + * + * @retval ::NRF_SUCCESS An event was pending. The event id is written in the p_evt_id parameter. + * @retval ::NRF_ERROR_NOT_FOUND No pending events. + */ +SVCALL(SD_EVT_GET, uint32_t, sd_evt_get(uint32_t *p_evt_id)); + +/**@brief Get the temperature measured on the chip + * + * This function will block until the temperature measurement is done. + * It takes around 50 us from call to return. + * + * @param[out] p_temp Result of temperature measurement. Die temperature in 0.25 degrees Celsius. + * + * @retval ::NRF_SUCCESS A temperature measurement was done, and the temperature was written to temp + */ +SVCALL(SD_TEMP_GET, uint32_t, sd_temp_get(int32_t *p_temp)); + +/**@brief Flash Write + * + * Commands to write a buffer to flash + * + * If the SoftDevice is enabled: + * This call initiates the flash access command, and its completion will be communicated to the + * application with exactly one of the following events: + * - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed. + * - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started. + * + * If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the + * write has been completed + * + * @note + * - This call takes control over the radio and the CPU during flash erase and write to make sure that + * they will not interfere with the flash access. This means that all interrupts will be blocked + * for a predictable time (depending on the NVMC specification in the device's Product Specification + * and the command parameters). + * - The data in the p_src buffer should not be modified before the @ref NRF_EVT_FLASH_OPERATION_SUCCESS + * or the @ref NRF_EVT_FLASH_OPERATION_ERROR have been received if the SoftDevice is enabled. + * - This call will make the SoftDevice trigger a hardfault when the page is written, if it is + * protected. + * + * + * @param[in] p_dst Pointer to start of flash location to be written. + * @param[in] p_src Pointer to buffer with data to be written. + * @param[in] size Number of 32-bit words to write. Maximum size is the number of words in one + * flash page. See the device's Product Specification for details. + * + * @retval ::NRF_ERROR_INVALID_ADDR Tried to write to a non existing flash address, or p_dst or p_src was unaligned. + * @retval ::NRF_ERROR_BUSY The previous command has not yet completed. + * @retval ::NRF_ERROR_INVALID_LENGTH Size was 0, or higher than the maximum allowed size. + * @retval ::NRF_ERROR_FORBIDDEN Tried to write to an address outside the application flash area. + * @retval ::NRF_SUCCESS The command was accepted. + */ +SVCALL(SD_FLASH_WRITE, uint32_t, sd_flash_write(uint32_t *p_dst, uint32_t const *p_src, uint32_t size)); + +/**@brief Flash Erase page + * + * Commands to erase a flash page + * If the SoftDevice is enabled: + * This call initiates the flash access command, and its completion will be communicated to the + * application with exactly one of the following events: + * - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed. + * - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started. + * + * If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the + * erase has been completed + * + * @note + * - This call takes control over the radio and the CPU during flash erase and write to make sure that + * they will not interfere with the flash access. This means that all interrupts will be blocked + * for a predictable time (depending on the NVMC specification in the device's Product Specification + * and the command parameters). + * - This call will make the SoftDevice trigger a hardfault when the page is erased, if it is + * protected. + * + * + * @param[in] page_number Page number of the page to erase + * + * @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error. + * @retval ::NRF_ERROR_INVALID_ADDR Tried to erase to a non existing flash page. + * @retval ::NRF_ERROR_BUSY The previous command has not yet completed. + * @retval ::NRF_ERROR_FORBIDDEN Tried to erase a page outside the application flash area. + * @retval ::NRF_SUCCESS The command was accepted. + */ +SVCALL(SD_FLASH_PAGE_ERASE, uint32_t, sd_flash_page_erase(uint32_t page_number)); + +/**@brief Opens a session for radio timeslot requests. + * + * @note Only one session can be open at a time. + * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) will be called when the radio timeslot + * starts. From this point the NRF_RADIO and NRF_TIMER0 peripherals can be freely accessed + * by the application. + * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0) is called whenever the NRF_TIMER0 + * interrupt occurs. + * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO) is called whenever the NRF_RADIO + * interrupt occurs. + * @note p_radio_signal_callback() will be called at ARM interrupt priority level 0. This + * implies that none of the sd_* API calls can be used from p_radio_signal_callback(). + * + * @param[in] p_radio_signal_callback The signal callback. + * + * @retval ::NRF_ERROR_INVALID_ADDR p_radio_signal_callback is an invalid function pointer. + * @retval ::NRF_ERROR_BUSY If session cannot be opened. + * @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error. + * @retval ::NRF_SUCCESS Otherwise. + */ +SVCALL(SD_RADIO_SESSION_OPEN, uint32_t, sd_radio_session_open(nrf_radio_signal_callback_t p_radio_signal_callback)); + +/**@brief Closes a session for radio timeslot requests. + * + * @note Any current radio timeslot will be finished before the session is closed. + * @note If a radio timeslot is scheduled when the session is closed, it will be canceled. + * @note The application cannot consider the session closed until the @ref NRF_EVT_RADIO_SESSION_CLOSED + * event is received. + * + * @retval ::NRF_ERROR_FORBIDDEN If session not opened. + * @retval ::NRF_ERROR_BUSY If session is currently being closed. + * @retval ::NRF_SUCCESS Otherwise. + */ +SVCALL(SD_RADIO_SESSION_CLOSE, uint32_t, sd_radio_session_close(void)); + +/**@brief Requests a radio timeslot. + * + * @note The request type is determined by p_request->request_type, and can be one of @ref NRF_RADIO_REQ_TYPE_EARLIEST + * and @ref NRF_RADIO_REQ_TYPE_NORMAL. The first request in a session must always be of type @ref + * NRF_RADIO_REQ_TYPE_EARLIEST. + * @note For a normal request (@ref NRF_RADIO_REQ_TYPE_NORMAL), the start time of a radio timeslot is specified by + * p_request->distance_us and is given relative to the start of the previous timeslot. + * @note A too small p_request->distance_us will lead to a @ref NRF_EVT_RADIO_BLOCKED event. + * @note Timeslots scheduled too close will lead to a @ref NRF_EVT_RADIO_BLOCKED event. + * @note See the SoftDevice Specification for more on radio timeslot scheduling, distances and lengths. + * @note If an opportunity for the first radio timeslot is not found before 100 ms after the call to this + * function, it is not scheduled, and instead a @ref NRF_EVT_RADIO_BLOCKED event is sent. + * The application may then try to schedule the first radio timeslot again. + * @note Successful requests will result in nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START). + * Unsuccessful requests will result in a @ref NRF_EVT_RADIO_BLOCKED event, see @ref NRF_SOC_EVTS. + * @note The jitter in the start time of the radio timeslots is +/- @ref NRF_RADIO_START_JITTER_US us. + * @note The nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) call has a latency relative to the + * specified radio timeslot start, but this does not affect the actual start time of the timeslot. + * @note NRF_TIMER0 is reset at the start of the radio timeslot, and is clocked at 1MHz from the high frequency + * (16 MHz) clock source. If p_request->hfclk_force_xtal is true, the high frequency clock is + * guaranteed to be clocked from the external crystal. + * @note The SoftDevice will neither access the NRF_RADIO peripheral nor the NRF_TIMER0 peripheral + * during the radio timeslot. + * + * @param[in] p_request Pointer to the request parameters. + * + * @retval ::NRF_ERROR_FORBIDDEN Either: + * - The session is not open. + * - The session is not IDLE. + * - This is the first request and its type is not @ref NRF_RADIO_REQ_TYPE_EARLIEST. + * - The request type was set to @ref NRF_RADIO_REQ_TYPE_NORMAL after a + * @ref NRF_RADIO_REQ_TYPE_EARLIEST request was blocked. + * @retval ::NRF_ERROR_INVALID_ADDR If the p_request pointer is invalid. + * @retval ::NRF_ERROR_INVALID_PARAM If the parameters of p_request are not valid. + * @retval ::NRF_SUCCESS Otherwise. + */ +SVCALL(SD_RADIO_REQUEST, uint32_t, sd_radio_request(nrf_radio_request_t const *p_request)); + +/**@brief Write register protected by the SoftDevice + * + * This function writes to a register that is write-protected by the SoftDevice. Please refer to your + * SoftDevice Specification for more details about which registers that are protected by SoftDevice. + * This function can write to the following protected peripheral: + * - ACL + * + * @note Protected registers may be read directly. + * @note Register that are write-once will return @ref NRF_SUCCESS on second set, even the value in + * the register has not changed. See the Product Specification for more details about register + * properties. + * + * @param[in] p_register Pointer to register to be written. + * @param[in] value Value to be written to the register. + * + * @retval ::NRF_ERROR_INVALID_ADDR This function can not write to the reguested register. + * @retval ::NRF_SUCCESS Value successfully written to register. + * + */ +SVCALL(SD_PROTECTED_REGISTER_WRITE, uint32_t, sd_protected_register_write(volatile uint32_t *p_register, uint32_t value)); + +/**@} */ + +#ifdef __cplusplus +} +#endif +#endif // NRF_SOC_H__ + +/**@} */ diff --git a/variants/xiao_ble/softdevice/nrf_svc.h b/variants/xiao_ble/softdevice/nrf_svc.h new file mode 100644 index 000000000..1de44656f --- /dev/null +++ b/variants/xiao_ble/softdevice/nrf_svc.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef NRF_SVC__ +#define NRF_SVC__ + +#include "stdint.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Supervisor call declaration. + * + * A call to a function marked with @ref SVCALL, will trigger a Supervisor Call (SVC) Exception. + * The SVCs with SVC numbers 0x00-0x0F are forwared to the application. All other SVCs are handled by the SoftDevice. + * + * @param[in] number The SVC number to be used. + * @param[in] return_type The return type of the SVC function. + * @param[in] signature Function signature. The function can have at most four arguments. + */ + +#ifdef SVCALL_AS_NORMAL_FUNCTION +#define SVCALL(number, return_type, signature) return_type signature +#else + +#ifndef SVCALL +#if defined(__CC_ARM) +#define SVCALL(number, return_type, signature) return_type __svc(number) signature +#elif defined(__GNUC__) +#ifdef __cplusplus +#define GCC_CAST_CPP (uint16_t) +#else +#define GCC_CAST_CPP +#endif +#define SVCALL(number, return_type, signature) \ + _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") __attribute__((naked)) \ + __attribute__((unused)) static return_type signature \ + { \ + __asm("svc %0\n" \ + "bx r14" \ + : \ + : "I"(GCC_CAST_CPP number) \ + : "r0"); \ + } \ + _Pragma("GCC diagnostic pop") + +#elif defined(__ICCARM__) +#define PRAGMA(x) _Pragma(#x) +#define SVCALL(number, return_type, signature) \ + PRAGMA(swi_number = (number)) \ + __swi return_type signature; +#else +#define SVCALL(number, return_type, signature) return_type signature +#endif +#endif // SVCALL + +#endif // SVCALL_AS_NORMAL_FUNCTION + +#ifdef __cplusplus +} +#endif +#endif // NRF_SVC__ From da5bca31edcd091b33d1e6b9b35ea6f807850eb0 Mon Sep 17 00:00:00 2001 From: todd-herbert Date: Sat, 8 Jun 2024 02:41:46 +1200 Subject: [PATCH 48/80] Triple-press not disabling GPS (#4041) * Replace (bool) isAwake with an enum, to track standby states * Tidy-up, extra logging * Rename enum values * Reorder GPSPowerState enum Possibly more intuitive when reading logs * Avoid lego comments https://github.com/meshtastic/firmware/pull/4041/files/de22c57298535f8b94154bffbef64a44af09648c#r1627334779 --- src/gps/GPS.cpp | 74 ++++++++++++++++++++++++++++++++++--------------- src/gps/GPS.h | 10 +++++-- 2 files changed, 59 insertions(+), 25 deletions(-) diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 4335244f0..17088910a 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -21,6 +21,13 @@ #define GPS_RESET_MODE HIGH #endif +// How many minutes of sleep make it worthwhile to power-off the GPS +// Shorter than this, and GPS will only enter standby +// Affected by lock-time, and config.position.gps_update_interval +#ifndef GPS_STANDBY_THRESHOLD_MINUTES +#define GPS_STANDBY_THRESHOLD_MINUTES 15 +#endif + #if defined(NRF52840_XXAA) || defined(NRF52833_XXAA) || defined(ARCH_ESP32) || defined(ARCH_PORTDUINO) HardwareSerial *GPS::_serial_gps = &Serial1; #else @@ -767,7 +774,16 @@ GPS::~GPS() void GPS::setGPSPower(bool on, bool standbyOnly, uint32_t sleepTime) { - LOG_INFO("Setting GPS power=%d\n", on); + // Record the current powerState + if (on) + powerState = GPS_AWAKE; + else if (!on && standbyOnly) + powerState = GPS_STANDBY; + else + powerState = GPS_OFF; + + LOG_DEBUG("GPS::powerState=%d\n", powerState); + if (on) { clearBuffer(); // drop any old data waiting in the buffer before re-enabling if (en_gpio) @@ -861,17 +877,21 @@ void GPS::setConnected() * * calls sleep/wake */ -void GPS::setAwake(bool on) +void GPS::setAwake(bool wantAwake) { - if (isAwake != on) { - LOG_DEBUG("WANT GPS=%d\n", on); - isAwake = on; - if (!enabled) { // short circuit if the user has disabled GPS - setGPSPower(false, false, 0); - return; - } - if (on) { + // If user has disabled GPS, make sure it is off, not just in standby + if (!wantAwake && !enabled && powerState != GPS_OFF) { + setGPSPower(false, false, 0); + return; + } + + // If GPS power state needs to change + if ((wantAwake && powerState != GPS_AWAKE) || (!wantAwake && powerState == GPS_AWAKE)) { + LOG_DEBUG("WANT GPS=%d\n", wantAwake); + + // Calculate how long it takes to get a GPS lock + if (wantAwake) { lastWakeStartMsec = millis(); } else { lastSleepStartMsec = millis(); @@ -883,23 +903,31 @@ void GPS::setAwake(bool on) GPSCycles++; LOG_DEBUG("GPS Lock took %d, average %d\n", (lastSleepStartMsec - lastWakeStartMsec) / 1000, averageLockTime / 1000); } - if ((int32_t)getSleepTime() - averageLockTime > - 15 * 60 * 1000) { // 15 minutes is probably long enough to make a complete poweroff worth it. - setGPSPower(on, false, getSleepTime() - averageLockTime); + + // If long interval between updates: power off between updates + if ((int32_t)getSleepTime() - averageLockTime > GPS_STANDBY_THRESHOLD_MINUTES * MS_IN_MINUTE) { + setGPSPower(wantAwake, false, getSleepTime() - averageLockTime); return; - } else if ((int32_t)getSleepTime() - averageLockTime > 10000) { // 10 seconds is enough for standby + } + + // If waking frequently: standby only. Would use more power trying to reacquire lock each time + else if ((int32_t)getSleepTime() - averageLockTime > 10000) { // 10 seconds is enough for standby #ifdef GPS_UC6580 - setGPSPower(on, false, getSleepTime() - averageLockTime); + setGPSPower(wantAwake, false, getSleepTime() - averageLockTime); #else - setGPSPower(on, true, getSleepTime() - averageLockTime); + setGPSPower(wantAwake, true, getSleepTime() - averageLockTime); #endif return; } + + // Gradually recover from an abnormally long "time to get lock" if (averageLockTime > 20000) { averageLockTime -= 1000; // eventually want to sleep again. } - if (on) - setGPSPower(true, true, 0); // make sure we don't have a fallthrough where GPS is stuck off + + // Make sure we don't have a fallthrough where GPS is stuck off + if (wantAwake) + setGPSPower(true, true, 0); } } @@ -1005,14 +1033,14 @@ int32_t GPS::runOnce() uint32_t timeAsleep = now - lastSleepStartMsec; auto sleepTime = getSleepTime(); - if (!isAwake && (sleepTime != UINT32_MAX) && + if (powerState != GPS_AWAKE && (sleepTime != UINT32_MAX) && ((timeAsleep > sleepTime) || (isInPowersave && timeAsleep > (sleepTime - averageLockTime)))) { // We now want to be awake - so wake up the GPS setAwake(true); } // While we are awake - if (isAwake) { + if (powerState == GPS_AWAKE) { // LOG_DEBUG("looking for location\n"); // If we've already set time from the GPS, no need to ask the GPS bool gotTime = (getRTCQuality() >= RTCQualityGPS); @@ -1058,7 +1086,7 @@ int32_t GPS::runOnce() // 9600bps is approx 1 byte per msec, so considering our buffer size we never need to wake more often than 200ms // if not awake we can run super infrquently (once every 5 secs?) to see if we need to wake. - return isAwake ? GPS_THREAD_INTERVAL : 5000; + return (powerState == GPS_AWAKE) ? GPS_THREAD_INTERVAL : 5000; } // clear the GPS rx buffer as quickly as possible @@ -1589,9 +1617,9 @@ bool GPS::whileIdle() { unsigned int charsInBuf = 0; bool isValid = false; - if (!isAwake) { + if (powerState != GPS_AWAKE) { clearBuffer(); - return isAwake; + return (powerState == GPS_AWAKE); } #ifdef SERIAL_BUFFER_SIZE if (_serial_gps->available() >= SERIAL_BUFFER_SIZE - 1) { diff --git a/src/gps/GPS.h b/src/gps/GPS.h index 77c6c0269..e9ec111a7 100644 --- a/src/gps/GPS.h +++ b/src/gps/GPS.h @@ -38,6 +38,12 @@ typedef enum { GNSS_RESPONSE_OK, } GPS_RESPONSE; +enum GPSPowerState : uint8_t { + GPS_OFF = 0, + GPS_AWAKE = 1, + GPS_STANDBY = 2, +}; + // Generate a string representation of DOP const char *getDOPString(uint32_t dop); @@ -78,8 +84,6 @@ class GPS : private concurrency::OSThread */ bool hasValidLocation = false; // default to false, until we complete our first read - bool isAwake = false; // true if we want a location right now - bool isInPowersave = false; bool shouldPublish = false; // If we've changed GPS state, this will force a publish the next loop() @@ -89,6 +93,8 @@ class GPS : private concurrency::OSThread bool GPSInitFinished = false; // Init thread finished? bool GPSInitStarted = false; // Init thread finished? + GPSPowerState powerState = GPS_OFF; // GPS_AWAKE if we want a location right now + uint8_t numSatellites = 0; CallbackObserver notifyDeepSleepObserver = CallbackObserver(this, &GPS::prepareDeepSleep); From 2fa55b7b6f799fbb294fece500c7c73d2af3d4cc Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Sat, 8 Jun 2024 09:44:13 -0500 Subject: [PATCH 49/80] Remove bandit from extra --- variants/radiomaster_900_bandit_nano/platformio.ini | 1 - 1 file changed, 1 deletion(-) diff --git a/variants/radiomaster_900_bandit_nano/platformio.ini b/variants/radiomaster_900_bandit_nano/platformio.ini index d83c14de2..0d43b8665 100644 --- a/variants/radiomaster_900_bandit_nano/platformio.ini +++ b/variants/radiomaster_900_bandit_nano/platformio.ini @@ -1,7 +1,6 @@ [env:radiomaster_900_bandit_nano] extends = esp32_base board = esp32doit-devkit-v1 -board_level = extra build_flags = ${esp32_base.build_flags} -DRADIOMASTER_900_BANDIT_NANO From 2335352fbe874e212cfebfd71f76745eb53512c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Sun, 9 Jun 2024 12:30:47 +0200 Subject: [PATCH 50/80] fix native build --- .github/workflows/main_matrix.yml | 75 +------------------------------ 1 file changed, 1 insertion(+), 74 deletions(-) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index 800c18b89..ed7f02b3b 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -112,79 +112,6 @@ jobs: package-native: uses: ./.github/workflows/package_amd64.yml - build-native: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Build base - id: base - uses: ./.github/actions/setup-base - - # We now run integration test before other build steps (to quickly see runtime failures) - #- name: Build for native - # run: platformio run -e native - #- name: Integration test - # run: | - #.pio/build/native/program - #& sleep 20 # 5 seconds was not enough - #echo "Simulator started, launching python test..." - #python3 -c 'from meshtastic.test import testSimulator; testSimulator()' - - - name: Build Native - run: bin/build-native.sh - - - name: Get release version string - run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT - id: version - - - name: Store binaries as an artifact - uses: actions/upload-artifact@v4 - with: - name: firmware-native-${{ steps.version.outputs.version }}.zip - overwrite: true - path: | - release/device-*.sh - release/device-*.bat - release/meshtasticd_linux* - - - name: Docker login - if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }} - uses: docker/login-action@v3 - with: - username: meshtastic - password: ${{ secrets.DOCKER_TOKEN }} - - name: Docker setup - if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }} - uses: docker/setup-buildx-action@v3 - - - name: Docker build and push tagged versions - if: ${{ github.event_name == 'workflow_dispatch' }} - uses: docker/build-push-action@v5 - with: - context: . - file: ./Dockerfile - push: true - tags: meshtastic/device-simulator:${{ steps.version.outputs.version }} - - - name: Docker build and push - if: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }} - uses: docker/build-push-action@v5 - with: - context: . - file: ./Dockerfile - push: true - tags: meshtastic/device-simulator:latest - - after-checks: - runs-on: ubuntu-latest - needs: [check] - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - ref: ${{github.event.pull_request.head.ref}} - repository: ${{github.event.pull_request.head.repo.full_name}} - gather-artifacts: permissions: contents: write @@ -196,10 +123,10 @@ jobs: build-esp32-s3, build-esp32-c3, build-nrf52, - build-native, build-rpi2040, package-raspbian, package-raspbian-armv7l, + package-native, ] steps: - name: Checkout code From 27ad3da0ac0157907259ca3ab70f81b6a17bd463 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Sun, 9 Jun 2024 12:37:23 +0200 Subject: [PATCH 51/80] reinstate after checks and hope the coffee kicks in --- .github/workflows/main_matrix.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index ed7f02b3b..702a7875e 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -112,6 +112,16 @@ jobs: package-native: uses: ./.github/workflows/package_amd64.yml + after-checks: + runs-on: ubuntu-latest + needs: [check] + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + ref: ${{github.event.pull_request.head.ref}} + repository: ${{github.event.pull_request.head.repo.full_name}} + gather-artifacts: permissions: contents: write @@ -126,7 +136,7 @@ jobs: build-rpi2040, package-raspbian, package-raspbian-armv7l, - package-native, + package-native ] steps: - name: Checkout code From 46b8e2a850bbfcfa804efd0f5ff292e59ecec47f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Sun, 9 Jun 2024 12:56:44 +0200 Subject: [PATCH 52/80] fix binary location --- .github/workflows/package_amd64.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/package_amd64.yml b/.github/workflows/package_amd64.yml index 7a5efd154..ae7bf3242 100644 --- a/.github/workflows/package_amd64.yml +++ b/.github/workflows/package_amd64.yml @@ -53,7 +53,7 @@ jobs: mkdir -p .debpkg/usr/lib/systemd/system/ tar -xf build.tar -C .debpkg/usr/share/doc/meshtasticd/web gunzip .debpkg/usr/share/doc/meshtasticd/web/*.gz - cp meshtasticd_linux_x86_64 .debpkg/usr/sbin/meshtasticd + cp release/meshtasticd_linux_x86_64 .debpkg/usr/sbin/meshtasticd cp bin/config-dist.yaml .debpkg/etc/meshtasticd/config.yaml chmod +x .debpkg/usr/sbin/meshtasticd cp bin/meshtasticd.service .debpkg/usr/lib/systemd/system/meshtasticd.service From 095887de4043eaae3ab12f2875446b1d5f1dcba0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Sun, 9 Jun 2024 13:00:06 +0200 Subject: [PATCH 53/80] do the docker dance --- .github/workflows/build_native.yml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/.github/workflows/build_native.yml b/.github/workflows/build_native.yml index 257bc4176..b92e77ef2 100644 --- a/.github/workflows/build_native.yml +++ b/.github/workflows/build_native.yml @@ -50,3 +50,32 @@ jobs: path: | release/meshtasticd_linux_x86_64 bin/config-dist.yaml + + - name: Docker login + if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }} + uses: docker/login-action@v3 + with: + username: meshtastic + password: ${{ secrets.DOCKER_TOKEN }} + + - name: Docker setup + if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }} + uses: docker/setup-buildx-action@v3 + + - name: Docker build and push tagged versions + if: ${{ github.event_name == 'workflow_dispatch' }} + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile + push: true + tags: meshtastic/device-simulator:${{ steps.version.outputs.version }} + + - name: Docker build and push + if: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }} + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile + push: true + tags: meshtastic/device-simulator:latest From f59cbc8ffbb9d32e992d4d357fe245ed36d3b4a4 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Sun, 9 Jun 2024 07:19:25 -0500 Subject: [PATCH 54/80] Add firmware repo level secret --- .github/workflows/build_native.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_native.yml b/.github/workflows/build_native.yml index b92e77ef2..ff0c2eaf6 100644 --- a/.github/workflows/build_native.yml +++ b/.github/workflows/build_native.yml @@ -56,7 +56,7 @@ jobs: uses: docker/login-action@v3 with: username: meshtastic - password: ${{ secrets.DOCKER_TOKEN }} + password: ${{ secrets.DOCKER_FIRMWARE_TOKEN }} - name: Docker setup if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }} From 2f99a8dbb8c578987d3bf279db84dd0a065b26c9 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Sun, 9 Jun 2024 07:40:57 -0500 Subject: [PATCH 55/80] Try latest version --- .github/workflows/build_native.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_native.yml b/.github/workflows/build_native.yml index ff0c2eaf6..f7c83eddb 100644 --- a/.github/workflows/build_native.yml +++ b/.github/workflows/build_native.yml @@ -53,7 +53,7 @@ jobs: - name: Docker login if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }} - uses: docker/login-action@v3 + uses: docker/login-action@v3.2.0 with: username: meshtastic password: ${{ secrets.DOCKER_FIRMWARE_TOKEN }} From 4da3f202e516ba0b1c3d772957c36a783e3876ef Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Sun, 9 Jun 2024 07:55:45 -0500 Subject: [PATCH 56/80] Roll-back to v2 --- .github/workflows/build_native.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_native.yml b/.github/workflows/build_native.yml index f7c83eddb..115f85bbe 100644 --- a/.github/workflows/build_native.yml +++ b/.github/workflows/build_native.yml @@ -53,7 +53,7 @@ jobs: - name: Docker login if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }} - uses: docker/login-action@v3.2.0 + uses: docker/login-action@v2.2.0 with: username: meshtastic password: ${{ secrets.DOCKER_FIRMWARE_TOKEN }} From 01a214aa5967924af814ca76c4bdcdf2ce41b1b3 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Sun, 9 Jun 2024 08:32:31 -0500 Subject: [PATCH 57/80] Add continues on failing docker steps --- .github/workflows/build_native.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_native.yml b/.github/workflows/build_native.yml index 115f85bbe..8fe8e6c31 100644 --- a/.github/workflows/build_native.yml +++ b/.github/workflows/build_native.yml @@ -53,17 +53,20 @@ jobs: - name: Docker login if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }} - uses: docker/login-action@v2.2.0 + uses: docker/login-action@v3 + continue-on-error: true # FIXME: Failing docker login auth with: username: meshtastic password: ${{ secrets.DOCKER_FIRMWARE_TOKEN }} - name: Docker setup if: ${{ github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }} + continue-on-error: true # FIXME: Failing docker login auth uses: docker/setup-buildx-action@v3 - name: Docker build and push tagged versions if: ${{ github.event_name == 'workflow_dispatch' }} + continue-on-error: true # FIXME: Failing docker login auth uses: docker/build-push-action@v5 with: context: . @@ -73,6 +76,7 @@ jobs: - name: Docker build and push if: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request_target' && github.event_name != 'pull_request' }} + continue-on-error: true # FIXME: Failing docker login auth uses: docker/build-push-action@v5 with: context: . From 1d98e48bab8d47b3ec4f3f5547ec9d565a523d9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Sun, 9 Jun 2024 16:33:50 +0200 Subject: [PATCH 58/80] Update main_matrix.yml --- .github/workflows/main_matrix.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index 702a7875e..89b71acb8 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -158,7 +158,7 @@ jobs: id: version - name: Move files up - run: mv -b -t ./ ./release/meshtasticd_linux_* ./bin/config-dist.yaml + run: mv -b -t ./ ./release/meshtasticd_linux_* ./bin/config-dist.yaml ./bin/device-*.sh ./bin/device-*.bat - name: Repackage in single firmware zip uses: actions/upload-artifact@v4 From 237944aaf05e0b48369d6c9577864ddbd1662f7d Mon Sep 17 00:00:00 2001 From: GUVWAF <78759985+GUVWAF@users.noreply.github.com> Date: Sun, 9 Jun 2024 23:02:52 +0200 Subject: [PATCH 59/80] Avoid assert on receiving undecryptable packet (#4059) * Send NAK on primary if original packet couldn't be decoded * Add checks for `isDecoded` when accessing `decoded` * Channel index should be of original packet, not of newly allocated NAK --- src/mesh/MeshModule.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/mesh/MeshModule.cpp b/src/mesh/MeshModule.cpp index 2ef46e4db..04fa250bf 100644 --- a/src/mesh/MeshModule.cpp +++ b/src/mesh/MeshModule.cpp @@ -62,7 +62,10 @@ meshtastic_MeshPacket *MeshModule::allocAckNak(meshtastic_Routing_Error err, Nod meshtastic_MeshPacket *MeshModule::allocErrorResponse(meshtastic_Routing_Error err, const meshtastic_MeshPacket *p) { - auto r = allocAckNak(err, getFrom(p), p->id, p->channel); + // If the original packet couldn't be decoded, use the primary channel + uint8_t channelIndex = + p->which_payload_variant == meshtastic_MeshPacket_decoded_tag ? p->channel : channels.getPrimaryIndex(); + auto r = allocAckNak(err, getFrom(p), p->id, channelIndex); setReplyTo(r, *p); @@ -114,13 +117,13 @@ void MeshModule::callModules(meshtastic_MeshPacket &mp, RxSource src) /// Also: if a packet comes in on the local PC interface, we don't check for bound channels, because it is TRUSTED and /// it needs to to be able to fetch the initial admin packets without yet knowing any channels. - bool rxChannelOk = !pi.boundChannel || (mp.from == 0) || (strcasecmp(ch->settings.name, pi.boundChannel) == 0); + bool rxChannelOk = !pi.boundChannel || (mp.from == 0) || (ch && strcasecmp(ch->settings.name, pi.boundChannel) == 0); if (!rxChannelOk) { // no one should have already replied! assert(!currentReply); - if (mp.decoded.want_response) { + if (isDecoded && mp.decoded.want_response) { printPacket("packet on wrong channel, returning error", &mp); currentReply = pi.allocErrorResponse(meshtastic_Routing_Error_NOT_AUTHORIZED, &mp); } else @@ -138,7 +141,8 @@ void MeshModule::callModules(meshtastic_MeshPacket &mp, RxSource src) // because currently when the phone sends things, it sends things using the local node ID as the from address. A // better solution (FIXME) would be to let phones have their own distinct addresses and we 'route' to them like // any other node. - if (mp.decoded.want_response && toUs && (getFrom(&mp) != ourNodeNum || mp.to == ourNodeNum) && !currentReply) { + if (isDecoded && mp.decoded.want_response && toUs && (getFrom(&mp) != ourNodeNum || mp.to == ourNodeNum) && + !currentReply) { pi.sendResponse(mp); ignoreRequest = ignoreRequest || pi.ignoreRequest; // If at least one module asks it, we may ignore a request LOG_INFO("Asked module '%s' to send a response\n", pi.name); @@ -163,7 +167,7 @@ void MeshModule::callModules(meshtastic_MeshPacket &mp, RxSource src) pi.currentRequest = NULL; } - if (mp.decoded.want_response && toUs) { + if (isDecoded && mp.decoded.want_response && toUs) { if (currentReply) { printPacket("Sending response", currentReply); service.sendToMesh(currentReply); @@ -183,7 +187,7 @@ void MeshModule::callModules(meshtastic_MeshPacket &mp, RxSource src) } } - if (!moduleFound) { + if (!moduleFound && isDecoded) { LOG_DEBUG("No modules interested in portnum=%d, src=%s\n", mp.decoded.portnum, (src == RX_SRC_LOCAL) ? "LOCAL" : "REMOTE"); } From a2fb3d23a1545b80d480208d5df917bbf179bb95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gjels=C3=B8?= <36234524+gjelsoe@users.noreply.github.com> Date: Sun, 9 Jun 2024 23:03:39 +0200 Subject: [PATCH 60/80] Radio Master 900 Bandit Nano Power output interpolation (#4057) * DAC and DB values based on dBm using interpolation * Moved getDACandDB funtion Moved getDACandDB funtion up so it won't conflict with RF95_MAX_POWER * Added DAC output to LOG_INFO Added DAC output to LOG_INFO * Make Trunk Happy --- src/mesh/RF95Interface.cpp | 64 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 3 deletions(-) diff --git a/src/mesh/RF95Interface.cpp b/src/mesh/RF95Interface.cpp index 5677e6eda..c5356ad3b 100644 --- a/src/mesh/RF95Interface.cpp +++ b/src/mesh/RF95Interface.cpp @@ -17,6 +17,48 @@ // if you set power to something higher than 17 or 20 you might fry your board. #define POWER_DEFAULT 17 // How much power to use if the user hasn't set a power level +#ifdef RADIOMASTER_900_BANDIT_NANO +// Structure to hold DAC and DB values +typedef struct { + uint8_t dac; + uint8_t db; +} DACDB; + +// Interpolation function +DACDB interpolate(uint8_t dbm, uint8_t dbm1, uint8_t dbm2, DACDB val1, DACDB val2) { + DACDB result; + double fraction = (double)(dbm - dbm1) / (dbm2 - dbm1); + result.dac = (uint8_t)(val1.dac + fraction * (val2.dac - val1.dac)); + result.db = (uint8_t)(val1.db + fraction * (val2.db - val1.db)); + return result; +} + +// Function to find the correct DAC and DB values based on dBm using interpolation +DACDB getDACandDB(uint8_t dbm) { + // Predefined values + static const struct { + uint8_t dbm; + DACDB values; + } dbmToDACDB[] = { + {20, {168, 2}}, // 100mW + {24, {148, 6}}, // 250mW + {27, {128, 9}}, // 500mW + {30, {90, 12}} // 1000mW + }; + const int numValues = sizeof(dbmToDACDB) / sizeof(dbmToDACDB[0]); + + // Find the interval dbm falls within and interpolate + for (int i = 0; i < numValues - 1; i++) { + if (dbm >= dbmToDACDB[i].dbm && dbm <= dbmToDACDB[i + 1].dbm) { + return interpolate(dbm, dbmToDACDB[i].dbm, dbmToDACDB[i + 1].dbm, dbmToDACDB[i].values, dbmToDACDB[i + 1].values); + } + } + + // Return a default value if no match is found and default to 100mW + DACDB defaultValue = {168, 2}; + return defaultValue; +} +#endif RF95Interface::RF95Interface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst, RADIOLIB_PIN_TYPE busy) @@ -52,9 +94,16 @@ bool RF95Interface::init() { RadioLibInterface::init(); +#ifdef RADIOMASTER_900_BANDIT_NANO + // DAC and DB values based on dBm using interpolation + DACDB dacDbValues = getDACandDB(power); + int8_t powerDAC = dacDbValues.dac; + power = dacDbValues.db; +#endif + if (power > RF95_MAX_POWER) // This chip has lower power limits than some power = RF95_MAX_POWER; - + limitPower(); iface = lora = new RadioLibRF95(&module); @@ -67,7 +116,13 @@ bool RF95Interface::init() // enable PA #ifdef RF95_PA_EN #if defined(RF95_PA_DAC_EN) - dacWrite(RF95_PA_EN, RF95_PA_LEVEL); + #ifdef RADIOMASTER_900_BANDIT_NANO + // Use calculated DAC value + dacWrite(RF95_PA_EN, powerDAC); + #else + // Use Value set in /*/variant.h + dacWrite(RF95_PA_EN, RF95_PA_LEVEL); + #endif #endif #endif @@ -107,6 +162,9 @@ bool RF95Interface::init() LOG_INFO("Frequency set to %f\n", getFreq()); LOG_INFO("Bandwidth set to %f\n", bw); LOG_INFO("Power output set to %d\n", power); +#ifdef RADIOMASTER_900_BANDIT_NANO + LOG_INFO("DAC output set to %d\n", powerDAC); +#endif if (res == RADIOLIB_ERR_NONE) res = lora->setCRC(RADIOLIB_SX126X_LORA_CRC_ON); @@ -259,4 +317,4 @@ bool RF95Interface::sleep() #endif return true; -} \ No newline at end of file +} From 24458a73d6cbdba9f4d731eb0be3f07ffd0973f1 Mon Sep 17 00:00:00 2001 From: GUVWAF <78759985+GUVWAF@users.noreply.github.com> Date: Sun, 9 Jun 2024 23:03:53 +0200 Subject: [PATCH 61/80] Add missing hops in traceroute as "unkown" (#4056) E.g. in case a node couldn't decrypt the packet --- src/modules/TraceRouteModule.cpp | 28 ++++++++++++++++++++++++---- src/modules/TraceRouteModule.h | 3 +++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/modules/TraceRouteModule.cpp b/src/modules/TraceRouteModule.cpp index aa0b6a1eb..f390aafcd 100644 --- a/src/modules/TraceRouteModule.cpp +++ b/src/modules/TraceRouteModule.cpp @@ -16,17 +16,37 @@ bool TraceRouteModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, m void TraceRouteModule::alterReceivedProtobuf(meshtastic_MeshPacket &p, meshtastic_RouteDiscovery *r) { auto &incoming = p.decoded; - // Only append an ID for the request (one way) and if we are not the destination (the reply will have our NodeNum already) - if (!incoming.request_id && p.to != nodeDB->getNodeNum()) { - appendMyID(r); - printRoute(r, p.from, NODENUM_BROADCAST); + // Only append IDs for the request (one way) + if (!incoming.request_id) { + // Insert unknown hops if necessary + insertUnknownHops(p, r); + // Don't add ourselves if we are the destination (the reply will have our NodeNum already) + if (p.to != nodeDB->getNodeNum()) { + appendMyID(r); + printRoute(r, p.from, NODENUM_BROADCAST); + } // Set updated route to the payload of the to be flooded packet p.decoded.payload.size = pb_encode_to_bytes(p.decoded.payload.bytes, sizeof(p.decoded.payload.bytes), &meshtastic_RouteDiscovery_msg, r); } } +void TraceRouteModule::insertUnknownHops(meshtastic_MeshPacket &p, meshtastic_RouteDiscovery *r) +{ + // Only insert unknown hops if hop_start is valid + if (p.hop_start != 0 && p.hop_limit <= p.hop_start) { + uint8_t hopsTaken = p.hop_start - p.hop_limit; + int8_t diff = hopsTaken - r->route_count; + for (uint8_t i = 0; i < diff; i++) { + if (r->route_count < sizeof(r->route) / sizeof(r->route[0])) { + r->route[r->route_count] = NODENUM_BROADCAST; // This will represent an unknown hop + r->route_count += 1; + } + } + } +} + void TraceRouteModule::appendMyID(meshtastic_RouteDiscovery *updated) { // Length of route array can normally not be exceeded due to the max. hop_limit of 7 diff --git a/src/modules/TraceRouteModule.h b/src/modules/TraceRouteModule.h index 15e01debd..18a5ac0cb 100644 --- a/src/modules/TraceRouteModule.h +++ b/src/modules/TraceRouteModule.h @@ -19,6 +19,9 @@ class TraceRouteModule : public ProtobufModule void alterReceivedProtobuf(meshtastic_MeshPacket &p, meshtastic_RouteDiscovery *r) override; private: + // Call to add unknown hops (e.g. when a node couldn't decrypt it) to the route based on hopStart and current hopLimit + void insertUnknownHops(meshtastic_MeshPacket &p, meshtastic_RouteDiscovery *r); + // Call to add your ID to the route array of a RouteDiscovery message void appendMyID(meshtastic_RouteDiscovery *r); From 4f906ae3ae49a2f9a2e6f9ed5bc9a1921c53882c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 9 Jun 2024 18:52:37 -0500 Subject: [PATCH 62/80] [create-pull-request] automated change (#4064) Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com> --- version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.properties b/version.properties index 700044e6f..a26da1996 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 2 minor = 3 -build = 12 +build = 13 From 62b310ac5c868075ef08e4670e2c53a4726cfd43 Mon Sep 17 00:00:00 2001 From: Wolfgang Nagele Date: Mon, 10 Jun 2024 15:10:17 +0200 Subject: [PATCH 63/80] Relax changes from #4001 to allow GPS and NTP as trusted sources (#4068) --- src/modules/PositionModule.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/modules/PositionModule.cpp b/src/modules/PositionModule.cpp index 002111171..49f2b808b 100644 --- a/src/modules/PositionModule.cpp +++ b/src/modules/PositionModule.cpp @@ -209,13 +209,13 @@ meshtastic_MeshPacket *PositionModule::allocReply() p.ground_speed = localPosition.ground_speed; // Strip out any time information before sending packets to other nodes - to keep the wire size small (and because other - // nodes shouldn't trust it anyways) Note: we allow a device with a local GPS to include the time, so that gpsless - // devices can get time. - if (getRTCQuality() < RTCQualityGPS) { + // nodes shouldn't trust it anyways) Note: we allow a device with a local GPS or NTP to include the time, so that devices + // without can get time. + if (getRTCQuality() < RTCQualityNTP) { LOG_INFO("Stripping time %u from position send\n", p.time); p.time = 0; } else { - p.time = getValidTime(RTCQualityGPS); + p.time = getValidTime(RTCQualityNTP); LOG_INFO("Providing time to mesh %u\n", p.time); } From 8b1b6faf896df177f585b2cb5f7799341815911d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Gjels=C3=B8?= <36234524+gjelsoe@users.noreply.github.com> Date: Tue, 11 Jun 2024 21:51:39 +0200 Subject: [PATCH 64/80] Added Radiomaster Bandit Nano and Radiomaster Bandit Micro to default_envs. (#4077) Added Radiomaster Bandit Micro, it shares the same code and settings as Bandit Nano --- platformio.ini | 2 ++ .../platformio.ini | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 variants/radiomaster_900_bandit_micro/platformio.ini diff --git a/platformio.ini b/platformio.ini index 85bce3279..7ed794a6e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -31,6 +31,8 @@ default_envs = tbeam ;default_envs = rak4631 ;default_envs = rak10701 ;default_envs = wio-e5 +;default_envs = radiomaster_900_bandit_nano +;default_envs = radiomaster_900_bandit_micro extra_configs = arch/*/*.ini diff --git a/variants/radiomaster_900_bandit_micro/platformio.ini b/variants/radiomaster_900_bandit_micro/platformio.ini new file mode 100644 index 000000000..9e54f5859 --- /dev/null +++ b/variants/radiomaster_900_bandit_micro/platformio.ini @@ -0,0 +1,19 @@ +; +; This uses the same code and settings as the Radio Master Bandit Nano (https://www.radiomasterrc.com/products/bandit-nano-expresslrs-rf-module) +; +; Link to the unit : https://www.radiomasterrc.com/products/bandit-micro-expresslrs-rf-module +; +[env:radiomaster_900_bandit_micro] +extends = esp32_base +board = esp32doit-devkit-v1 +build_flags = + ${esp32_base.build_flags} + -DRADIOMASTER_900_BANDIT_NANO + -DVTABLES_IN_FLASH=1 + -DCONFIG_DISABLE_HAL_LOCKS=1 + -O2 + -Ivariants/radiomaster_900_bandit_nano +board_build.f_cpu = 240000000L +upload_protocol = esptool +lib_deps = + ${esp32_base.lib_deps} \ No newline at end of file From 7f2647abb18303c1e1af8325fbd53e3129e221dd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 11 Jun 2024 14:52:02 -0500 Subject: [PATCH 65/80] [create-pull-request] automated change (#4078) Co-authored-by: jp-bennett <5630967+jp-bennett@users.noreply.github.com> --- protobufs | 2 +- src/mesh/generated/meshtastic/config.pb.cpp | 1 + src/mesh/generated/meshtastic/config.pb.h | 36 ++++++++++++++++--- src/mesh/generated/meshtastic/deviceonly.pb.h | 2 +- src/mesh/generated/meshtastic/localonly.pb.h | 2 +- 5 files changed, 36 insertions(+), 7 deletions(-) diff --git a/protobufs b/protobufs index a641c5ce4..8c8048798 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit a641c5ce4fca158d18ca3cffc92ac7a10f9b6a04 +Subproject commit 8c8048798c1b1773b9d8f2c32eb3f4c9e72f8218 diff --git a/src/mesh/generated/meshtastic/config.pb.cpp b/src/mesh/generated/meshtastic/config.pb.cpp index f05e47573..bb82198c0 100644 --- a/src/mesh/generated/meshtastic/config.pb.cpp +++ b/src/mesh/generated/meshtastic/config.pb.cpp @@ -46,3 +46,4 @@ PB_BIND(meshtastic_Config_BluetoothConfig, meshtastic_Config_BluetoothConfig, AU + diff --git a/src/mesh/generated/meshtastic/config.pb.h b/src/mesh/generated/meshtastic/config.pb.h index 0830ed851..781538d11 100644 --- a/src/mesh/generated/meshtastic/config.pb.h +++ b/src/mesh/generated/meshtastic/config.pb.h @@ -182,6 +182,25 @@ typedef enum _meshtastic_Config_DisplayConfig_DisplayMode { meshtastic_Config_DisplayConfig_DisplayMode_COLOR = 3 } meshtastic_Config_DisplayConfig_DisplayMode; +typedef enum _meshtastic_Config_DisplayConfig_CompassOrientation { + /* The compass and the display are in the same orientation. */ + meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_0 = 0, + /* Rotate the compass by 90 degrees. */ + meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_90 = 1, + /* Rotate the compass by 180 degrees. */ + meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_180 = 2, + /* Rotate the compass by 270 degrees. */ + meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_270 = 3, + /* Don't rotate the compass, but invert the result. */ + meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_0_INVERTED = 4, + /* Rotate the compass by 90 degrees and invert. */ + meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_90_INVERTED = 5, + /* Rotate the compass by 180 degrees and invert. */ + meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_180_INVERTED = 6, + /* Rotate the compass by 270 degrees and invert. */ + meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_270_INVERTED = 7 +} meshtastic_Config_DisplayConfig_CompassOrientation; + typedef enum _meshtastic_Config_LoRaConfig_RegionCode { /* Region is not set */ meshtastic_Config_LoRaConfig_RegionCode_UNSET = 0, @@ -413,6 +432,8 @@ typedef struct _meshtastic_Config_DisplayConfig { bool heading_bold; /* Should we wake the screen up on accelerometer detected motion or tap */ bool wake_on_tap_or_motion; + /* Indicates how to rotate or invert the compass output to accurate display on the display. */ + meshtastic_Config_DisplayConfig_CompassOrientation compass_orientation; } meshtastic_Config_DisplayConfig; /* Lora Config */ @@ -547,6 +568,10 @@ extern "C" { #define _meshtastic_Config_DisplayConfig_DisplayMode_MAX meshtastic_Config_DisplayConfig_DisplayMode_COLOR #define _meshtastic_Config_DisplayConfig_DisplayMode_ARRAYSIZE ((meshtastic_Config_DisplayConfig_DisplayMode)(meshtastic_Config_DisplayConfig_DisplayMode_COLOR+1)) +#define _meshtastic_Config_DisplayConfig_CompassOrientation_MIN meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_0 +#define _meshtastic_Config_DisplayConfig_CompassOrientation_MAX meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_270_INVERTED +#define _meshtastic_Config_DisplayConfig_CompassOrientation_ARRAYSIZE ((meshtastic_Config_DisplayConfig_CompassOrientation)(meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_270_INVERTED+1)) + #define _meshtastic_Config_LoRaConfig_RegionCode_MIN meshtastic_Config_LoRaConfig_RegionCode_UNSET #define _meshtastic_Config_LoRaConfig_RegionCode_MAX meshtastic_Config_LoRaConfig_RegionCode_SG_923 #define _meshtastic_Config_LoRaConfig_RegionCode_ARRAYSIZE ((meshtastic_Config_LoRaConfig_RegionCode)(meshtastic_Config_LoRaConfig_RegionCode_SG_923+1)) @@ -573,6 +598,7 @@ extern "C" { #define meshtastic_Config_DisplayConfig_units_ENUMTYPE meshtastic_Config_DisplayConfig_DisplayUnits #define meshtastic_Config_DisplayConfig_oled_ENUMTYPE meshtastic_Config_DisplayConfig_OledType #define meshtastic_Config_DisplayConfig_displaymode_ENUMTYPE meshtastic_Config_DisplayConfig_DisplayMode +#define meshtastic_Config_DisplayConfig_compass_orientation_ENUMTYPE meshtastic_Config_DisplayConfig_CompassOrientation #define meshtastic_Config_LoRaConfig_modem_preset_ENUMTYPE meshtastic_Config_LoRaConfig_ModemPreset #define meshtastic_Config_LoRaConfig_region_ENUMTYPE meshtastic_Config_LoRaConfig_RegionCode @@ -587,7 +613,7 @@ extern "C" { #define meshtastic_Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_Config_NetworkConfig_init_default {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_default, ""} #define meshtastic_Config_NetworkConfig_IpV4Config_init_default {0, 0, 0, 0} -#define meshtastic_Config_DisplayConfig_init_default {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0} +#define meshtastic_Config_DisplayConfig_init_default {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0, _meshtastic_Config_DisplayConfig_CompassOrientation_MIN} #define meshtastic_Config_LoRaConfig_init_default {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0} #define meshtastic_Config_BluetoothConfig_init_default {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0} #define meshtastic_Config_init_zero {0, {meshtastic_Config_DeviceConfig_init_zero}} @@ -596,7 +622,7 @@ extern "C" { #define meshtastic_Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_Config_NetworkConfig_init_zero {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_zero, ""} #define meshtastic_Config_NetworkConfig_IpV4Config_init_zero {0, 0, 0, 0} -#define meshtastic_Config_DisplayConfig_init_zero {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0} +#define meshtastic_Config_DisplayConfig_init_zero {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0, _meshtastic_Config_DisplayConfig_CompassOrientation_MIN} #define meshtastic_Config_LoRaConfig_init_zero {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0} #define meshtastic_Config_BluetoothConfig_init_zero {0, _meshtastic_Config_BluetoothConfig_PairingMode_MIN, 0} @@ -656,6 +682,7 @@ extern "C" { #define meshtastic_Config_DisplayConfig_displaymode_tag 8 #define meshtastic_Config_DisplayConfig_heading_bold_tag 9 #define meshtastic_Config_DisplayConfig_wake_on_tap_or_motion_tag 10 +#define meshtastic_Config_DisplayConfig_compass_orientation_tag 11 #define meshtastic_Config_LoRaConfig_use_preset_tag 1 #define meshtastic_Config_LoRaConfig_modem_preset_tag 2 #define meshtastic_Config_LoRaConfig_bandwidth_tag 3 @@ -778,7 +805,8 @@ X(a, STATIC, SINGULAR, UENUM, units, 6) \ X(a, STATIC, SINGULAR, UENUM, oled, 7) \ X(a, STATIC, SINGULAR, UENUM, displaymode, 8) \ X(a, STATIC, SINGULAR, BOOL, heading_bold, 9) \ -X(a, STATIC, SINGULAR, BOOL, wake_on_tap_or_motion, 10) +X(a, STATIC, SINGULAR, BOOL, wake_on_tap_or_motion, 10) \ +X(a, STATIC, SINGULAR, UENUM, compass_orientation, 11) #define meshtastic_Config_DisplayConfig_CALLBACK NULL #define meshtastic_Config_DisplayConfig_DEFAULT NULL @@ -834,7 +862,7 @@ extern const pb_msgdesc_t meshtastic_Config_BluetoothConfig_msg; #define MESHTASTIC_MESHTASTIC_CONFIG_PB_H_MAX_SIZE meshtastic_Config_size #define meshtastic_Config_BluetoothConfig_size 10 #define meshtastic_Config_DeviceConfig_size 100 -#define meshtastic_Config_DisplayConfig_size 28 +#define meshtastic_Config_DisplayConfig_size 30 #define meshtastic_Config_LoRaConfig_size 80 #define meshtastic_Config_NetworkConfig_IpV4Config_size 20 #define meshtastic_Config_NetworkConfig_size 196 diff --git a/src/mesh/generated/meshtastic/deviceonly.pb.h b/src/mesh/generated/meshtastic/deviceonly.pb.h index a5cbc42a5..0e3e28ba1 100644 --- a/src/mesh/generated/meshtastic/deviceonly.pb.h +++ b/src/mesh/generated/meshtastic/deviceonly.pb.h @@ -308,7 +308,7 @@ extern const pb_msgdesc_t meshtastic_OEMStore_msg; #define MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_MAX_SIZE meshtastic_OEMStore_size #define meshtastic_ChannelFile_size 718 #define meshtastic_NodeInfoLite_size 166 -#define meshtastic_OEMStore_size 3368 +#define meshtastic_OEMStore_size 3370 #define meshtastic_PositionLite_size 28 #ifdef __cplusplus diff --git a/src/mesh/generated/meshtastic/localonly.pb.h b/src/mesh/generated/meshtastic/localonly.pb.h index 1b8123ef5..160202d9b 100644 --- a/src/mesh/generated/meshtastic/localonly.pb.h +++ b/src/mesh/generated/meshtastic/localonly.pb.h @@ -181,7 +181,7 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg; /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_MAX_SIZE meshtastic_LocalModuleConfig_size -#define meshtastic_LocalConfig_size 537 +#define meshtastic_LocalConfig_size 539 #define meshtastic_LocalModuleConfig_size 685 #ifdef __cplusplus From 0852a170a3b6a10b69fc88963ef267faeda11a07 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Tue, 11 Jun 2024 17:47:45 -0500 Subject: [PATCH 66/80] Add support for BMX160/RAK12034 compass module (#4021) --- src/AccelerometerThread.h | 81 ++- src/Fusion/Fusion.h | 32 ++ src/Fusion/FusionAhrs.c | 542 ++++++++++++++++++ src/Fusion/FusionAhrs.h | 112 ++++ src/Fusion/FusionAxes.h | 188 ++++++ src/Fusion/FusionCalibration.h | 49 ++ src/Fusion/FusionCompass.c | 51 ++ src/Fusion/FusionCompass.h | 26 + src/Fusion/FusionConvention.h | 25 + src/Fusion/FusionMath.h | 503 ++++++++++++++++ src/Fusion/FusionOffset.c | 80 +++ src/Fusion/FusionOffset.h | 40 ++ src/configuration.h | 1 + src/detect/ScanI2C.cpp | 4 +- src/detect/ScanI2C.h | 3 +- src/detect/ScanI2CTwoWire.cpp | 1 + src/graphics/Screen.cpp | 8 +- src/graphics/Screen.h | 13 + src/main.h | 6 +- variants/rak4631/platformio.ini | 1 + variants/rak4631_epaper/platformio.ini | 1 + variants/rak4631_epaper_onrxtx/platformio.ini | 3 +- 22 files changed, 1760 insertions(+), 10 deletions(-) create mode 100644 src/Fusion/Fusion.h create mode 100644 src/Fusion/FusionAhrs.c create mode 100644 src/Fusion/FusionAhrs.h create mode 100644 src/Fusion/FusionAxes.h create mode 100644 src/Fusion/FusionCalibration.h create mode 100644 src/Fusion/FusionCompass.c create mode 100644 src/Fusion/FusionCompass.h create mode 100644 src/Fusion/FusionConvention.h create mode 100644 src/Fusion/FusionMath.h create mode 100644 src/Fusion/FusionOffset.c create mode 100644 src/Fusion/FusionOffset.h diff --git a/src/AccelerometerThread.h b/src/AccelerometerThread.h index ad40cd9bd..f03752cad 100644 --- a/src/AccelerometerThread.h +++ b/src/AccelerometerThread.h @@ -14,6 +14,10 @@ #include #include #include +#ifdef RAK_4631 +#include "Fusion/Fusion.h" +#include +#endif #define ACCELEROMETER_CHECK_INTERVAL_MS 100 #define ACCELEROMETER_CLICK_THRESHOLD 40 @@ -50,12 +54,13 @@ class AccelerometerThread : public concurrency::OSThread return; } acceleremoter_type = type; - +#ifndef RAK_4631 if (!config.display.wake_on_tap_or_motion && !config.device.double_tap_as_button_press) { LOG_DEBUG("AccelerometerThread disabling due to no interested configurations\n"); disable(); return; } +#endif init(); } @@ -87,6 +92,71 @@ class AccelerometerThread : public concurrency::OSThread wakeScreen(); return 500; } +#ifdef RAK_4631 + } else if (acceleremoter_type == ScanI2C::DeviceType::BMX160) { + sBmx160SensorData_t magAccel; + sBmx160SensorData_t gAccel; + + /* Get a new sensor event */ + bmx160.getAllData(&magAccel, NULL, &gAccel); + + // expirimental calibrate routine. Limited to between 10 and 30 seconds after boot + if (millis() > 10 * 1000 && millis() < 30 * 1000) { + if (magAccel.x > highestX) + highestX = magAccel.x; + if (magAccel.x < lowestX) + lowestX = magAccel.x; + if (magAccel.y > highestY) + highestY = magAccel.y; + if (magAccel.y < lowestY) + lowestY = magAccel.y; + if (magAccel.z > highestZ) + highestZ = magAccel.z; + if (magAccel.z < lowestZ) + lowestZ = magAccel.z; + } + + int highestRealX = highestX - (highestX + lowestX) / 2; + + magAccel.x -= (highestX + lowestX) / 2; + magAccel.y -= (highestY + lowestY) / 2; + magAccel.z -= (highestZ + lowestZ) / 2; + FusionVector ga, ma; + ga.axis.x = -gAccel.x; // default location for the BMX160 is on the rear of the board + ga.axis.y = -gAccel.y; + ga.axis.z = gAccel.z; + ma.axis.x = -magAccel.x; + ma.axis.y = -magAccel.y; + ma.axis.z = magAccel.z * 3; + + // If we're set to one of the inverted positions + if (config.display.compass_orientation > meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_270) { + ma = FusionAxesSwap(ma, FusionAxesAlignmentNXNYPZ); + ga = FusionAxesSwap(ga, FusionAxesAlignmentNXNYPZ); + } + + float heading = FusionCompassCalculateHeading(FusionConventionNed, ga, ma); + + switch (config.display.compass_orientation) { + case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_0: + break; + case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_90: + case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_90_INVERTED: + heading += 90; + break; + case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_180: + case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_180_INVERTED: + heading += 180; + break; + case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_270: + case meshtastic_Config_DisplayConfig_CompassOrientation_DEGREES_270_INVERTED: + heading += 270; + break; + } + + screen->setHeading(heading); + +#endif } else if (acceleremoter_type == ScanI2C::DeviceType::LSM6DS3 && lsm.shake()) { wakeScreen(); return 500; @@ -149,6 +219,11 @@ class AccelerometerThread : public concurrency::OSThread bmaSensor.enableTiltIRQ(); // It corresponds to isDoubleClick interrupt bmaSensor.enableWakeupIRQ(); +#ifdef RAK_4631 + } else if (acceleremoter_type == ScanI2C::DeviceType::BMX160 && bmx160.begin()) { + bmx160.ODR_Config(BMX160_ACCEL_ODR_100HZ, BMX160_GYRO_ODR_100HZ); // set output data rate + +#endif } else if (acceleremoter_type == ScanI2C::DeviceType::LSM6DS3 && lsm.begin_I2C(accelerometer_found.address)) { LOG_DEBUG("LSM6DS3 initializing\n"); // Default threshold of 2G, less sensitive options are 4, 8 or 16G @@ -179,6 +254,10 @@ class AccelerometerThread : public concurrency::OSThread Adafruit_LIS3DH lis; Adafruit_LSM6DS3TRC lsm; SensorBMA423 bmaSensor; +#ifdef RAK_4631 + RAK_BMX160 bmx160; + float highestX = 0, lowestX = 0, highestY = 0, lowestY = 0, highestZ = 0, lowestZ = 0; +#endif bool BMA_IRQ = false; }; diff --git a/src/Fusion/Fusion.h b/src/Fusion/Fusion.h new file mode 100644 index 000000000..48f5198c5 --- /dev/null +++ b/src/Fusion/Fusion.h @@ -0,0 +1,32 @@ +/** + * @file Fusion.h + * @author Seb Madgwick + * @brief Main header file for the Fusion library. This is the only file that + * needs to be included when using the library. + */ + +#ifndef FUSION_H +#define FUSION_H + +//------------------------------------------------------------------------------ +// Includes + +#ifdef __cplusplus +extern "C" { +#endif + +#include "FusionAhrs.h" +#include "FusionAxes.h" +#include "FusionCalibration.h" +#include "FusionCompass.h" +#include "FusionConvention.h" +#include "FusionMath.h" +#include "FusionOffset.h" + +#ifdef __cplusplus +} +#endif + +#endif +//------------------------------------------------------------------------------ +// End of file diff --git a/src/Fusion/FusionAhrs.c b/src/Fusion/FusionAhrs.c new file mode 100644 index 000000000..d6c1d0215 --- /dev/null +++ b/src/Fusion/FusionAhrs.c @@ -0,0 +1,542 @@ +/** + * @file FusionAhrs.c + * @author Seb Madgwick + * @brief AHRS algorithm to combine gyroscope, accelerometer, and magnetometer + * measurements into a single measurement of orientation relative to the Earth. + */ + +//------------------------------------------------------------------------------ +// Includes + +#include "FusionAhrs.h" +#include // FLT_MAX +#include // atan2f, cosf, fabsf, powf, sinf + +//------------------------------------------------------------------------------ +// Definitions + +/** + * @brief Initial gain used during the initialisation. + */ +#define INITIAL_GAIN (10.0f) + +/** + * @brief Initialisation period in seconds. + */ +#define INITIALISATION_PERIOD (3.0f) + +//------------------------------------------------------------------------------ +// Function declarations + +static inline FusionVector HalfGravity(const FusionAhrs *const ahrs); + +static inline FusionVector HalfMagnetic(const FusionAhrs *const ahrs); + +static inline FusionVector Feedback(const FusionVector sensor, const FusionVector reference); + +static inline int Clamp(const int value, const int min, const int max); + +//------------------------------------------------------------------------------ +// Functions + +/** + * @brief Initialises the AHRS algorithm structure. + * @param ahrs AHRS algorithm structure. + */ +void FusionAhrsInitialise(FusionAhrs *const ahrs) +{ + const FusionAhrsSettings settings = { + .convention = FusionConventionNwu, + .gain = 0.5f, + .gyroscopeRange = 0.0f, + .accelerationRejection = 90.0f, + .magneticRejection = 90.0f, + .recoveryTriggerPeriod = 0, + }; + FusionAhrsSetSettings(ahrs, &settings); + FusionAhrsReset(ahrs); +} + +/** + * @brief Resets the AHRS algorithm. This is equivalent to reinitialising the + * algorithm while maintaining the current settings. + * @param ahrs AHRS algorithm structure. + */ +void FusionAhrsReset(FusionAhrs *const ahrs) +{ + ahrs->quaternion = FUSION_IDENTITY_QUATERNION; + ahrs->accelerometer = FUSION_VECTOR_ZERO; + ahrs->initialising = true; + ahrs->rampedGain = INITIAL_GAIN; + ahrs->angularRateRecovery = false; + ahrs->halfAccelerometerFeedback = FUSION_VECTOR_ZERO; + ahrs->halfMagnetometerFeedback = FUSION_VECTOR_ZERO; + ahrs->accelerometerIgnored = false; + ahrs->accelerationRecoveryTrigger = 0; + ahrs->accelerationRecoveryTimeout = ahrs->settings.recoveryTriggerPeriod; + ahrs->magnetometerIgnored = false; + ahrs->magneticRecoveryTrigger = 0; + ahrs->magneticRecoveryTimeout = ahrs->settings.recoveryTriggerPeriod; +} + +/** + * @brief Sets the AHRS algorithm settings. + * @param ahrs AHRS algorithm structure. + * @param settings Settings. + */ +void FusionAhrsSetSettings(FusionAhrs *const ahrs, const FusionAhrsSettings *const settings) +{ + ahrs->settings.convention = settings->convention; + ahrs->settings.gain = settings->gain; + ahrs->settings.gyroscopeRange = settings->gyroscopeRange == 0.0f ? FLT_MAX : 0.98f * settings->gyroscopeRange; + ahrs->settings.accelerationRejection = settings->accelerationRejection == 0.0f + ? FLT_MAX + : powf(0.5f * sinf(FusionDegreesToRadians(settings->accelerationRejection)), 2); + ahrs->settings.magneticRejection = + settings->magneticRejection == 0.0f ? FLT_MAX : powf(0.5f * sinf(FusionDegreesToRadians(settings->magneticRejection)), 2); + ahrs->settings.recoveryTriggerPeriod = settings->recoveryTriggerPeriod; + ahrs->accelerationRecoveryTimeout = ahrs->settings.recoveryTriggerPeriod; + ahrs->magneticRecoveryTimeout = ahrs->settings.recoveryTriggerPeriod; + if ((settings->gain == 0.0f) || + (settings->recoveryTriggerPeriod == 0)) { // disable acceleration and magnetic rejection features if gain is zero + ahrs->settings.accelerationRejection = FLT_MAX; + ahrs->settings.magneticRejection = FLT_MAX; + } + if (ahrs->initialising == false) { + ahrs->rampedGain = ahrs->settings.gain; + } + ahrs->rampedGainStep = (INITIAL_GAIN - ahrs->settings.gain) / INITIALISATION_PERIOD; +} + +/** + * @brief Updates the AHRS algorithm using the gyroscope, accelerometer, and + * magnetometer measurements. + * @param ahrs AHRS algorithm structure. + * @param gyroscope Gyroscope measurement in degrees per second. + * @param accelerometer Accelerometer measurement in g. + * @param magnetometer Magnetometer measurement in arbitrary units. + * @param deltaTime Delta time in seconds. + */ +void FusionAhrsUpdate(FusionAhrs *const ahrs, const FusionVector gyroscope, const FusionVector accelerometer, + const FusionVector magnetometer, const float deltaTime) +{ +#define Q ahrs->quaternion.element + + // Store accelerometer + ahrs->accelerometer = accelerometer; + + // Reinitialise if gyroscope range exceeded + if ((fabsf(gyroscope.axis.x) > ahrs->settings.gyroscopeRange) || (fabsf(gyroscope.axis.y) > ahrs->settings.gyroscopeRange) || + (fabsf(gyroscope.axis.z) > ahrs->settings.gyroscopeRange)) { + const FusionQuaternion quaternion = ahrs->quaternion; + FusionAhrsReset(ahrs); + ahrs->quaternion = quaternion; + ahrs->angularRateRecovery = true; + } + + // Ramp down gain during initialisation + if (ahrs->initialising) { + ahrs->rampedGain -= ahrs->rampedGainStep * deltaTime; + if ((ahrs->rampedGain < ahrs->settings.gain) || (ahrs->settings.gain == 0.0f)) { + ahrs->rampedGain = ahrs->settings.gain; + ahrs->initialising = false; + ahrs->angularRateRecovery = false; + } + } + + // Calculate direction of gravity indicated by algorithm + const FusionVector halfGravity = HalfGravity(ahrs); + + // Calculate accelerometer feedback + FusionVector halfAccelerometerFeedback = FUSION_VECTOR_ZERO; + ahrs->accelerometerIgnored = true; + if (FusionVectorIsZero(accelerometer) == false) { + + // Calculate accelerometer feedback scaled by 0.5 + ahrs->halfAccelerometerFeedback = Feedback(FusionVectorNormalise(accelerometer), halfGravity); + + // Don't ignore accelerometer if acceleration error below threshold + if (ahrs->initialising || + ((FusionVectorMagnitudeSquared(ahrs->halfAccelerometerFeedback) <= ahrs->settings.accelerationRejection))) { + ahrs->accelerometerIgnored = false; + ahrs->accelerationRecoveryTrigger -= 9; + } else { + ahrs->accelerationRecoveryTrigger += 1; + } + + // Don't ignore accelerometer during acceleration recovery + if (ahrs->accelerationRecoveryTrigger > ahrs->accelerationRecoveryTimeout) { + ahrs->accelerationRecoveryTimeout = 0; + ahrs->accelerometerIgnored = false; + } else { + ahrs->accelerationRecoveryTimeout = ahrs->settings.recoveryTriggerPeriod; + } + ahrs->accelerationRecoveryTrigger = Clamp(ahrs->accelerationRecoveryTrigger, 0, ahrs->settings.recoveryTriggerPeriod); + + // Apply accelerometer feedback + if (ahrs->accelerometerIgnored == false) { + halfAccelerometerFeedback = ahrs->halfAccelerometerFeedback; + } + } + + // Calculate magnetometer feedback + FusionVector halfMagnetometerFeedback = FUSION_VECTOR_ZERO; + ahrs->magnetometerIgnored = true; + if (FusionVectorIsZero(magnetometer) == false) { + + // Calculate direction of magnetic field indicated by algorithm + const FusionVector halfMagnetic = HalfMagnetic(ahrs); + + // Calculate magnetometer feedback scaled by 0.5 + ahrs->halfMagnetometerFeedback = + Feedback(FusionVectorNormalise(FusionVectorCrossProduct(halfGravity, magnetometer)), halfMagnetic); + + // Don't ignore magnetometer if magnetic error below threshold + if (ahrs->initialising || + ((FusionVectorMagnitudeSquared(ahrs->halfMagnetometerFeedback) <= ahrs->settings.magneticRejection))) { + ahrs->magnetometerIgnored = false; + ahrs->magneticRecoveryTrigger -= 9; + } else { + ahrs->magneticRecoveryTrigger += 1; + } + + // Don't ignore magnetometer during magnetic recovery + if (ahrs->magneticRecoveryTrigger > ahrs->magneticRecoveryTimeout) { + ahrs->magneticRecoveryTimeout = 0; + ahrs->magnetometerIgnored = false; + } else { + ahrs->magneticRecoveryTimeout = ahrs->settings.recoveryTriggerPeriod; + } + ahrs->magneticRecoveryTrigger = Clamp(ahrs->magneticRecoveryTrigger, 0, ahrs->settings.recoveryTriggerPeriod); + + // Apply magnetometer feedback + if (ahrs->magnetometerIgnored == false) { + halfMagnetometerFeedback = ahrs->halfMagnetometerFeedback; + } + } + + // Convert gyroscope to radians per second scaled by 0.5 + const FusionVector halfGyroscope = FusionVectorMultiplyScalar(gyroscope, FusionDegreesToRadians(0.5f)); + + // Apply feedback to gyroscope + const FusionVector adjustedHalfGyroscope = FusionVectorAdd( + halfGyroscope, + FusionVectorMultiplyScalar(FusionVectorAdd(halfAccelerometerFeedback, halfMagnetometerFeedback), ahrs->rampedGain)); + + // Integrate rate of change of quaternion + ahrs->quaternion = FusionQuaternionAdd( + ahrs->quaternion, + FusionQuaternionMultiplyVector(ahrs->quaternion, FusionVectorMultiplyScalar(adjustedHalfGyroscope, deltaTime))); + + // Normalise quaternion + ahrs->quaternion = FusionQuaternionNormalise(ahrs->quaternion); +#undef Q +} + +/** + * @brief Returns the direction of gravity scaled by 0.5. + * @param ahrs AHRS algorithm structure. + * @return Direction of gravity scaled by 0.5. + */ +static inline FusionVector HalfGravity(const FusionAhrs *const ahrs) +{ +#define Q ahrs->quaternion.element + switch (ahrs->settings.convention) { + case FusionConventionNwu: + case FusionConventionEnu: { + const FusionVector halfGravity = {.axis = { + .x = Q.x * Q.z - Q.w * Q.y, + .y = Q.y * Q.z + Q.w * Q.x, + .z = Q.w * Q.w - 0.5f + Q.z * Q.z, + }}; // third column of transposed rotation matrix scaled by 0.5 + return halfGravity; + } + case FusionConventionNed: { + const FusionVector halfGravity = {.axis = { + .x = Q.w * Q.y - Q.x * Q.z, + .y = -1.0f * (Q.y * Q.z + Q.w * Q.x), + .z = 0.5f - Q.w * Q.w - Q.z * Q.z, + }}; // third column of transposed rotation matrix scaled by -0.5 + return halfGravity; + } + } + return FUSION_VECTOR_ZERO; // avoid compiler warning +#undef Q +} + +/** + * @brief Returns the direction of the magnetic field scaled by 0.5. + * @param ahrs AHRS algorithm structure. + * @return Direction of the magnetic field scaled by 0.5. + */ +static inline FusionVector HalfMagnetic(const FusionAhrs *const ahrs) +{ +#define Q ahrs->quaternion.element + switch (ahrs->settings.convention) { + case FusionConventionNwu: { + const FusionVector halfMagnetic = {.axis = { + .x = Q.x * Q.y + Q.w * Q.z, + .y = Q.w * Q.w - 0.5f + Q.y * Q.y, + .z = Q.y * Q.z - Q.w * Q.x, + }}; // second column of transposed rotation matrix scaled by 0.5 + return halfMagnetic; + } + case FusionConventionEnu: { + const FusionVector halfMagnetic = {.axis = { + .x = 0.5f - Q.w * Q.w - Q.x * Q.x, + .y = Q.w * Q.z - Q.x * Q.y, + .z = -1.0f * (Q.x * Q.z + Q.w * Q.y), + }}; // first column of transposed rotation matrix scaled by -0.5 + return halfMagnetic; + } + case FusionConventionNed: { + const FusionVector halfMagnetic = {.axis = { + .x = -1.0f * (Q.x * Q.y + Q.w * Q.z), + .y = 0.5f - Q.w * Q.w - Q.y * Q.y, + .z = Q.w * Q.x - Q.y * Q.z, + }}; // second column of transposed rotation matrix scaled by -0.5 + return halfMagnetic; + } + } + return FUSION_VECTOR_ZERO; // avoid compiler warning +#undef Q +} + +/** + * @brief Returns the feedback. + * @param sensor Sensor. + * @param reference Reference. + * @return Feedback. + */ +static inline FusionVector Feedback(const FusionVector sensor, const FusionVector reference) +{ + if (FusionVectorDotProduct(sensor, reference) < 0.0f) { // if error is >90 degrees + return FusionVectorNormalise(FusionVectorCrossProduct(sensor, reference)); + } + return FusionVectorCrossProduct(sensor, reference); +} + +/** + * @brief Returns a value limited to maximum and minimum. + * @param value Value. + * @param min Minimum value. + * @param max Maximum value. + * @return Value limited to maximum and minimum. + */ +static inline int Clamp(const int value, const int min, const int max) +{ + if (value < min) { + return min; + } + if (value > max) { + return max; + } + return value; +} + +/** + * @brief Updates the AHRS algorithm using the gyroscope and accelerometer + * measurements only. + * @param ahrs AHRS algorithm structure. + * @param gyroscope Gyroscope measurement in degrees per second. + * @param accelerometer Accelerometer measurement in g. + * @param deltaTime Delta time in seconds. + */ +void FusionAhrsUpdateNoMagnetometer(FusionAhrs *const ahrs, const FusionVector gyroscope, const FusionVector accelerometer, + const float deltaTime) +{ + + // Update AHRS algorithm + FusionAhrsUpdate(ahrs, gyroscope, accelerometer, FUSION_VECTOR_ZERO, deltaTime); + + // Zero heading during initialisation + if (ahrs->initialising) { + FusionAhrsSetHeading(ahrs, 0.0f); + } +} + +/** + * @brief Updates the AHRS algorithm using the gyroscope, accelerometer, and + * heading measurements. + * @param ahrs AHRS algorithm structure. + * @param gyroscope Gyroscope measurement in degrees per second. + * @param accelerometer Accelerometer measurement in g. + * @param heading Heading measurement in degrees. + * @param deltaTime Delta time in seconds. + */ +void FusionAhrsUpdateExternalHeading(FusionAhrs *const ahrs, const FusionVector gyroscope, const FusionVector accelerometer, + const float heading, const float deltaTime) +{ +#define Q ahrs->quaternion.element + + // Calculate roll + const float roll = atan2f(Q.w * Q.x + Q.y * Q.z, 0.5f - Q.y * Q.y - Q.x * Q.x); + + // Calculate magnetometer + const float headingRadians = FusionDegreesToRadians(heading); + const float sinHeadingRadians = sinf(headingRadians); + const FusionVector magnetometer = {.axis = { + .x = cosf(headingRadians), + .y = -1.0f * cosf(roll) * sinHeadingRadians, + .z = sinHeadingRadians * sinf(roll), + }}; + + // Update AHRS algorithm + FusionAhrsUpdate(ahrs, gyroscope, accelerometer, magnetometer, deltaTime); +#undef Q +} + +/** + * @brief Returns the quaternion describing the sensor relative to the Earth. + * @param ahrs AHRS algorithm structure. + * @return Quaternion describing the sensor relative to the Earth. + */ +FusionQuaternion FusionAhrsGetQuaternion(const FusionAhrs *const ahrs) +{ + return ahrs->quaternion; +} + +/** + * @brief Sets the quaternion describing the sensor relative to the Earth. + * @param ahrs AHRS algorithm structure. + * @param quaternion Quaternion describing the sensor relative to the Earth. + */ +void FusionAhrsSetQuaternion(FusionAhrs *const ahrs, const FusionQuaternion quaternion) +{ + ahrs->quaternion = quaternion; +} + +/** + * @brief Returns the linear acceleration measurement equal to the accelerometer + * measurement with the 1 g of gravity removed. + * @param ahrs AHRS algorithm structure. + * @return Linear acceleration measurement in g. + */ +FusionVector FusionAhrsGetLinearAcceleration(const FusionAhrs *const ahrs) +{ +#define Q ahrs->quaternion.element + + // Calculate gravity in the sensor coordinate frame + const FusionVector gravity = {.axis = { + .x = 2.0f * (Q.x * Q.z - Q.w * Q.y), + .y = 2.0f * (Q.y * Q.z + Q.w * Q.x), + .z = 2.0f * (Q.w * Q.w - 0.5f + Q.z * Q.z), + }}; // third column of transposed rotation matrix + + // Remove gravity from accelerometer measurement + switch (ahrs->settings.convention) { + case FusionConventionNwu: + case FusionConventionEnu: { + return FusionVectorSubtract(ahrs->accelerometer, gravity); + } + case FusionConventionNed: { + return FusionVectorAdd(ahrs->accelerometer, gravity); + } + } + return FUSION_VECTOR_ZERO; // avoid compiler warning +#undef Q +} + +/** + * @brief Returns the Earth acceleration measurement equal to accelerometer + * measurement in the Earth coordinate frame with the 1 g of gravity removed. + * @param ahrs AHRS algorithm structure. + * @return Earth acceleration measurement in g. + */ +FusionVector FusionAhrsGetEarthAcceleration(const FusionAhrs *const ahrs) +{ +#define Q ahrs->quaternion.element +#define A ahrs->accelerometer.axis + + // Calculate accelerometer measurement in the Earth coordinate frame + const float qwqw = Q.w * Q.w; // calculate common terms to avoid repeated operations + const float qwqx = Q.w * Q.x; + const float qwqy = Q.w * Q.y; + const float qwqz = Q.w * Q.z; + const float qxqy = Q.x * Q.y; + const float qxqz = Q.x * Q.z; + const float qyqz = Q.y * Q.z; + FusionVector accelerometer = {.axis = { + .x = 2.0f * ((qwqw - 0.5f + Q.x * Q.x) * A.x + (qxqy - qwqz) * A.y + (qxqz + qwqy) * A.z), + .y = 2.0f * ((qxqy + qwqz) * A.x + (qwqw - 0.5f + Q.y * Q.y) * A.y + (qyqz - qwqx) * A.z), + .z = 2.0f * ((qxqz - qwqy) * A.x + (qyqz + qwqx) * A.y + (qwqw - 0.5f + Q.z * Q.z) * A.z), + }}; // rotation matrix multiplied with the accelerometer + + // Remove gravity from accelerometer measurement + switch (ahrs->settings.convention) { + case FusionConventionNwu: + case FusionConventionEnu: + accelerometer.axis.z -= 1.0f; + break; + case FusionConventionNed: + accelerometer.axis.z += 1.0f; + break; + } + return accelerometer; +#undef Q +#undef A +} + +/** + * @brief Returns the AHRS algorithm internal states. + * @param ahrs AHRS algorithm structure. + * @return AHRS algorithm internal states. + */ +FusionAhrsInternalStates FusionAhrsGetInternalStates(const FusionAhrs *const ahrs) +{ + const FusionAhrsInternalStates internalStates = { + .accelerationError = FusionRadiansToDegrees(FusionAsin(2.0f * FusionVectorMagnitude(ahrs->halfAccelerometerFeedback))), + .accelerometerIgnored = ahrs->accelerometerIgnored, + .accelerationRecoveryTrigger = + ahrs->settings.recoveryTriggerPeriod == 0 + ? 0.0f + : (float)ahrs->accelerationRecoveryTrigger / (float)ahrs->settings.recoveryTriggerPeriod, + .magneticError = FusionRadiansToDegrees(FusionAsin(2.0f * FusionVectorMagnitude(ahrs->halfMagnetometerFeedback))), + .magnetometerIgnored = ahrs->magnetometerIgnored, + .magneticRecoveryTrigger = ahrs->settings.recoveryTriggerPeriod == 0 + ? 0.0f + : (float)ahrs->magneticRecoveryTrigger / (float)ahrs->settings.recoveryTriggerPeriod, + }; + return internalStates; +} + +/** + * @brief Returns the AHRS algorithm flags. + * @param ahrs AHRS algorithm structure. + * @return AHRS algorithm flags. + */ +FusionAhrsFlags FusionAhrsGetFlags(const FusionAhrs *const ahrs) +{ + const FusionAhrsFlags flags = { + .initialising = ahrs->initialising, + .angularRateRecovery = ahrs->angularRateRecovery, + .accelerationRecovery = ahrs->accelerationRecoveryTrigger > ahrs->accelerationRecoveryTimeout, + .magneticRecovery = ahrs->magneticRecoveryTrigger > ahrs->magneticRecoveryTimeout, + }; + return flags; +} + +/** + * @brief Sets the heading of the orientation measurement provided by the AHRS + * algorithm. This function can be used to reset drift in heading when the AHRS + * algorithm is being used without a magnetometer. + * @param ahrs AHRS algorithm structure. + * @param heading Heading angle in degrees. + */ +void FusionAhrsSetHeading(FusionAhrs *const ahrs, const float heading) +{ +#define Q ahrs->quaternion.element + const float yaw = atan2f(Q.w * Q.z + Q.x * Q.y, 0.5f - Q.y * Q.y - Q.z * Q.z); + const float halfYawMinusHeading = 0.5f * (yaw - FusionDegreesToRadians(heading)); + const FusionQuaternion rotation = {.element = { + .w = cosf(halfYawMinusHeading), + .x = 0.0f, + .y = 0.0f, + .z = -1.0f * sinf(halfYawMinusHeading), + }}; + ahrs->quaternion = FusionQuaternionMultiply(rotation, ahrs->quaternion); +#undef Q +} + +//------------------------------------------------------------------------------ +// End of file diff --git a/src/Fusion/FusionAhrs.h b/src/Fusion/FusionAhrs.h new file mode 100644 index 000000000..aa2326e43 --- /dev/null +++ b/src/Fusion/FusionAhrs.h @@ -0,0 +1,112 @@ +/** + * @file FusionAhrs.h + * @author Seb Madgwick + * @brief AHRS algorithm to combine gyroscope, accelerometer, and magnetometer + * measurements into a single measurement of orientation relative to the Earth. + */ + +#ifndef FUSION_AHRS_H +#define FUSION_AHRS_H + +//------------------------------------------------------------------------------ +// Includes + +#include "FusionConvention.h" +#include "FusionMath.h" +#include + +//------------------------------------------------------------------------------ +// Definitions + +/** + * @brief AHRS algorithm settings. + */ +typedef struct { + FusionConvention convention; + float gain; + float gyroscopeRange; + float accelerationRejection; + float magneticRejection; + unsigned int recoveryTriggerPeriod; +} FusionAhrsSettings; + +/** + * @brief AHRS algorithm structure. Structure members are used internally and + * must not be accessed by the application. + */ +typedef struct { + FusionAhrsSettings settings; + FusionQuaternion quaternion; + FusionVector accelerometer; + bool initialising; + float rampedGain; + float rampedGainStep; + bool angularRateRecovery; + FusionVector halfAccelerometerFeedback; + FusionVector halfMagnetometerFeedback; + bool accelerometerIgnored; + int accelerationRecoveryTrigger; + int accelerationRecoveryTimeout; + bool magnetometerIgnored; + int magneticRecoveryTrigger; + int magneticRecoveryTimeout; +} FusionAhrs; + +/** + * @brief AHRS algorithm internal states. + */ +typedef struct { + float accelerationError; + bool accelerometerIgnored; + float accelerationRecoveryTrigger; + float magneticError; + bool magnetometerIgnored; + float magneticRecoveryTrigger; +} FusionAhrsInternalStates; + +/** + * @brief AHRS algorithm flags. + */ +typedef struct { + bool initialising; + bool angularRateRecovery; + bool accelerationRecovery; + bool magneticRecovery; +} FusionAhrsFlags; + +//------------------------------------------------------------------------------ +// Function declarations + +void FusionAhrsInitialise(FusionAhrs *const ahrs); + +void FusionAhrsReset(FusionAhrs *const ahrs); + +void FusionAhrsSetSettings(FusionAhrs *const ahrs, const FusionAhrsSettings *const settings); + +void FusionAhrsUpdate(FusionAhrs *const ahrs, const FusionVector gyroscope, const FusionVector accelerometer, + const FusionVector magnetometer, const float deltaTime); + +void FusionAhrsUpdateNoMagnetometer(FusionAhrs *const ahrs, const FusionVector gyroscope, const FusionVector accelerometer, + const float deltaTime); + +void FusionAhrsUpdateExternalHeading(FusionAhrs *const ahrs, const FusionVector gyroscope, const FusionVector accelerometer, + const float heading, const float deltaTime); + +FusionQuaternion FusionAhrsGetQuaternion(const FusionAhrs *const ahrs); + +void FusionAhrsSetQuaternion(FusionAhrs *const ahrs, const FusionQuaternion quaternion); + +FusionVector FusionAhrsGetLinearAcceleration(const FusionAhrs *const ahrs); + +FusionVector FusionAhrsGetEarthAcceleration(const FusionAhrs *const ahrs); + +FusionAhrsInternalStates FusionAhrsGetInternalStates(const FusionAhrs *const ahrs); + +FusionAhrsFlags FusionAhrsGetFlags(const FusionAhrs *const ahrs); + +void FusionAhrsSetHeading(FusionAhrs *const ahrs, const float heading); + +#endif + +//------------------------------------------------------------------------------ +// End of file diff --git a/src/Fusion/FusionAxes.h b/src/Fusion/FusionAxes.h new file mode 100644 index 000000000..9673c88ff --- /dev/null +++ b/src/Fusion/FusionAxes.h @@ -0,0 +1,188 @@ +/** + * @file FusionAxes.h + * @author Seb Madgwick + * @brief Swaps sensor axes for alignment with the body axes. + */ + +#ifndef FUSION_AXES_H +#define FUSION_AXES_H + +//------------------------------------------------------------------------------ +// Includes + +#include "FusionMath.h" + +//------------------------------------------------------------------------------ +// Definitions + +/** + * @brief Axes alignment describing the sensor axes relative to the body axes. + * For example, if the body X axis is aligned with the sensor Y axis and the + * body Y axis is aligned with sensor X axis but pointing the opposite direction + * then alignment is +Y-X+Z. + */ +typedef enum { + FusionAxesAlignmentPXPYPZ, /* +X+Y+Z */ + FusionAxesAlignmentPXNZPY, /* +X-Z+Y */ + FusionAxesAlignmentPXNYNZ, /* +X-Y-Z */ + FusionAxesAlignmentPXPZNY, /* +X+Z-Y */ + FusionAxesAlignmentNXPYNZ, /* -X+Y-Z */ + FusionAxesAlignmentNXPZPY, /* -X+Z+Y */ + FusionAxesAlignmentNXNYPZ, /* -X-Y+Z */ + FusionAxesAlignmentNXNZNY, /* -X-Z-Y */ + FusionAxesAlignmentPYNXPZ, /* +Y-X+Z */ + FusionAxesAlignmentPYNZNX, /* +Y-Z-X */ + FusionAxesAlignmentPYPXNZ, /* +Y+X-Z */ + FusionAxesAlignmentPYPZPX, /* +Y+Z+X */ + FusionAxesAlignmentNYPXPZ, /* -Y+X+Z */ + FusionAxesAlignmentNYNZPX, /* -Y-Z+X */ + FusionAxesAlignmentNYNXNZ, /* -Y-X-Z */ + FusionAxesAlignmentNYPZNX, /* -Y+Z-X */ + FusionAxesAlignmentPZPYNX, /* +Z+Y-X */ + FusionAxesAlignmentPZPXPY, /* +Z+X+Y */ + FusionAxesAlignmentPZNYPX, /* +Z-Y+X */ + FusionAxesAlignmentPZNXNY, /* +Z-X-Y */ + FusionAxesAlignmentNZPYPX, /* -Z+Y+X */ + FusionAxesAlignmentNZNXPY, /* -Z-X+Y */ + FusionAxesAlignmentNZNYNX, /* -Z-Y-X */ + FusionAxesAlignmentNZPXNY, /* -Z+X-Y */ +} FusionAxesAlignment; + +//------------------------------------------------------------------------------ +// Inline functions + +/** + * @brief Swaps sensor axes for alignment with the body axes. + * @param sensor Sensor axes. + * @param alignment Axes alignment. + * @return Sensor axes aligned with the body axes. + */ +static inline FusionVector FusionAxesSwap(const FusionVector sensor, const FusionAxesAlignment alignment) +{ + FusionVector result; + switch (alignment) { + case FusionAxesAlignmentPXPYPZ: + break; + case FusionAxesAlignmentPXNZPY: + result.axis.x = +sensor.axis.x; + result.axis.y = -sensor.axis.z; + result.axis.z = +sensor.axis.y; + return result; + case FusionAxesAlignmentPXNYNZ: + result.axis.x = +sensor.axis.x; + result.axis.y = -sensor.axis.y; + result.axis.z = -sensor.axis.z; + return result; + case FusionAxesAlignmentPXPZNY: + result.axis.x = +sensor.axis.x; + result.axis.y = +sensor.axis.z; + result.axis.z = -sensor.axis.y; + return result; + case FusionAxesAlignmentNXPYNZ: + result.axis.x = -sensor.axis.x; + result.axis.y = +sensor.axis.y; + result.axis.z = -sensor.axis.z; + return result; + case FusionAxesAlignmentNXPZPY: + result.axis.x = -sensor.axis.x; + result.axis.y = +sensor.axis.z; + result.axis.z = +sensor.axis.y; + return result; + case FusionAxesAlignmentNXNYPZ: + result.axis.x = -sensor.axis.x; + result.axis.y = -sensor.axis.y; + result.axis.z = +sensor.axis.z; + return result; + case FusionAxesAlignmentNXNZNY: + result.axis.x = -sensor.axis.x; + result.axis.y = -sensor.axis.z; + result.axis.z = -sensor.axis.y; + return result; + case FusionAxesAlignmentPYNXPZ: + result.axis.x = +sensor.axis.y; + result.axis.y = -sensor.axis.x; + result.axis.z = +sensor.axis.z; + return result; + case FusionAxesAlignmentPYNZNX: + result.axis.x = +sensor.axis.y; + result.axis.y = -sensor.axis.z; + result.axis.z = -sensor.axis.x; + return result; + case FusionAxesAlignmentPYPXNZ: + result.axis.x = +sensor.axis.y; + result.axis.y = +sensor.axis.x; + result.axis.z = -sensor.axis.z; + return result; + case FusionAxesAlignmentPYPZPX: + result.axis.x = +sensor.axis.y; + result.axis.y = +sensor.axis.z; + result.axis.z = +sensor.axis.x; + return result; + case FusionAxesAlignmentNYPXPZ: + result.axis.x = -sensor.axis.y; + result.axis.y = +sensor.axis.x; + result.axis.z = +sensor.axis.z; + return result; + case FusionAxesAlignmentNYNZPX: + result.axis.x = -sensor.axis.y; + result.axis.y = -sensor.axis.z; + result.axis.z = +sensor.axis.x; + return result; + case FusionAxesAlignmentNYNXNZ: + result.axis.x = -sensor.axis.y; + result.axis.y = -sensor.axis.x; + result.axis.z = -sensor.axis.z; + return result; + case FusionAxesAlignmentNYPZNX: + result.axis.x = -sensor.axis.y; + result.axis.y = +sensor.axis.z; + result.axis.z = -sensor.axis.x; + return result; + case FusionAxesAlignmentPZPYNX: + result.axis.x = +sensor.axis.z; + result.axis.y = +sensor.axis.y; + result.axis.z = -sensor.axis.x; + return result; + case FusionAxesAlignmentPZPXPY: + result.axis.x = +sensor.axis.z; + result.axis.y = +sensor.axis.x; + result.axis.z = +sensor.axis.y; + return result; + case FusionAxesAlignmentPZNYPX: + result.axis.x = +sensor.axis.z; + result.axis.y = -sensor.axis.y; + result.axis.z = +sensor.axis.x; + return result; + case FusionAxesAlignmentPZNXNY: + result.axis.x = +sensor.axis.z; + result.axis.y = -sensor.axis.x; + result.axis.z = -sensor.axis.y; + return result; + case FusionAxesAlignmentNZPYPX: + result.axis.x = -sensor.axis.z; + result.axis.y = +sensor.axis.y; + result.axis.z = +sensor.axis.x; + return result; + case FusionAxesAlignmentNZNXPY: + result.axis.x = -sensor.axis.z; + result.axis.y = -sensor.axis.x; + result.axis.z = +sensor.axis.y; + return result; + case FusionAxesAlignmentNZNYNX: + result.axis.x = -sensor.axis.z; + result.axis.y = -sensor.axis.y; + result.axis.z = -sensor.axis.x; + return result; + case FusionAxesAlignmentNZPXNY: + result.axis.x = -sensor.axis.z; + result.axis.y = +sensor.axis.x; + result.axis.z = -sensor.axis.y; + return result; + } + return sensor; // avoid compiler warning +} + +#endif + +//------------------------------------------------------------------------------ +// End of file diff --git a/src/Fusion/FusionCalibration.h b/src/Fusion/FusionCalibration.h new file mode 100644 index 000000000..be7102b73 --- /dev/null +++ b/src/Fusion/FusionCalibration.h @@ -0,0 +1,49 @@ +/** + * @file FusionCalibration.h + * @author Seb Madgwick + * @brief Gyroscope, accelerometer, and magnetometer calibration models. + */ + +#ifndef FUSION_CALIBRATION_H +#define FUSION_CALIBRATION_H + +//------------------------------------------------------------------------------ +// Includes + +#include "FusionMath.h" + +//------------------------------------------------------------------------------ +// Inline functions + +/** + * @brief Gyroscope and accelerometer calibration model. + * @param uncalibrated Uncalibrated measurement. + * @param misalignment Misalignment matrix. + * @param sensitivity Sensitivity. + * @param offset Offset. + * @return Calibrated measurement. + */ +static inline FusionVector FusionCalibrationInertial(const FusionVector uncalibrated, const FusionMatrix misalignment, + const FusionVector sensitivity, const FusionVector offset) +{ + return FusionMatrixMultiplyVector(misalignment, + FusionVectorHadamardProduct(FusionVectorSubtract(uncalibrated, offset), sensitivity)); +} + +/** + * @brief Magnetometer calibration model. + * @param uncalibrated Uncalibrated measurement. + * @param softIronMatrix Soft-iron matrix. + * @param hardIronOffset Hard-iron offset. + * @return Calibrated measurement. + */ +static inline FusionVector FusionCalibrationMagnetic(const FusionVector uncalibrated, const FusionMatrix softIronMatrix, + const FusionVector hardIronOffset) +{ + return FusionMatrixMultiplyVector(softIronMatrix, FusionVectorSubtract(uncalibrated, hardIronOffset)); +} + +#endif + +//------------------------------------------------------------------------------ +// End of file diff --git a/src/Fusion/FusionCompass.c b/src/Fusion/FusionCompass.c new file mode 100644 index 000000000..6a6f9591a --- /dev/null +++ b/src/Fusion/FusionCompass.c @@ -0,0 +1,51 @@ +/** + * @file FusionCompass.c + * @author Seb Madgwick + * @brief Tilt-compensated compass to calculate the magnetic heading using + * accelerometer and magnetometer measurements. + */ + +//------------------------------------------------------------------------------ +// Includes + +#include "FusionCompass.h" +#include "FusionAxes.h" +#include // atan2f + +//------------------------------------------------------------------------------ +// Functions + +/** + * @brief Calculates the magnetic heading. + * @param convention Earth axes convention. + * @param accelerometer Accelerometer measurement in any calibrated units. + * @param magnetometer Magnetometer measurement in any calibrated units. + * @return Heading angle in degrees. + */ +float FusionCompassCalculateHeading(const FusionConvention convention, const FusionVector accelerometer, + const FusionVector magnetometer) +{ + switch (convention) { + case FusionConventionNwu: { + const FusionVector west = FusionVectorNormalise(FusionVectorCrossProduct(accelerometer, magnetometer)); + const FusionVector north = FusionVectorNormalise(FusionVectorCrossProduct(west, accelerometer)); + return FusionRadiansToDegrees(atan2f(west.axis.x, north.axis.x)); + } + case FusionConventionEnu: { + const FusionVector west = FusionVectorNormalise(FusionVectorCrossProduct(accelerometer, magnetometer)); + const FusionVector north = FusionVectorNormalise(FusionVectorCrossProduct(west, accelerometer)); + const FusionVector east = FusionVectorMultiplyScalar(west, -1.0f); + return FusionRadiansToDegrees(atan2f(north.axis.x, east.axis.x)); + } + case FusionConventionNed: { + const FusionVector up = FusionVectorMultiplyScalar(accelerometer, -1.0f); + const FusionVector west = FusionVectorNormalise(FusionVectorCrossProduct(up, magnetometer)); + const FusionVector north = FusionVectorNormalise(FusionVectorCrossProduct(west, up)); + return FusionRadiansToDegrees(atan2f(west.axis.x, north.axis.x)); + } + } + return 0; // avoid compiler warning +} + +//------------------------------------------------------------------------------ +// End of file diff --git a/src/Fusion/FusionCompass.h b/src/Fusion/FusionCompass.h new file mode 100644 index 000000000..a3d0b466a --- /dev/null +++ b/src/Fusion/FusionCompass.h @@ -0,0 +1,26 @@ +/** + * @file FusionCompass.h + * @author Seb Madgwick + * @brief Tilt-compensated compass to calculate the magnetic heading using + * accelerometer and magnetometer measurements. + */ + +#ifndef FUSION_COMPASS_H +#define FUSION_COMPASS_H + +//------------------------------------------------------------------------------ +// Includes + +#include "FusionConvention.h" +#include "FusionMath.h" + +//------------------------------------------------------------------------------ +// Function declarations + +float FusionCompassCalculateHeading(const FusionConvention convention, const FusionVector accelerometer, + const FusionVector magnetometer); + +#endif + +//------------------------------------------------------------------------------ +// End of file diff --git a/src/Fusion/FusionConvention.h b/src/Fusion/FusionConvention.h new file mode 100644 index 000000000..0b0d43adc --- /dev/null +++ b/src/Fusion/FusionConvention.h @@ -0,0 +1,25 @@ +/** + * @file FusionConvention.h + * @author Seb Madgwick + * @brief Earth axes convention. + */ + +#ifndef FUSION_CONVENTION_H +#define FUSION_CONVENTION_H + +//------------------------------------------------------------------------------ +// Definitions + +/** + * @brief Earth axes convention. + */ +typedef enum { + FusionConventionNwu, /* North-West-Up */ + FusionConventionEnu, /* East-North-Up */ + FusionConventionNed, /* North-East-Down */ +} FusionConvention; + +#endif + +//------------------------------------------------------------------------------ +// End of file diff --git a/src/Fusion/FusionMath.h b/src/Fusion/FusionMath.h new file mode 100644 index 000000000..c3fc34b2d --- /dev/null +++ b/src/Fusion/FusionMath.h @@ -0,0 +1,503 @@ +/** + * @file FusionMath.h + * @author Seb Madgwick + * @brief Math library. + */ + +#ifndef FUSION_MATH_H +#define FUSION_MATH_H + +//------------------------------------------------------------------------------ +// Includes + +#include // M_PI, sqrtf, atan2f, asinf +#include +#include + +//------------------------------------------------------------------------------ +// Definitions + +/** + * @brief 3D vector. + */ +typedef union { + float array[3]; + + struct { + float x; + float y; + float z; + } axis; +} FusionVector; + +/** + * @brief Quaternion. + */ +typedef union { + float array[4]; + + struct { + float w; + float x; + float y; + float z; + } element; +} FusionQuaternion; + +/** + * @brief 3x3 matrix in row-major order. + * See http://en.wikipedia.org/wiki/Row-major_order + */ +typedef union { + float array[3][3]; + + struct { + float xx; + float xy; + float xz; + float yx; + float yy; + float yz; + float zx; + float zy; + float zz; + } element; +} FusionMatrix; + +/** + * @brief Euler angles. Roll, pitch, and yaw correspond to rotations around + * X, Y, and Z respectively. + */ +typedef union { + float array[3]; + + struct { + float roll; + float pitch; + float yaw; + } angle; +} FusionEuler; + +/** + * @brief Vector of zeros. + */ +#define FUSION_VECTOR_ZERO ((FusionVector){.array = {0.0f, 0.0f, 0.0f}}) + +/** + * @brief Vector of ones. + */ +#define FUSION_VECTOR_ONES ((FusionVector){.array = {1.0f, 1.0f, 1.0f}}) + +/** + * @brief Identity quaternion. + */ +#define FUSION_IDENTITY_QUATERNION ((FusionQuaternion){.array = {1.0f, 0.0f, 0.0f, 0.0f}}) + +/** + * @brief Identity matrix. + */ +#define FUSION_IDENTITY_MATRIX ((FusionMatrix){.array = {{1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}}}) + +/** + * @brief Euler angles of zero. + */ +#define FUSION_EULER_ZERO ((FusionEuler){.array = {0.0f, 0.0f, 0.0f}}) + +/** + * @brief Pi. May not be defined in math.h. + */ +#ifndef M_PI +#define M_PI (3.14159265358979323846) +#endif + +/** + * @brief Include this definition or add as a preprocessor definition to use + * normal square root operations. + */ +// #define FUSION_USE_NORMAL_SQRT + +//------------------------------------------------------------------------------ +// Inline functions - Degrees and radians conversion + +/** + * @brief Converts degrees to radians. + * @param degrees Degrees. + * @return Radians. + */ +static inline float FusionDegreesToRadians(const float degrees) +{ + return degrees * ((float)M_PI / 180.0f); +} + +/** + * @brief Converts radians to degrees. + * @param radians Radians. + * @return Degrees. + */ +static inline float FusionRadiansToDegrees(const float radians) +{ + return radians * (180.0f / (float)M_PI); +} + +//------------------------------------------------------------------------------ +// Inline functions - Arc sine + +/** + * @brief Returns the arc sine of the value. + * @param value Value. + * @return Arc sine of the value. + */ +static inline float FusionAsin(const float value) +{ + if (value <= -1.0f) { + return (float)M_PI / -2.0f; + } + if (value >= 1.0f) { + return (float)M_PI / 2.0f; + } + return asinf(value); +} + +//------------------------------------------------------------------------------ +// Inline functions - Fast inverse square root + +#ifndef FUSION_USE_NORMAL_SQRT + +/** + * @brief Calculates the reciprocal of the square root. + * See https://pizer.wordpress.com/2008/10/12/fast-inverse-square-root/ + * @param x Operand. + * @return Reciprocal of the square root of x. + */ +static inline float FusionFastInverseSqrt(const float x) +{ + + typedef union { + float f; + int32_t i; + } Union32; + + Union32 union32 = {.f = x}; + union32.i = 0x5F1F1412 - (union32.i >> 1); + return union32.f * (1.69000231f - 0.714158168f * x * union32.f * union32.f); +} + +#endif + +//------------------------------------------------------------------------------ +// Inline functions - Vector operations + +/** + * @brief Returns true if the vector is zero. + * @param vector Vector. + * @return True if the vector is zero. + */ +static inline bool FusionVectorIsZero(const FusionVector vector) +{ + return (vector.axis.x == 0.0f) && (vector.axis.y == 0.0f) && (vector.axis.z == 0.0f); +} + +/** + * @brief Returns the sum of two vectors. + * @param vectorA Vector A. + * @param vectorB Vector B. + * @return Sum of two vectors. + */ +static inline FusionVector FusionVectorAdd(const FusionVector vectorA, const FusionVector vectorB) +{ + const FusionVector result = {.axis = { + .x = vectorA.axis.x + vectorB.axis.x, + .y = vectorA.axis.y + vectorB.axis.y, + .z = vectorA.axis.z + vectorB.axis.z, + }}; + return result; +} + +/** + * @brief Returns vector B subtracted from vector A. + * @param vectorA Vector A. + * @param vectorB Vector B. + * @return Vector B subtracted from vector A. + */ +static inline FusionVector FusionVectorSubtract(const FusionVector vectorA, const FusionVector vectorB) +{ + const FusionVector result = {.axis = { + .x = vectorA.axis.x - vectorB.axis.x, + .y = vectorA.axis.y - vectorB.axis.y, + .z = vectorA.axis.z - vectorB.axis.z, + }}; + return result; +} + +/** + * @brief Returns the sum of the elements. + * @param vector Vector. + * @return Sum of the elements. + */ +static inline float FusionVectorSum(const FusionVector vector) +{ + return vector.axis.x + vector.axis.y + vector.axis.z; +} + +/** + * @brief Returns the multiplication of a vector by a scalar. + * @param vector Vector. + * @param scalar Scalar. + * @return Multiplication of a vector by a scalar. + */ +static inline FusionVector FusionVectorMultiplyScalar(const FusionVector vector, const float scalar) +{ + const FusionVector result = {.axis = { + .x = vector.axis.x * scalar, + .y = vector.axis.y * scalar, + .z = vector.axis.z * scalar, + }}; + return result; +} + +/** + * @brief Calculates the Hadamard product (element-wise multiplication). + * @param vectorA Vector A. + * @param vectorB Vector B. + * @return Hadamard product. + */ +static inline FusionVector FusionVectorHadamardProduct(const FusionVector vectorA, const FusionVector vectorB) +{ + const FusionVector result = {.axis = { + .x = vectorA.axis.x * vectorB.axis.x, + .y = vectorA.axis.y * vectorB.axis.y, + .z = vectorA.axis.z * vectorB.axis.z, + }}; + return result; +} + +/** + * @brief Returns the cross product. + * @param vectorA Vector A. + * @param vectorB Vector B. + * @return Cross product. + */ +static inline FusionVector FusionVectorCrossProduct(const FusionVector vectorA, const FusionVector vectorB) +{ +#define A vectorA.axis +#define B vectorB.axis + const FusionVector result = {.axis = { + .x = A.y * B.z - A.z * B.y, + .y = A.z * B.x - A.x * B.z, + .z = A.x * B.y - A.y * B.x, + }}; + return result; +#undef A +#undef B +} + +/** + * @brief Returns the dot product. + * @param vectorA Vector A. + * @param vectorB Vector B. + * @return Dot product. + */ +static inline float FusionVectorDotProduct(const FusionVector vectorA, const FusionVector vectorB) +{ + return FusionVectorSum(FusionVectorHadamardProduct(vectorA, vectorB)); +} + +/** + * @brief Returns the vector magnitude squared. + * @param vector Vector. + * @return Vector magnitude squared. + */ +static inline float FusionVectorMagnitudeSquared(const FusionVector vector) +{ + return FusionVectorSum(FusionVectorHadamardProduct(vector, vector)); +} + +/** + * @brief Returns the vector magnitude. + * @param vector Vector. + * @return Vector magnitude. + */ +static inline float FusionVectorMagnitude(const FusionVector vector) +{ + return sqrtf(FusionVectorMagnitudeSquared(vector)); +} + +/** + * @brief Returns the normalised vector. + * @param vector Vector. + * @return Normalised vector. + */ +static inline FusionVector FusionVectorNormalise(const FusionVector vector) +{ +#ifdef FUSION_USE_NORMAL_SQRT + const float magnitudeReciprocal = 1.0f / sqrtf(FusionVectorMagnitudeSquared(vector)); +#else + const float magnitudeReciprocal = FusionFastInverseSqrt(FusionVectorMagnitudeSquared(vector)); +#endif + return FusionVectorMultiplyScalar(vector, magnitudeReciprocal); +} + +//------------------------------------------------------------------------------ +// Inline functions - Quaternion operations + +/** + * @brief Returns the sum of two quaternions. + * @param quaternionA Quaternion A. + * @param quaternionB Quaternion B. + * @return Sum of two quaternions. + */ +static inline FusionQuaternion FusionQuaternionAdd(const FusionQuaternion quaternionA, const FusionQuaternion quaternionB) +{ + const FusionQuaternion result = {.element = { + .w = quaternionA.element.w + quaternionB.element.w, + .x = quaternionA.element.x + quaternionB.element.x, + .y = quaternionA.element.y + quaternionB.element.y, + .z = quaternionA.element.z + quaternionB.element.z, + }}; + return result; +} + +/** + * @brief Returns the multiplication of two quaternions. + * @param quaternionA Quaternion A (to be post-multiplied). + * @param quaternionB Quaternion B (to be pre-multiplied). + * @return Multiplication of two quaternions. + */ +static inline FusionQuaternion FusionQuaternionMultiply(const FusionQuaternion quaternionA, const FusionQuaternion quaternionB) +{ +#define A quaternionA.element +#define B quaternionB.element + const FusionQuaternion result = {.element = { + .w = A.w * B.w - A.x * B.x - A.y * B.y - A.z * B.z, + .x = A.w * B.x + A.x * B.w + A.y * B.z - A.z * B.y, + .y = A.w * B.y - A.x * B.z + A.y * B.w + A.z * B.x, + .z = A.w * B.z + A.x * B.y - A.y * B.x + A.z * B.w, + }}; + return result; +#undef A +#undef B +} + +/** + * @brief Returns the multiplication of a quaternion with a vector. This is a + * normal quaternion multiplication where the vector is treated a + * quaternion with a W element value of zero. The quaternion is post- + * multiplied by the vector. + * @param quaternion Quaternion. + * @param vector Vector. + * @return Multiplication of a quaternion with a vector. + */ +static inline FusionQuaternion FusionQuaternionMultiplyVector(const FusionQuaternion quaternion, const FusionVector vector) +{ +#define Q quaternion.element +#define V vector.axis + const FusionQuaternion result = {.element = { + .w = -Q.x * V.x - Q.y * V.y - Q.z * V.z, + .x = Q.w * V.x + Q.y * V.z - Q.z * V.y, + .y = Q.w * V.y - Q.x * V.z + Q.z * V.x, + .z = Q.w * V.z + Q.x * V.y - Q.y * V.x, + }}; + return result; +#undef Q +#undef V +} + +/** + * @brief Returns the normalised quaternion. + * @param quaternion Quaternion. + * @return Normalised quaternion. + */ +static inline FusionQuaternion FusionQuaternionNormalise(const FusionQuaternion quaternion) +{ +#define Q quaternion.element +#ifdef FUSION_USE_NORMAL_SQRT + const float magnitudeReciprocal = 1.0f / sqrtf(Q.w * Q.w + Q.x * Q.x + Q.y * Q.y + Q.z * Q.z); +#else + const float magnitudeReciprocal = FusionFastInverseSqrt(Q.w * Q.w + Q.x * Q.x + Q.y * Q.y + Q.z * Q.z); +#endif + const FusionQuaternion result = {.element = { + .w = Q.w * magnitudeReciprocal, + .x = Q.x * magnitudeReciprocal, + .y = Q.y * magnitudeReciprocal, + .z = Q.z * magnitudeReciprocal, + }}; + return result; +#undef Q +} + +//------------------------------------------------------------------------------ +// Inline functions - Matrix operations + +/** + * @brief Returns the multiplication of a matrix with a vector. + * @param matrix Matrix. + * @param vector Vector. + * @return Multiplication of a matrix with a vector. + */ +static inline FusionVector FusionMatrixMultiplyVector(const FusionMatrix matrix, const FusionVector vector) +{ +#define R matrix.element + const FusionVector result = {.axis = { + .x = R.xx * vector.axis.x + R.xy * vector.axis.y + R.xz * vector.axis.z, + .y = R.yx * vector.axis.x + R.yy * vector.axis.y + R.yz * vector.axis.z, + .z = R.zx * vector.axis.x + R.zy * vector.axis.y + R.zz * vector.axis.z, + }}; + return result; +#undef R +} + +//------------------------------------------------------------------------------ +// Inline functions - Conversion operations + +/** + * @brief Converts a quaternion to a rotation matrix. + * @param quaternion Quaternion. + * @return Rotation matrix. + */ +static inline FusionMatrix FusionQuaternionToMatrix(const FusionQuaternion quaternion) +{ +#define Q quaternion.element + const float qwqw = Q.w * Q.w; // calculate common terms to avoid repeated operations + const float qwqx = Q.w * Q.x; + const float qwqy = Q.w * Q.y; + const float qwqz = Q.w * Q.z; + const float qxqy = Q.x * Q.y; + const float qxqz = Q.x * Q.z; + const float qyqz = Q.y * Q.z; + const FusionMatrix matrix = {.element = { + .xx = 2.0f * (qwqw - 0.5f + Q.x * Q.x), + .xy = 2.0f * (qxqy - qwqz), + .xz = 2.0f * (qxqz + qwqy), + .yx = 2.0f * (qxqy + qwqz), + .yy = 2.0f * (qwqw - 0.5f + Q.y * Q.y), + .yz = 2.0f * (qyqz - qwqx), + .zx = 2.0f * (qxqz - qwqy), + .zy = 2.0f * (qyqz + qwqx), + .zz = 2.0f * (qwqw - 0.5f + Q.z * Q.z), + }}; + return matrix; +#undef Q +} + +/** + * @brief Converts a quaternion to ZYX Euler angles in degrees. + * @param quaternion Quaternion. + * @return Euler angles in degrees. + */ +static inline FusionEuler FusionQuaternionToEuler(const FusionQuaternion quaternion) +{ +#define Q quaternion.element + const float halfMinusQySquared = 0.5f - Q.y * Q.y; // calculate common terms to avoid repeated operations + const FusionEuler euler = {.angle = { + .roll = FusionRadiansToDegrees(atan2f(Q.w * Q.x + Q.y * Q.z, halfMinusQySquared - Q.x * Q.x)), + .pitch = FusionRadiansToDegrees(FusionAsin(2.0f * (Q.w * Q.y - Q.z * Q.x))), + .yaw = FusionRadiansToDegrees(atan2f(Q.w * Q.z + Q.x * Q.y, halfMinusQySquared - Q.z * Q.z)), + }}; + return euler; +#undef Q +} + +#endif + +//------------------------------------------------------------------------------ +// End of file diff --git a/src/Fusion/FusionOffset.c b/src/Fusion/FusionOffset.c new file mode 100644 index 000000000..d4334c874 --- /dev/null +++ b/src/Fusion/FusionOffset.c @@ -0,0 +1,80 @@ +/** + * @file FusionOffset.c + * @author Seb Madgwick + * @brief Gyroscope offset correction algorithm for run-time calibration of the + * gyroscope offset. + */ + +//------------------------------------------------------------------------------ +// Includes + +#include "FusionOffset.h" +#include // fabsf + +//------------------------------------------------------------------------------ +// Definitions + +/** + * @brief Cutoff frequency in Hz. + */ +#define CUTOFF_FREQUENCY (0.02f) + +/** + * @brief Timeout in seconds. + */ +#define TIMEOUT (5) + +/** + * @brief Threshold in degrees per second. + */ +#define THRESHOLD (3.0f) + +//------------------------------------------------------------------------------ +// Functions + +/** + * @brief Initialises the gyroscope offset algorithm. + * @param offset Gyroscope offset algorithm structure. + * @param sampleRate Sample rate in Hz. + */ +void FusionOffsetInitialise(FusionOffset *const offset, const unsigned int sampleRate) +{ + offset->filterCoefficient = 2.0f * (float)M_PI * CUTOFF_FREQUENCY * (1.0f / (float)sampleRate); + offset->timeout = TIMEOUT * sampleRate; + offset->timer = 0; + offset->gyroscopeOffset = FUSION_VECTOR_ZERO; +} + +/** + * @brief Updates the gyroscope offset algorithm and returns the corrected + * gyroscope measurement. + * @param offset Gyroscope offset algorithm structure. + * @param gyroscope Gyroscope measurement in degrees per second. + * @return Corrected gyroscope measurement in degrees per second. + */ +FusionVector FusionOffsetUpdate(FusionOffset *const offset, FusionVector gyroscope) +{ + + // Subtract offset from gyroscope measurement + gyroscope = FusionVectorSubtract(gyroscope, offset->gyroscopeOffset); + + // Reset timer if gyroscope not stationary + if ((fabsf(gyroscope.axis.x) > THRESHOLD) || (fabsf(gyroscope.axis.y) > THRESHOLD) || (fabsf(gyroscope.axis.z) > THRESHOLD)) { + offset->timer = 0; + return gyroscope; + } + + // Increment timer while gyroscope stationary + if (offset->timer < offset->timeout) { + offset->timer++; + return gyroscope; + } + + // Adjust offset if timer has elapsed + offset->gyroscopeOffset = + FusionVectorAdd(offset->gyroscopeOffset, FusionVectorMultiplyScalar(gyroscope, offset->filterCoefficient)); + return gyroscope; +} + +//------------------------------------------------------------------------------ +// End of file diff --git a/src/Fusion/FusionOffset.h b/src/Fusion/FusionOffset.h new file mode 100644 index 000000000..51ae4a896 --- /dev/null +++ b/src/Fusion/FusionOffset.h @@ -0,0 +1,40 @@ +/** + * @file FusionOffset.h + * @author Seb Madgwick + * @brief Gyroscope offset correction algorithm for run-time calibration of the + * gyroscope offset. + */ + +#ifndef FUSION_OFFSET_H +#define FUSION_OFFSET_H + +//------------------------------------------------------------------------------ +// Includes + +#include "FusionMath.h" + +//------------------------------------------------------------------------------ +// Definitions + +/** + * @brief Gyroscope offset algorithm structure. Structure members are used + * internally and must not be accessed by the application. + */ +typedef struct { + float filterCoefficient; + unsigned int timeout; + unsigned int timer; + FusionVector gyroscopeOffset; +} FusionOffset; + +//------------------------------------------------------------------------------ +// Function declarations + +void FusionOffsetInitialise(FusionOffset *const offset, const unsigned int sampleRate); + +FusionVector FusionOffsetUpdate(FusionOffset *const offset, FusionVector gyroscope); + +#endif + +//------------------------------------------------------------------------------ +// End of file diff --git a/src/configuration.h b/src/configuration.h index 462210cf2..62c48a205 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -144,6 +144,7 @@ along with this program. If not, see . #define LIS3DH_ADR 0x18 #define BMA423_ADDR 0x19 #define LSM6DS3_ADDR 0x6A +#define BMX160_ADDR 0x69 // ----------------------------------------------------------------------------- // LED diff --git a/src/detect/ScanI2C.cpp b/src/detect/ScanI2C.cpp index 149bb95f0..3231f7054 100644 --- a/src/detect/ScanI2C.cpp +++ b/src/detect/ScanI2C.cpp @@ -36,8 +36,8 @@ ScanI2C::FoundDevice ScanI2C::firstKeyboard() const ScanI2C::FoundDevice ScanI2C::firstAccelerometer() const { - ScanI2C::DeviceType types[] = {MPU6050, LIS3DH, BMA423, LSM6DS3}; - return firstOfOrNONE(4, types); + ScanI2C::DeviceType types[] = {MPU6050, LIS3DH, BMA423, LSM6DS3, BMX160}; + return firstOfOrNONE(5, types); } ScanI2C::FoundDevice ScanI2C::find(ScanI2C::DeviceType) const diff --git a/src/detect/ScanI2C.h b/src/detect/ScanI2C.h index 13dd66763..20994ede1 100644 --- a/src/detect/ScanI2C.h +++ b/src/detect/ScanI2C.h @@ -49,7 +49,8 @@ class ScanI2C OPT3001, MLX90632, AHT10, - DFROBOT_LARK, + BMX160, + DFROBOT_LARK } DeviceType; // typedef uint8_t DeviceAddress; diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index 86099ad19..f800a9963 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -342,6 +342,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port) SCAN_SIMPLE_CASE(PMSA0031_ADDR, PMSA0031, "PMSA0031 air quality sensor found\n") SCAN_SIMPLE_CASE(MPU6050_ADDR, MPU6050, "MPU6050 accelerometer found\n"); + SCAN_SIMPLE_CASE(BMX160_ADDR, BMX160, "BMX160 accelerometer found\n"); SCAN_SIMPLE_CASE(BMA423_ADDR, BMA423, "BMA423 accelerometer found\n"); SCAN_SIMPLE_CASE(LSM6DS3_ADDR, LSM6DS3, "LSM6DS3 accelerometer found at address 0x%x\n", (uint8_t)addr.address); SCAN_SIMPLE_CASE(TCA9555_ADDR, TCA9555, "TCA9555 I2C expander found\n"); diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 1c9484f62..5a892bbfb 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -1516,9 +1516,13 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_ } bool hasNodeHeading = false; - if (ourNode && hasValidPosition(ourNode)) { + if (ourNode && (hasValidPosition(ourNode) || screen->hasHeading())) { const meshtastic_PositionLite &op = ourNode->position; - float myHeading = estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i)); + float myHeading; + if (screen->hasHeading()) + myHeading = (screen->getHeading()) * PI / 180; // gotta convert compass degrees to Radians + else + myHeading = estimatedHeading(DegD(op.latitude_i), DegD(op.longitude_i)); drawCompassNorth(display, compassX, compassY, myHeading); if (hasValidPosition(node)) { diff --git a/src/graphics/Screen.h b/src/graphics/Screen.h index 7f8d078e7..f4d719715 100644 --- a/src/graphics/Screen.h +++ b/src/graphics/Screen.h @@ -204,6 +204,17 @@ class Screen : public concurrency::OSThread enqueueCmd(cmd); } + // Function to allow the AccelerometerThread to set the heading if a sensor provides it + // Mutex needed? + void setHeading(long _heading) + { + hasCompass = true; + compassHeading = _heading; + } + + bool hasHeading() { return hasCompass; } + + long getHeading() { return compassHeading; } // functions for display brightness void increaseBrightness(); void decreaseBrightness(); @@ -428,6 +439,8 @@ class Screen : public concurrency::OSThread // Implementation to Adjust Brightness uint8_t brightness = BRIGHTNESS_DEFAULT; // H = 254, MH = 192, ML = 130 L = 103 + bool hasCompass = false; + float compassHeading; /// Holds state for debug information DebugInfo debugInfo; diff --git a/src/main.h b/src/main.h index db05a4734..2ef7edb3a 100644 --- a/src/main.h +++ b/src/main.h @@ -53,6 +53,9 @@ extern Adafruit_DRV2605 drv; extern AudioThread *audioThread; #endif +// Global Screen singleton. +extern graphics::Screen *screen; + #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR #include "AccelerometerThread.h" extern AccelerometerThread *accelerometerThread; @@ -62,9 +65,6 @@ extern bool isVibrating; extern int TCPPort; // set by Portduino -// Global Screen singleton. -extern graphics::Screen *screen; - // extern Observable newPowerStatus; //TODO: move this to main-esp32.cpp somehow or a helper class // extern meshtastic::PowerStatus *powerStatus; diff --git a/variants/rak4631/platformio.ini b/variants/rak4631/platformio.ini index f64811429..24f209b01 100644 --- a/variants/rak4631/platformio.ini +++ b/variants/rak4631/platformio.ini @@ -16,6 +16,7 @@ lib_deps = melopero/Melopero RV3028@^1.1.0 https://github.com/RAKWireless/RAK13800-W5100S.git#1.0.2 rakwireless/RAKwireless NCP5623 RGB LED library@^1.0.2 + beegee-tokyo/RAKwireless RAK12034@^1.0.0 debug_tool = jlink ; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm) ;upload_protocol = jlink \ No newline at end of file diff --git a/variants/rak4631_epaper/platformio.ini b/variants/rak4631_epaper/platformio.ini index 1ca9a2157..08342dcf7 100644 --- a/variants/rak4631_epaper/platformio.ini +++ b/variants/rak4631_epaper/platformio.ini @@ -13,6 +13,7 @@ lib_deps = zinggjm/GxEPD2@^1.4.9 melopero/Melopero RV3028@^1.1.0 rakwireless/RAKwireless NCP5623 RGB LED library@^1.0.2 + beegee-tokyo/RAKwireless RAK12034@^1.0.0 debug_tool = jlink ; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm) ;upload_protocol = jlink \ No newline at end of file diff --git a/variants/rak4631_epaper_onrxtx/platformio.ini b/variants/rak4631_epaper_onrxtx/platformio.ini index e0a0a5a58..f7035a1b1 100644 --- a/variants/rak4631_epaper_onrxtx/platformio.ini +++ b/variants/rak4631_epaper_onrxtx/platformio.ini @@ -15,7 +15,8 @@ lib_deps = zinggjm/GxEPD2@^1.5.1 melopero/Melopero RV3028@^1.1.0 rakwireless/RAKwireless NCP5623 RGB LED library@^1.0.2 + beegee-tokyo/RAKwireless RAK12034@^1.0.0 debug_tool = jlink ; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm) ;upload_protocol = jlink -;upload_port = /dev/ttyACM3 +;upload_port = /dev/ttyACM3 \ No newline at end of file From e63278cf431f9d403c79d8006a750a967208a3d0 Mon Sep 17 00:00:00 2001 From: Tavis Date: Tue, 11 Jun 2024 15:13:17 -1000 Subject: [PATCH 67/80] add wind speed and direction to json --- src/mqtt/MQTT.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index f3eda6d7c..566eb352d 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -675,6 +675,8 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp) msgPayload["lux"] = new JSONValue(decoded->variant.environment_metrics.lux); msgPayload["white_lux"] = new JSONValue(decoded->variant.environment_metrics.white_lux); msgPayload["iaq"] = new JSONValue((uint)decoded->variant.environment_metrics.iaq); + msgPayload["wind_speed"] = new JSONValue((uint)decoded->variant.environment_metrics.wind_speed); + msgPayload["wind_direction"] = new JSONValue((uint)decoded->variant.environment_metrics.wind_direction); } else if (decoded->which_variant == meshtastic_Telemetry_power_metrics_tag) { msgPayload["voltage_ch1"] = new JSONValue(decoded->variant.power_metrics.ch1_voltage); msgPayload["current_ch1"] = new JSONValue(decoded->variant.power_metrics.ch1_current); From d60d1d74477a5ad3f5d6785b8157f255bb0bbfd4 Mon Sep 17 00:00:00 2001 From: todd-herbert Date: Wed, 12 Jun 2024 23:34:00 +1200 Subject: [PATCH 68/80] Workaround to disable bluetooth on NRF52 (#4055) * Workaround to allow bluetooth disable on NRF52 * Use miminum tx power for bluetooth * Reorganize * Instantiate nrf52Bluetooth correctly.. * Change log message --- src/platform/nrf52/NRF52Bluetooth.cpp | 12 ++++++ src/platform/nrf52/NRF52Bluetooth.h | 1 + src/platform/nrf52/main-nrf52.cpp | 55 ++++++++++++++++++--------- 3 files changed, 50 insertions(+), 18 deletions(-) diff --git a/src/platform/nrf52/NRF52Bluetooth.cpp b/src/platform/nrf52/NRF52Bluetooth.cpp index 39898ab25..4c25f38ea 100644 --- a/src/platform/nrf52/NRF52Bluetooth.cpp +++ b/src/platform/nrf52/NRF52Bluetooth.cpp @@ -215,6 +215,18 @@ void NRF52Bluetooth::shutdown() Bluefruit.Advertising.stop(); } +void NRF52Bluetooth::startDisabled() +{ + // Setup Bluetooth + nrf52Bluetooth->setup(); + + // Shutdown bluetooth for minimum power draw + Bluefruit.Advertising.stop(); + Bluefruit.setTxPower(-40); // Minimum power + + LOG_INFO("Disabling NRF52 Bluetooth. (Workaround: tx power min, advertising stopped)\n"); +} + bool NRF52Bluetooth::isConnected() { return Bluefruit.connected(connectionHandle); diff --git a/src/platform/nrf52/NRF52Bluetooth.h b/src/platform/nrf52/NRF52Bluetooth.h index 11e18c127..450af47f9 100644 --- a/src/platform/nrf52/NRF52Bluetooth.h +++ b/src/platform/nrf52/NRF52Bluetooth.h @@ -8,6 +8,7 @@ class NRF52Bluetooth : BluetoothApi public: void setup(); void shutdown(); + void startDisabled(); void resumeAdvertising(); void clearBonds(); bool isConnected(); diff --git a/src/platform/nrf52/main-nrf52.cpp b/src/platform/nrf52/main-nrf52.cpp index 9cc52a7de..1f2c6867d 100644 --- a/src/platform/nrf52/main-nrf52.cpp +++ b/src/platform/nrf52/main-nrf52.cpp @@ -68,28 +68,47 @@ static const bool useSoftDevice = true; // Set to false for easier debugging #if !MESHTASTIC_EXCLUDE_BLUETOOTH void setBluetoothEnable(bool enable) { - if (enable && config.bluetooth.enabled) { - if (!useSoftDevice) { + // For debugging use: don't use bluetooth + if (!useSoftDevice) { + if (enable) LOG_INFO("DISABLING NRF52 BLUETOOTH WHILE DEBUGGING\n"); - } else { - if (!nrf52Bluetooth) { - LOG_DEBUG("Initializing NRF52 Bluetooth\n"); - nrf52Bluetooth = new NRF52Bluetooth(); - nrf52Bluetooth->setup(); - - // We delay brownout init until after BLE because BLE starts soft device - initBrownout(); - } else { - nrf52Bluetooth->resumeAdvertising(); - } - } - } else { - if (nrf52Bluetooth) { - nrf52Bluetooth->shutdown(); - } + return; } + + // If user disabled bluetooth: init then disable advertising & reduce power + // Workaround. Avoid issue where device hangs several days after boot.. + // Allegedly, no significant increase in power consumption + if (!config.bluetooth.enabled) { + static bool initialized = false; + if (!initialized) { + nrf52Bluetooth = new NRF52Bluetooth(); + nrf52Bluetooth->startDisabled(); + initBrownout(); + initialized = true; + } + return; + } + + if (enable) { + // If not yet set-up + if (!nrf52Bluetooth) { + LOG_DEBUG("Initializing NRF52 Bluetooth\n"); + nrf52Bluetooth = new NRF52Bluetooth(); + nrf52Bluetooth->setup(); + + // We delay brownout init until after BLE because BLE starts soft device + initBrownout(); + } + // Already setup, apparently + else + nrf52Bluetooth->resumeAdvertising(); + } + // Disable (if previously set-up) + else if (nrf52Bluetooth) + nrf52Bluetooth->shutdown(); } #else +#warning NRF52 "Bluetooth disable" workaround does not apply to builds with MESHTASTIC_EXCLUDE_BLUETOOTH void setBluetoothEnable(bool enable) {} #endif /** From 992d1c42e6d73f46e818fb8178d8e067d48bdec0 Mon Sep 17 00:00:00 2001 From: Jan Veeh <33117982+craft4tnt@users.noreply.github.com> Date: Wed, 12 Jun 2024 13:43:50 +0200 Subject: [PATCH 69/80] changed CFG-PM config message to use external signal (#4062) --- src/gps/ubx.h | 61 ++++++++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/src/gps/ubx.h b/src/gps/ubx.h index 0a382a8a3..df03c1634 100644 --- a/src/gps/ubx.h +++ b/src/gps/ubx.h @@ -319,6 +319,7 @@ const uint8_t GPS::_message_SAVE[] = { // As the M10 has no flash, the best we can do to preserve the config is to set it in RAM and BBR. // BBR will survive a restart, and power off for a while, but modules with small backup // batteries or super caps will not retain the config for a long power off time. +// for all configurations using sleep / low power modes, V_BCKP needs to be hooked to permanent power for fast aquisition after sleep // VALSET Commands for M10 // Please refer to the M10 Protocol Specification: @@ -327,40 +328,44 @@ const uint8_t GPS::_message_SAVE[] = { // and: // https://content.u-blox.com/sites/default/files/u-blox-M10-ROM-5.10_ReleaseNotes_UBX-22001426.pdf // for interesting insights. +// +// Integration manual: +// https://content.u-blox.com/sites/default/files/documents/SAM-M10Q_IntegrationManual_UBX-22020019.pdf +// has details on low-power modes + /* CFG-PM2 has been replaced by many CFG-PM commands -OPERATEMODE E1 2 (0 | 1 | 2) -POSUPDATEPERIOD U4 1000ms for M10 must be >= 5s try 5 -ACQPERIOD U4 10 seems ok for M10 def ok -GRIDOFFSET U4 0 seems ok for M10 def ok -ONTIME U2 1 will try 1 -MINACQTIME U1 0 will try 0 def ok -MAXACQTIME U1 stick with default of 0 def ok -DONOTENTEROFF L 1 stay at 1 -WAITTIMEFIX L 1 stay with 1 -UPDATEEPH L 1 changed to 1 for gps rework default is 1 -EXTINTWAKE L 0 no ext ints -EXTINTBACKUP L 0 no ext ints -EXTINTINACTIVE L 0 no ext ints -EXTINTACTIVITY U4 0 no ext ints -LIMITPEAKCURRENT L 1 stay with 1 -*/ -// CFG-PMS has been removed +CFG-PMS has been removed + +CFG-PM-OPERATEMODE E1 (0 | 1 | 2) -> 1 (PSMOO), because sporadic position updates are required instead of continous tracking <10s (PSMCT) +CFG-PM-POSUPDATEPERIOD U4 -> 0ms, no self-timed wakup because receiver power mode is controlled via "software standby mode" by legacy UBX-RXM-PMREQ request +CFG-PM-ACQPERIOD U4 -> 0ms, because receiver power mode is controlled via "software standby mode" by legacy UBX-RXM-PMREQ request +CFG-PM-ONTIME U4 -> 0ms, optional I guess +CFG-PM-EXTINTBACKUP L -> 1, force receiver into BACKUP mode when EXTINT (should be connected to GPS_EN_PIN) pin is "low" + +This is required because the receiver never enters low power mode if microcontroller is in deep-sleep. +Maybe the changing UART_RX levels trigger a wakeup but even with UBX-RXM-PMREQ[12] = 0x00 (all external wakeup sources disabled) the receivcer remains +in aquisition state -> potentially a bug + +Workaround: Control the EXTINT pin by the GPS_EN_PIN signal + +As mentioned in the M10 operational issues down below, power save won't allow the use of BDS B1C. +CFG-SIGNAL-BDS_B1C_ENA L -> 0 // Ram layer config message: -// b5 62 06 8a 26 00 00 01 00 00 01 00 d0 20 02 02 00 d0 40 05 00 00 00 05 00 d0 30 01 00 08 00 d0 10 01 09 00 d0 10 01 10 00 d0 -// 10 01 8b de +// 01 01 00 00 01 00 D0 20 01 02 00 D0 40 00 00 00 00 03 00 D0 40 00 00 00 00 05 00 D0 30 00 00 0D 00 D0 10 01 // BBR layer config message: -// b5 62 06 8a 26 00 00 02 00 00 01 00 d0 20 02 02 00 d0 40 05 00 00 00 05 00 d0 30 01 00 08 00 d0 10 01 09 00 d0 10 01 10 00 d0 -// 10 01 8c 03 - -const uint8_t GPS::_message_VALSET_PM_RAM[] = {0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0xd0, 0x20, 0x02, 0x02, 0x00, 0xd0, 0x40, - 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0xd0, 0x30, 0x01, 0x00, 0x08, 0x00, 0xd0, - 0x10, 0x01, 0x09, 0x00, 0xd0, 0x10, 0x01, 0x10, 0x00, 0xd0, 0x10, 0x01}; -const uint8_t GPS::_message_VALSET_PM_BBR[] = {0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0xd0, 0x20, 0x02, 0x02, 0x00, 0xd0, 0x40, - 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0xd0, 0x30, 0x01, 0x00, 0x08, 0x00, 0xd0, - 0x10, 0x01, 0x09, 0x00, 0xd0, 0x10, 0x01, 0x10, 0x00, 0xd0, 0x10, 0x01}; +// 01 02 00 00 01 00 D0 20 01 02 00 D0 40 00 00 00 00 03 00 D0 40 00 00 00 00 05 00 D0 30 00 00 0D 00 D0 10 01 +*/ +const uint8_t GPS::_message_VALSET_PM_RAM[] = {0x01, 0x01, 0x00, 0x00, 0x0F, 0x00, 0x31, 0x10, 0x00, 0x01, 0x00, 0xD0, 0x20, + 0x01, 0x02, 0x00, 0xD0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xD0, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0xD0, 0x30, 0x00, 0x00, 0x0D, 0x00, 0xD0, + 0x10, 0x01}; +const uint8_t GPS::_message_VALSET_PM_BBR[] = {0x01, 0x02, 0x00, 0x00, 0x0F, 0x00, 0x31, 0x10, 0x00, 0x01, 0x00, 0xD0, 0x20, + 0x01, 0x02, 0x00, 0xD0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xD0, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0xD0, 0x30, 0x00, 0x00, 0x0D, 0x00, 0xD0, + 0x10, 0x01}; /* CFG-ITFM replaced by 5 valset messages which can be combined into one for RAM and one for BBR From b09cee118c5f17c9d9e38473896b041776a3faea Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Wed, 12 Jun 2024 06:57:11 -0500 Subject: [PATCH 70/80] Trunk --- src/gps/ubx.h | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/src/gps/ubx.h b/src/gps/ubx.h index df03c1634..0852c331d 100644 --- a/src/gps/ubx.h +++ b/src/gps/ubx.h @@ -319,7 +319,8 @@ const uint8_t GPS::_message_SAVE[] = { // As the M10 has no flash, the best we can do to preserve the config is to set it in RAM and BBR. // BBR will survive a restart, and power off for a while, but modules with small backup // batteries or super caps will not retain the config for a long power off time. -// for all configurations using sleep / low power modes, V_BCKP needs to be hooked to permanent power for fast aquisition after sleep +// for all configurations using sleep / low power modes, V_BCKP needs to be hooked to permanent power for fast aquisition after +// sleep // VALSET Commands for M10 // Please refer to the M10 Protocol Specification: @@ -337,15 +338,15 @@ const uint8_t GPS::_message_SAVE[] = { CFG-PM2 has been replaced by many CFG-PM commands CFG-PMS has been removed -CFG-PM-OPERATEMODE E1 (0 | 1 | 2) -> 1 (PSMOO), because sporadic position updates are required instead of continous tracking <10s (PSMCT) -CFG-PM-POSUPDATEPERIOD U4 -> 0ms, no self-timed wakup because receiver power mode is controlled via "software standby mode" by legacy UBX-RXM-PMREQ request -CFG-PM-ACQPERIOD U4 -> 0ms, because receiver power mode is controlled via "software standby mode" by legacy UBX-RXM-PMREQ request -CFG-PM-ONTIME U4 -> 0ms, optional I guess -CFG-PM-EXTINTBACKUP L -> 1, force receiver into BACKUP mode when EXTINT (should be connected to GPS_EN_PIN) pin is "low" +CFG-PM-OPERATEMODE E1 (0 | 1 | 2) -> 1 (PSMOO), because sporadic position updates are required instead of continous tracking <10s +(PSMCT) CFG-PM-POSUPDATEPERIOD U4 -> 0ms, no self-timed wakup because receiver power mode is controlled via "software standby +mode" by legacy UBX-RXM-PMREQ request CFG-PM-ACQPERIOD U4 -> 0ms, because receiver power mode is controlled via "software standby +mode" by legacy UBX-RXM-PMREQ request CFG-PM-ONTIME U4 -> 0ms, optional I guess CFG-PM-EXTINTBACKUP L -> 1, force receiver into +BACKUP mode when EXTINT (should be connected to GPS_EN_PIN) pin is "low" This is required because the receiver never enters low power mode if microcontroller is in deep-sleep. -Maybe the changing UART_RX levels trigger a wakeup but even with UBX-RXM-PMREQ[12] = 0x00 (all external wakeup sources disabled) the receivcer remains -in aquisition state -> potentially a bug +Maybe the changing UART_RX levels trigger a wakeup but even with UBX-RXM-PMREQ[12] = 0x00 (all external wakeup sources disabled) +the receivcer remains in aquisition state -> potentially a bug Workaround: Control the EXTINT pin by the GPS_EN_PIN signal @@ -358,14 +359,12 @@ CFG-SIGNAL-BDS_B1C_ENA L -> 0 // BBR layer config message: // 01 02 00 00 01 00 D0 20 01 02 00 D0 40 00 00 00 00 03 00 D0 40 00 00 00 00 05 00 D0 30 00 00 0D 00 D0 10 01 */ -const uint8_t GPS::_message_VALSET_PM_RAM[] = {0x01, 0x01, 0x00, 0x00, 0x0F, 0x00, 0x31, 0x10, 0x00, 0x01, 0x00, 0xD0, 0x20, - 0x01, 0x02, 0x00, 0xD0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xD0, 0x40, - 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0xD0, 0x30, 0x00, 0x00, 0x0D, 0x00, 0xD0, - 0x10, 0x01}; -const uint8_t GPS::_message_VALSET_PM_BBR[] = {0x01, 0x02, 0x00, 0x00, 0x0F, 0x00, 0x31, 0x10, 0x00, 0x01, 0x00, 0xD0, 0x20, - 0x01, 0x02, 0x00, 0xD0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xD0, 0x40, - 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0xD0, 0x30, 0x00, 0x00, 0x0D, 0x00, 0xD0, - 0x10, 0x01}; +const uint8_t GPS::_message_VALSET_PM_RAM[] = {0x01, 0x01, 0x00, 0x00, 0x0F, 0x00, 0x31, 0x10, 0x00, 0x01, 0x00, 0xD0, 0x20, 0x01, + 0x02, 0x00, 0xD0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xD0, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x05, 0x00, 0xD0, 0x30, 0x00, 0x00, 0x0D, 0x00, 0xD0, 0x10, 0x01}; +const uint8_t GPS::_message_VALSET_PM_BBR[] = {0x01, 0x02, 0x00, 0x00, 0x0F, 0x00, 0x31, 0x10, 0x00, 0x01, 0x00, 0xD0, 0x20, 0x01, + 0x02, 0x00, 0xD0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xD0, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x05, 0x00, 0xD0, 0x30, 0x00, 0x00, 0x0D, 0x00, 0xD0, 0x10, 0x01}; /* CFG-ITFM replaced by 5 valset messages which can be combined into one for RAM and one for BBR From 5b1d3ed173fc1eddd8dc8e494095e4353223ccfe Mon Sep 17 00:00:00 2001 From: Heltec-Aaron-Lee Date: Wed, 12 Jun 2024 20:21:26 +0800 Subject: [PATCH 71/80] Add Heltec Capsule Sensor V3 to source code --- platformio.ini | 1 + src/ButtonThread.cpp | 4 ++ src/Power.cpp | 25 +++++++---- src/platform/esp32/architecture.h | 2 + .../heltec_capsule_sensor_v3/platformio.ini | 11 +++++ variants/heltec_capsule_sensor_v3/variant.h | 42 +++++++++++++++++++ 6 files changed, 78 insertions(+), 7 deletions(-) create mode 100644 variants/heltec_capsule_sensor_v3/platformio.ini create mode 100644 variants/heltec_capsule_sensor_v3/variant.h diff --git a/platformio.ini b/platformio.ini index 7ed794a6e..9c29d2d67 100644 --- a/platformio.ini +++ b/platformio.ini @@ -33,6 +33,7 @@ default_envs = tbeam ;default_envs = wio-e5 ;default_envs = radiomaster_900_bandit_nano ;default_envs = radiomaster_900_bandit_micro +;default_envs = heltec_capsule_sensor_v3 extra_configs = arch/*/*.ini diff --git a/src/ButtonThread.cpp b/src/ButtonThread.cpp index 7e678d69d..4b3bb3fbc 100644 --- a/src/ButtonThread.cpp +++ b/src/ButtonThread.cpp @@ -41,7 +41,11 @@ ButtonThread::ButtonThread() : OSThread("Button") } #elif defined(BUTTON_PIN) int pin = config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN; // Resolved button pin +#if defined(HELTEC_CAPSULE_SENSOR_V3) + this->userButton = OneButton(pin, false, false); +#else this->userButton = OneButton(pin, true, true); +#endif LOG_DEBUG("Using GPIO%02d for button\n", pin); #endif diff --git a/src/Power.cpp b/src/Power.cpp index b80d8a0d5..d80bfd55c 100644 --- a/src/Power.cpp +++ b/src/Power.cpp @@ -335,13 +335,20 @@ class AnalogBatteryLevel : public HasBatteryLevel virtual bool isVbusIn() override { #ifdef EXT_PWR_DETECT - // if external powered that pin will be pulled up - if (digitalRead(EXT_PWR_DETECT) == HIGH) { - return true; - } - // if it's not HIGH - check the battery + #ifdef HELTEC_CAPSULE_SENSOR_V3 + // if external powered that pin will be pulled down + if (digitalRead(EXT_PWR_DETECT) == LOW) { + return true; + } + // if it's not LOW - check the battery + #else + // if external powered that pin will be pulled up + if (digitalRead(EXT_PWR_DETECT) == HIGH) { + return true; + } + // if it's not HIGH - check the battery + #endif #endif - return getBattVoltage() > chargingVolt; } @@ -421,7 +428,11 @@ Power::Power() : OSThread("Power") bool Power::analogInit() { #ifdef EXT_PWR_DETECT - pinMode(EXT_PWR_DETECT, INPUT); + #ifdef HELTEC_CAPSULE_SENSOR_V3 + pinMode(EXT_PWR_DETECT, INPUT_PULLUP); + #else + pinMode(EXT_PWR_DETECT, INPUT); + #endif #endif #ifdef EXT_CHRG_DETECT pinMode(EXT_CHRG_DETECT, ext_chrg_detect_mode); diff --git a/src/platform/esp32/architecture.h b/src/platform/esp32/architecture.h index 824c11bdd..c979d016c 100644 --- a/src/platform/esp32/architecture.h +++ b/src/platform/esp32/architecture.h @@ -147,6 +147,8 @@ #define HW_VENDOR meshtastic_HardwareModel_WIPHONE #elif defined(RADIOMASTER_900_BANDIT_NANO) #define HW_VENDOR meshtastic_HardwareModel_RADIOMASTER_900_BANDIT_NANO +#elif defined(HELTEC_CAPSULE_SENSOR_V3) +#define HW_VENDOR meshtastic_HardwareModel_HELTEC_CAPSULE_SENSOR_V3 #endif // ----------------------------------------------------------------------------- diff --git a/variants/heltec_capsule_sensor_v3/platformio.ini b/variants/heltec_capsule_sensor_v3/platformio.ini new file mode 100644 index 000000000..f1aef925d --- /dev/null +++ b/variants/heltec_capsule_sensor_v3/platformio.ini @@ -0,0 +1,11 @@ +[env:heltec_capsule_sensor_v3] +extends = esp32s3_base +board = heltec_wifi_lora_32_V3 +board_check = true + +build_flags = + ${esp32s3_base.build_flags} -I variants/heltec_capsule_sensor_v3 + -D HELTEC_CAPSULE_SENSOR_V3 + -D GPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely. + ;-D DEBUG_DISABLED ; uncomment this line to disable DEBUG output + diff --git a/variants/heltec_capsule_sensor_v3/variant.h b/variants/heltec_capsule_sensor_v3/variant.h new file mode 100644 index 000000000..0d5ab73cf --- /dev/null +++ b/variants/heltec_capsule_sensor_v3/variant.h @@ -0,0 +1,42 @@ +#define LED_PIN 33 +#define LED_PIN2 34 +#define EXT_PWR_DETECT 35 + +#define BUTTON_PIN 18 + +#define BATTERY_PIN 7 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage +#define ADC_CHANNEL ADC1_GPIO7_CHANNEL +#define ADC_ATTENUATION ADC_ATTEN_DB_2_5 // lower dB for high resistance voltage divider +#define ADC_MULTIPLIER (4.9 * 1.045) +#define ADC_CTRL 36 // active HIGH, powers the voltage divider. Only on 1.1 +#define ADC_CTRL_ENABLED HIGH + +#undef GPS_RX_PIN +#undef GPS_TX_PIN +#define GPS_RX_PIN 5 +#define GPS_TX_PIN 4 +#define PIN_GPS_RESET 3 +#define GPS_RESET_MODE LOW +#define PIN_GPS_PPS 1 +#define PIN_GPS_EN 21 +#define GPS_EN_ACTIVE HIGH + +#define USE_SX1262 +#define LORA_DIO0 -1 // a No connect on the SX1262 module +#define LORA_RESET 12 +#define LORA_DIO1 14 // SX1262 IRQ +#define LORA_DIO2 13 // SX1262 BUSY +#define LORA_DIO3 // Not connected on PCB, but internally on the TTGO SX1262, if DIO3 is high the TXCO is enabled + +#define LORA_SCK 9 +#define LORA_MISO 11 +#define LORA_MOSI 10 +#define LORA_CS 8 + +#define SX126X_CS LORA_CS +#define SX126X_DIO1 LORA_DIO1 +#define SX126X_BUSY LORA_DIO2 +#define SX126X_RESET LORA_RESET + +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 From c7769274dd417017bf06a01e5215e61054567cfd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 12 Jun 2024 07:23:54 -0500 Subject: [PATCH 72/80] [create-pull-request] automated change (#4085) Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com> --- protobufs | 2 +- src/mesh/generated/meshtastic/mesh.pb.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/protobufs b/protobufs index 8c8048798..8f4faf76e 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 8c8048798c1b1773b9d8f2c32eb3f4c9e72f8218 +Subproject commit 8f4faf76e52c2ef63c582c26642d312d9781b7c0 diff --git a/src/mesh/generated/meshtastic/mesh.pb.h b/src/mesh/generated/meshtastic/mesh.pb.h index ad97cb80f..0e9e6a28d 100644 --- a/src/mesh/generated/meshtastic/mesh.pb.h +++ b/src/mesh/generated/meshtastic/mesh.pb.h @@ -161,6 +161,8 @@ typedef enum _meshtastic_HardwareModel { /* RadioMaster 900 Bandit Nano, https://www.radiomasterrc.com/products/bandit-nano-expresslrs-rf-module ESP32-D0WDQ6 With SX1276/SKY66122, SSD1306 OLED and No GPS */ meshtastic_HardwareModel_RADIOMASTER_900_BANDIT_NANO = 64, + /* Heltec Capsule Sensor V3 with ESP32-S3 CPU, Portable LoRa device that can replace GNSS modules or sensors */ + meshtastic_HardwareModel_HELTEC_CAPSULE_SENSOR_V3 = 65, /* ------------------------------------------------------------------------------------------------------------------------------------------ Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits. ------------------------------------------------------------------------------------------------------------------------------------------ */ From 871f6854b5751b88fbb3b3905970125f6ffb4285 Mon Sep 17 00:00:00 2001 From: John Gorkos - AB0OO Date: Wed, 12 Jun 2024 08:22:01 -0700 Subject: [PATCH 73/80] feature-mqtt: add hop_start and hop_limit to MQTT uplink --- src/mqtt/MQTT.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index 566eb352d..905c2b7d3 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -902,7 +902,9 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp) jsonObj["snr"] = new JSONValue((float)mp->rx_snr); if (mp->hop_start != 0 && mp->hop_limit <= mp->hop_start) jsonObj["hops_away"] = new JSONValue((unsigned int)(mp->hop_start - mp->hop_limit)); - + jsonObj["hop_start"] = new JSONValue((unsigned int)(mp->hop_start)); + jsonObj["hop_limit"] = new JSONValue((unsigned int)(mp->hop_limit)); + // serialize and write it to the stream JSONValue *value = new JSONValue(jsonObj); std::string jsonStr = value->Stringify(); From d80bcd7d67df2876b9536cd1418bec64171269e9 Mon Sep 17 00:00:00 2001 From: John Gorkos - AB0OO Date: Wed, 12 Jun 2024 12:59:52 -0700 Subject: [PATCH 74/80] adding only hop_start, per @GUVWAF --- src/mqtt/MQTT.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index 905c2b7d3..4f685cd7a 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -903,7 +903,6 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp) if (mp->hop_start != 0 && mp->hop_limit <= mp->hop_start) jsonObj["hops_away"] = new JSONValue((unsigned int)(mp->hop_start - mp->hop_limit)); jsonObj["hop_start"] = new JSONValue((unsigned int)(mp->hop_start)); - jsonObj["hop_limit"] = new JSONValue((unsigned int)(mp->hop_limit)); // serialize and write it to the stream JSONValue *value = new JSONValue(jsonObj); From b42185c722c27e17523bf2474079915f8eca7f04 Mon Sep 17 00:00:00 2001 From: John Gorkos - AB0OO Date: Wed, 12 Jun 2024 13:02:01 -0700 Subject: [PATCH 75/80] included hop_start in conditional for hop_away --- src/mqtt/MQTT.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index 4f685cd7a..d93166ce9 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -900,9 +900,10 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp) jsonObj["rssi"] = new JSONValue((int)mp->rx_rssi); if (mp->rx_snr != 0) jsonObj["snr"] = new JSONValue((float)mp->rx_snr); - if (mp->hop_start != 0 && mp->hop_limit <= mp->hop_start) + if (mp->hop_start != 0 && mp->hop_limit <= mp->hop_start) { jsonObj["hops_away"] = new JSONValue((unsigned int)(mp->hop_start - mp->hop_limit)); - jsonObj["hop_start"] = new JSONValue((unsigned int)(mp->hop_start)); + jsonObj["hop_start"] = new JSONValue((unsigned int)(mp->hop_start)); + } // serialize and write it to the stream JSONValue *value = new JSONValue(jsonObj); From f7433eb4ee772477493545800da88eafc1455e96 Mon Sep 17 00:00:00 2001 From: John Gorkos - AB0OO Date: Wed, 12 Jun 2024 14:36:38 -0700 Subject: [PATCH 76/80] trunk formatting --- src/mqtt/MQTT.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index d93166ce9..9f9ac5c24 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -904,7 +904,7 @@ std::string MQTT::meshPacketToJson(meshtastic_MeshPacket *mp) jsonObj["hops_away"] = new JSONValue((unsigned int)(mp->hop_start - mp->hop_limit)); jsonObj["hop_start"] = new JSONValue((unsigned int)(mp->hop_start)); } - + // serialize and write it to the stream JSONValue *value = new JSONValue(jsonObj); std::string jsonStr = value->Stringify(); From 26d4d06e2a2359d35f349eaf15b6a703058bacff Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 13 Jun 2024 08:39:38 -0500 Subject: [PATCH 77/80] [create-pull-request] automated change (#4093) Co-authored-by: caveman99 <25002+caveman99@users.noreply.github.com> --- protobufs | 2 +- .../generated/meshtastic/telemetry.pb.cpp | 3 ++ src/mesh/generated/meshtastic/telemetry.pb.h | 30 +++++++++++++++++-- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/protobufs b/protobufs index 8f4faf76e..260d24318 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 8f4faf76e52c2ef63c582c26642d312d9781b7c0 +Subproject commit 260d24318d811518171ed2916c94c0cfd94eb9d4 diff --git a/src/mesh/generated/meshtastic/telemetry.pb.cpp b/src/mesh/generated/meshtastic/telemetry.pb.cpp index 6388e37a0..c93483a15 100644 --- a/src/mesh/generated/meshtastic/telemetry.pb.cpp +++ b/src/mesh/generated/meshtastic/telemetry.pb.cpp @@ -21,5 +21,8 @@ PB_BIND(meshtastic_AirQualityMetrics, meshtastic_AirQualityMetrics, AUTO) PB_BIND(meshtastic_Telemetry, meshtastic_Telemetry, AUTO) +PB_BIND(meshtastic_Nau7802Config, meshtastic_Nau7802Config, AUTO) + + diff --git a/src/mesh/generated/meshtastic/telemetry.pb.h b/src/mesh/generated/meshtastic/telemetry.pb.h index 02b0bdd6d..47961cd7d 100644 --- a/src/mesh/generated/meshtastic/telemetry.pb.h +++ b/src/mesh/generated/meshtastic/telemetry.pb.h @@ -61,7 +61,9 @@ typedef enum _meshtastic_TelemetrySensorType { /* AHT10 Integrated temperature and humidity sensor */ meshtastic_TelemetrySensorType_AHT10 = 23, /* DFRobot Lark Weather station (temperature, humidity, pressure, wind speed and direction) */ - meshtastic_TelemetrySensorType_DFROBOT_LARK = 24 + meshtastic_TelemetrySensorType_DFROBOT_LARK = 24, + /* NAU7802 Scale Chip or compatible */ + meshtastic_TelemetrySensorType_NAU7802 = 25 } meshtastic_TelemetrySensorType; /* Struct definitions */ @@ -174,6 +176,14 @@ typedef struct _meshtastic_Telemetry { } variant; } meshtastic_Telemetry; +/* NAU7802 Telemetry configuration, for saving to flash */ +typedef struct _meshtastic_Nau7802Config { + /* The offset setting for the NAU7802 */ + int32_t zeroOffset; + /* The calibration factor for the NAU7802 */ + float calibrationFactor; +} meshtastic_Nau7802Config; + #ifdef __cplusplus extern "C" { @@ -181,8 +191,9 @@ extern "C" { /* Helper constants for enums */ #define _meshtastic_TelemetrySensorType_MIN meshtastic_TelemetrySensorType_SENSOR_UNSET -#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_DFROBOT_LARK -#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_DFROBOT_LARK+1)) +#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_NAU7802 +#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_NAU7802+1)) + @@ -196,11 +207,13 @@ extern "C" { #define meshtastic_PowerMetrics_init_default {0, 0, 0, 0, 0, 0} #define meshtastic_AirQualityMetrics_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_Telemetry_init_default {0, 0, {meshtastic_DeviceMetrics_init_default}} +#define meshtastic_Nau7802Config_init_default {0, 0} #define meshtastic_DeviceMetrics_init_zero {0, 0, 0, 0, 0} #define meshtastic_EnvironmentMetrics_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_PowerMetrics_init_zero {0, 0, 0, 0, 0, 0} #define meshtastic_AirQualityMetrics_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_Telemetry_init_zero {0, 0, {meshtastic_DeviceMetrics_init_zero}} +#define meshtastic_Nau7802Config_init_zero {0, 0} /* Field tags (for use in manual encoding/decoding) */ #define meshtastic_DeviceMetrics_battery_level_tag 1 @@ -245,6 +258,8 @@ extern "C" { #define meshtastic_Telemetry_environment_metrics_tag 3 #define meshtastic_Telemetry_air_quality_metrics_tag 4 #define meshtastic_Telemetry_power_metrics_tag 5 +#define meshtastic_Nau7802Config_zeroOffset_tag 1 +#define meshtastic_Nau7802Config_calibrationFactor_tag 2 /* Struct field encoding specification for nanopb */ #define meshtastic_DeviceMetrics_FIELDLIST(X, a) \ @@ -313,11 +328,18 @@ X(a, STATIC, ONEOF, MESSAGE, (variant,power_metrics,variant.power_metrics) #define meshtastic_Telemetry_variant_air_quality_metrics_MSGTYPE meshtastic_AirQualityMetrics #define meshtastic_Telemetry_variant_power_metrics_MSGTYPE meshtastic_PowerMetrics +#define meshtastic_Nau7802Config_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, INT32, zeroOffset, 1) \ +X(a, STATIC, SINGULAR, FLOAT, calibrationFactor, 2) +#define meshtastic_Nau7802Config_CALLBACK NULL +#define meshtastic_Nau7802Config_DEFAULT NULL + extern const pb_msgdesc_t meshtastic_DeviceMetrics_msg; extern const pb_msgdesc_t meshtastic_EnvironmentMetrics_msg; extern const pb_msgdesc_t meshtastic_PowerMetrics_msg; extern const pb_msgdesc_t meshtastic_AirQualityMetrics_msg; extern const pb_msgdesc_t meshtastic_Telemetry_msg; +extern const pb_msgdesc_t meshtastic_Nau7802Config_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define meshtastic_DeviceMetrics_fields &meshtastic_DeviceMetrics_msg @@ -325,12 +347,14 @@ extern const pb_msgdesc_t meshtastic_Telemetry_msg; #define meshtastic_PowerMetrics_fields &meshtastic_PowerMetrics_msg #define meshtastic_AirQualityMetrics_fields &meshtastic_AirQualityMetrics_msg #define meshtastic_Telemetry_fields &meshtastic_Telemetry_msg +#define meshtastic_Nau7802Config_fields &meshtastic_Nau7802Config_msg /* Maximum encoded size of messages (where known) */ #define MESHTASTIC_MESHTASTIC_TELEMETRY_PB_H_MAX_SIZE meshtastic_Telemetry_size #define meshtastic_AirQualityMetrics_size 72 #define meshtastic_DeviceMetrics_size 27 #define meshtastic_EnvironmentMetrics_size 68 +#define meshtastic_Nau7802Config_size 16 #define meshtastic_PowerMetrics_size 30 #define meshtastic_Telemetry_size 79 From 75d5cd2c356eaa2ff76b1b360325091a92b44d89 Mon Sep 17 00:00:00 2001 From: caveman99 <25002+caveman99@users.noreply.github.com> Date: Thu, 13 Jun 2024 14:50:21 +0000 Subject: [PATCH 78/80] [create-pull-request] automated change --- protobufs | 2 +- src/mesh/generated/meshtastic/telemetry.pb.h | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/protobufs b/protobufs index 260d24318..ab576a4a1 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 260d24318d811518171ed2916c94c0cfd94eb9d4 +Subproject commit ab576a4a122c1a1d0a3c2235b0a0cf3bd4a83c65 diff --git a/src/mesh/generated/meshtastic/telemetry.pb.h b/src/mesh/generated/meshtastic/telemetry.pb.h index 47961cd7d..28d368754 100644 --- a/src/mesh/generated/meshtastic/telemetry.pb.h +++ b/src/mesh/generated/meshtastic/telemetry.pb.h @@ -113,6 +113,8 @@ typedef struct _meshtastic_EnvironmentMetrics { uint16_t wind_direction; /* Wind speed in m/s */ float wind_speed; + /* Weight in KG */ + float weight; } meshtastic_EnvironmentMetrics; /* Power Metrics (voltage / current / etc) */ @@ -203,13 +205,13 @@ extern "C" { /* Initializer values for message structs */ #define meshtastic_DeviceMetrics_init_default {0, 0, 0, 0, 0} -#define meshtastic_EnvironmentMetrics_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +#define meshtastic_EnvironmentMetrics_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_PowerMetrics_init_default {0, 0, 0, 0, 0, 0} #define meshtastic_AirQualityMetrics_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_Telemetry_init_default {0, 0, {meshtastic_DeviceMetrics_init_default}} #define meshtastic_Nau7802Config_init_default {0, 0} #define meshtastic_DeviceMetrics_init_zero {0, 0, 0, 0, 0} -#define meshtastic_EnvironmentMetrics_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +#define meshtastic_EnvironmentMetrics_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_PowerMetrics_init_zero {0, 0, 0, 0, 0, 0} #define meshtastic_AirQualityMetrics_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} #define meshtastic_Telemetry_init_zero {0, 0, {meshtastic_DeviceMetrics_init_zero}} @@ -235,6 +237,7 @@ extern "C" { #define meshtastic_EnvironmentMetrics_uv_lux_tag 12 #define meshtastic_EnvironmentMetrics_wind_direction_tag 13 #define meshtastic_EnvironmentMetrics_wind_speed_tag 14 +#define meshtastic_EnvironmentMetrics_weight_tag 15 #define meshtastic_PowerMetrics_ch1_voltage_tag 1 #define meshtastic_PowerMetrics_ch1_current_tag 2 #define meshtastic_PowerMetrics_ch2_voltage_tag 3 @@ -285,7 +288,8 @@ X(a, STATIC, SINGULAR, FLOAT, white_lux, 10) \ X(a, STATIC, SINGULAR, FLOAT, ir_lux, 11) \ X(a, STATIC, SINGULAR, FLOAT, uv_lux, 12) \ X(a, STATIC, SINGULAR, UINT32, wind_direction, 13) \ -X(a, STATIC, SINGULAR, FLOAT, wind_speed, 14) +X(a, STATIC, SINGULAR, FLOAT, wind_speed, 14) \ +X(a, STATIC, SINGULAR, FLOAT, weight, 15) #define meshtastic_EnvironmentMetrics_CALLBACK NULL #define meshtastic_EnvironmentMetrics_DEFAULT NULL @@ -353,10 +357,10 @@ extern const pb_msgdesc_t meshtastic_Nau7802Config_msg; #define MESHTASTIC_MESHTASTIC_TELEMETRY_PB_H_MAX_SIZE meshtastic_Telemetry_size #define meshtastic_AirQualityMetrics_size 72 #define meshtastic_DeviceMetrics_size 27 -#define meshtastic_EnvironmentMetrics_size 68 +#define meshtastic_EnvironmentMetrics_size 73 #define meshtastic_Nau7802Config_size 16 #define meshtastic_PowerMetrics_size 30 -#define meshtastic_Telemetry_size 79 +#define meshtastic_Telemetry_size 80 #ifdef __cplusplus } /* extern "C" */ From 85bca8a32a09d75d786a16d8908c0582389a1d7d Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Thu, 13 Jun 2024 11:13:18 -0500 Subject: [PATCH 79/80] Update lark to ref to clear C++ warning --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index 9c29d2d67..2064bac48 100644 --- a/platformio.ini +++ b/platformio.ini @@ -143,4 +143,4 @@ lib_deps = ClosedCube OPT3001@^1.1.2 emotibit/EmotiBit MLX90632@^1.0.8 dfrobot/DFRobot_RTU@^1.0.3 - https://github.com/meshtastic/DFRobot_LarkWeatherStation#0e884fc86b7a0b602c7ff3d26b893b997f15c6ac \ No newline at end of file + https://github.com/meshtastic/DFRobot_LarkWeatherStation#dee914270dc7cb3e43fbf034edd85a63a16a12ee \ No newline at end of file From 16b41b51af7ea2ae3b0c9ad4e3b0afb4e0051797 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Thu, 13 Jun 2024 12:05:14 -0500 Subject: [PATCH 80/80] Update OLED ref --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index 2064bac48..34471fc54 100644 --- a/platformio.ini +++ b/platformio.ini @@ -78,7 +78,7 @@ monitor_speed = 115200 lib_deps = jgromes/RadioLib@~6.6.0 - https://github.com/meshtastic/esp8266-oled-ssd1306.git#ee628ee6c9588d4c56c9e3da35f0fc9448ad54a8 ; ESP8266_SSD1306 + https://github.com/meshtastic/esp8266-oled-ssd1306.git#69ba98fa30e67b12d4577b121f210f3eb7049d6b ; ESP8266_SSD1306 mathertel/OneButton@^2.5.0 ; OneButton library for non-blocking button debounce https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159 https://github.com/meshtastic/TinyGPSPlus.git#71a82db35f3b973440044c476d4bcdc673b104f4