Skip to content

Commit 8703381

Browse files
Thalleynashif
authored andcommitted
Bluetooth: Host: Add conversion macros from ms to various units
Add conversion macros from milliseconds to various units. The purpose of these macros is to make it more clear/easier for users to set and read values using milliseconds rather than the various BT units which may be in 0.625, 1.25 or 10ms units. This is especially useful when comparing related values using different units, such as advertising interval (0.625ms units) and periodic advertising interval units (1.25ms units). Users will have to be aware that these macros can provide slightly different values than what is provided, if the provided values do not match the units. Signed-off-by: Emil Gydesen <[email protected]>
1 parent 0d249ec commit 8703381

File tree

30 files changed

+540
-100
lines changed

30 files changed

+540
-100
lines changed

include/zephyr/bluetooth/conn.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,9 @@ struct bt_le_conn_param {
7474
* Latency: 0
7575
* Timeout: 4 s
7676
*/
77-
#define BT_LE_CONN_PARAM_DEFAULT BT_LE_CONN_PARAM(BT_GAP_INIT_CONN_INT_MIN, \
78-
BT_GAP_INIT_CONN_INT_MAX, \
79-
0, 400)
77+
#define BT_LE_CONN_PARAM_DEFAULT \
78+
BT_LE_CONN_PARAM(BT_GAP_INIT_CONN_INT_MIN, BT_GAP_INIT_CONN_INT_MAX, 0, \
79+
BT_GAP_MS_TO_CONN_TIMEOUT(4000))
8080

8181
/** Connection PHY information for LE connections */
8282
struct bt_conn_le_phy_info {

include/zephyr/bluetooth/gap.h

Lines changed: 215 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -825,12 +825,225 @@ enum {
825825
/** Maximum Periodic Advertising Interval (N * 1.25 ms) */
826826
#define BT_GAP_PER_ADV_MAX_INTERVAL 0xFFFF /* 81.91875 s */
827827

828+
/**
829+
* @brief Convert periodic advertising interval (N * 0.625 ms) to microseconds
830+
*
831+
* Value range of @p _interval is @ref BT_LE_ADV_INTERVAL_MIN to @ref BT_LE_ADV_INTERVAL_MAX
832+
*/
833+
#define BT_GAP_ADV_INTERVAL_TO_US(_interval) ((uint32_t)((_interval) * 625U))
834+
835+
/**
836+
* @brief Convert periodic advertising interval (N * 0.625 ms) to milliseconds
837+
*
838+
* Value range of @p _interval is @ref BT_LE_ADV_INTERVAL_MIN to @ref BT_LE_ADV_INTERVAL_MAX
839+
*
840+
* @note When intervals cannot be represented in milliseconds, this will round down.
841+
* For example BT_GAP_ADV_INTERVAL_TO_MS(0x0021) will become 20 ms instead of 20.625 ms
842+
*/
843+
#define BT_GAP_ADV_INTERVAL_TO_MS(_interval) (BT_GAP_ADV_INTERVAL_TO_US(_interval) / USEC_PER_MSEC)
844+
845+
/**
846+
* @brief Convert isochronous interval (N * 1.25 ms) to microseconds
847+
*
848+
* Value range of @p _interval is @ref BT_HCI_ISO_INTERVAL_MIN to @ref BT_HCI_ISO_INTERVAL_MAX
849+
*/
850+
#define BT_GAP_ISO_INTERVAL_TO_US(_interval) ((uint32_t)((_interval) * 1250U))
851+
852+
/**
853+
* @brief Convert isochronous interval (N * 1.25 ms) to milliseconds
854+
*
855+
* Value range of @p _interval is @ref BT_HCI_ISO_INTERVAL_MIN to @ref BT_HCI_ISO_INTERVAL_MAX
856+
*
857+
* @note When intervals cannot be represented in milliseconds, this will round down.
858+
* For example BT_GAP_ISO_INTERVAL_TO_MS(0x0005) will become 6 ms instead of 6.25 ms
859+
*/
860+
#define BT_GAP_ISO_INTERVAL_TO_MS(_interval) (BT_GAP_ISO_INTERVAL_TO_US(_interval) / USEC_PER_MSEC)
861+
862+
/** @brief Convert periodic advertising interval (N * 1.25 ms) to microseconds *
863+
*
864+
* Value range of @p _interval is @ref BT_HCI_LE_PER_ADV_INTERVAL_MIN to @ref
865+
* BT_HCI_LE_PER_ADV_INTERVAL_MAX
866+
*/
867+
#define BT_GAP_PER_ADV_INTERVAL_TO_US(_interval) ((uint32_t)((_interval) * 1250U))
868+
828869
/**
829870
* @brief Convert periodic advertising interval (N * 1.25 ms) to milliseconds
830871
*
831-
* 5 / 4 represents 1.25 ms unit.
872+
* @note When intervals cannot be represented in milliseconds, this will round down.
873+
* For example BT_GAP_PER_ADV_INTERVAL_TO_MS(0x0009) will become 11 ms instead of 11.25 ms
874+
*/
875+
#define BT_GAP_PER_ADV_INTERVAL_TO_MS(_interval) \
876+
(BT_GAP_PER_ADV_INTERVAL_TO_US(_interval) / USEC_PER_MSEC)
877+
878+
/**
879+
* @brief Convert microseconds to advertising interval units (0.625 ms)
880+
*
881+
* Value range of @p _interval is 20000 to 1024000
882+
*
883+
* @note If @p _interval is not a multiple of the unit, it will round down to nearest.
884+
* For example BT_GAP_US_TO_ADV_INTERVAL(21000) will become 20625 microseconds
885+
*/
886+
#define BT_GAP_US_TO_ADV_INTERVAL(_interval) ((uint16_t)((_interval) / 625U))
887+
888+
/**
889+
* @brief Convert milliseconds to advertising interval units (0.625 ms)
890+
*
891+
* Value range of @p _interval is 20 to 1024
892+
*
893+
* @note If @p _interval is not a multiple of the unit, it will round down to nearest.
894+
* For example BT_GAP_MS_TO_ADV_INTERVAL(21) will become 20.625 milliseconds
895+
*/
896+
#define BT_GAP_MS_TO_ADV_INTERVAL(_interval) \
897+
(BT_GAP_US_TO_ADV_INTERVAL((_interval) * USEC_PER_MSEC))
898+
899+
/**
900+
* @brief Convert microseconds to periodic advertising interval units (1.25 ms)
901+
*
902+
* Value range of @p _interval is 7500 to 81918750
903+
*
904+
* @note If @p _interval is not a multiple of the unit, it will round down to nearest.
905+
* For example BT_GAP_US_TO_PER_ADV_INTERVAL(11000) will become 10000 microseconds
906+
*/
907+
#define BT_GAP_US_TO_PER_ADV_INTERVAL(_interval) ((uint16_t)((_interval) / 1250U))
908+
909+
/**
910+
* @brief Convert milliseconds to periodic advertising interval units (1.25 ms)
911+
*
912+
* Value range of @p _interval is 7.5 to 81918.75
913+
*
914+
* @note If @p _interval is not a multiple of the unit, it will round down to nearest.
915+
* For example BT_GAP_MS_TO_PER_ADV_INTERVAL(11) will become 10 milliseconds
916+
*/
917+
#define BT_GAP_MS_TO_PER_ADV_INTERVAL(_interval) \
918+
(BT_GAP_US_TO_PER_ADV_INTERVAL((_interval) * USEC_PER_MSEC))
919+
920+
/**
921+
* @brief Convert milliseconds to periodic advertising sync timeout units (10 ms)
922+
*
923+
* Value range of @p _timeout is 100 to 163840
924+
*
925+
* @note If @p _timeout is not a multiple of the unit, it will round down to nearest.
926+
* For example BT_GAP_MS_TO_PER_ADV_SYNC_TIMEOUT(4005) will become 4000 milliseconds
927+
*/
928+
#define BT_GAP_MS_TO_PER_ADV_SYNC_TIMEOUT(_timeout) ((uint16_t)((_timeout) / 10U))
929+
930+
/**
931+
* @brief Convert microseconds to periodic advertising sync timeout units (10 ms)
932+
*
933+
* Value range of @p _timeout is 100000 to 163840000
934+
*
935+
* @note If @p _timeout is not a multiple of the unit, it will round down to nearest.
936+
* For example BT_GAP_MS_TO_PER_ADV_SYNC_TIMEOUT(4005000) will become 4000000 microseconds
937+
*/
938+
#define BT_GAP_US_TO_PER_ADV_SYNC_TIMEOUT(_timeout) \
939+
(BT_GAP_MS_TO_PER_ADV_SYNC_TIMEOUT((_timeout) / USEC_PER_MSEC))
940+
941+
/**
942+
* @brief Convert microseconds to scan interval units (0.625 ms)
943+
*
944+
* Value range of @p _interval is 2500 to 40959375 if @kconfig{CONFIG_BT_EXT_ADV} else
945+
* 2500 to 10240000
946+
*
947+
* @note If @p _interval is not a multiple of the unit, it will round down to nearest.
948+
* For example BT_GAP_US_TO_SCAN_INTERVAL(21000) will become 20625 microseconds
949+
*/
950+
#define BT_GAP_US_TO_SCAN_INTERVAL(_interval) ((uint16_t)((_interval) / 625U))
951+
952+
/**
953+
* @brief Convert milliseconds to scan interval units (0.625 ms)
954+
*
955+
* Value range of @p _interval is 2.5 to 40959.375 if @kconfig{CONFIG_BT_EXT_ADV} else
956+
* 2500 to 10240
957+
*
958+
* @note If @p _interval is not a multiple of the unit, it will round down to nearest.
959+
* For example BT_GAP_MS_TO_SCAN_INTERVAL(21) will become 20.625 milliseconds
960+
*/
961+
#define BT_GAP_MS_TO_SCAN_INTERVAL(_interval) \
962+
(BT_GAP_US_TO_SCAN_INTERVAL((_interval) * USEC_PER_MSEC))
963+
964+
/**
965+
* @brief Convert microseconds to scan window units (0.625 ms)
966+
*
967+
* Value range of @p _window is 2500 to 40959375 if @kconfig{CONFIG_BT_EXT_ADV} else
968+
* 2500 to 10240000
969+
*
970+
* @note If @p _window is not a multiple of the unit, it will round down to nearest.
971+
* For example BT_GAP_US_TO_SCAN_WINDOW(21000) will become 20625 microseconds
972+
*/
973+
#define BT_GAP_US_TO_SCAN_WINDOW(_window) ((uint16_t)((_window) / 625U))
974+
975+
/**
976+
* @brief Convert milliseconds to scan window units (0.625 ms)
977+
*
978+
* Value range of @p _window is 2.5 to 40959.375 if @kconfig{CONFIG_BT_EXT_ADV} else
979+
* 2500 to 10240
980+
*
981+
* @note If @p _window is not a multiple of the unit, it will round down to nearest.
982+
* For example BT_GAP_MS_TO_SCAN_WINDOW(21) will become 20.625 milliseconds
983+
*/
984+
#define BT_GAP_MS_TO_SCAN_WINDOW(_window) (BT_GAP_US_TO_SCAN_WINDOW((_window) * USEC_PER_MSEC))
985+
986+
/**
987+
* @brief Convert microseconds to connection interval units (1.25 ms)
988+
*
989+
* Value range of @p _interval is 7500 to 4000000
990+
*
991+
* @note If @p _interval is not a multiple of the unit, it will round down to nearest.
992+
* For example BT_GAP_US_TO_CONN_INTERVAL(21000) will become 20000 microseconds
993+
*/
994+
#define BT_GAP_US_TO_CONN_INTERVAL(_interval) ((uint16_t)((_interval) / 1250U))
995+
996+
/**
997+
* @brief Convert milliseconds to connection interval units (1.25 ms)
998+
*
999+
* Value range of @p _interval is 7.5 to 4000
1000+
*
1001+
* @note If @p _interval is not a multiple of the unit, it will round down to nearest.
1002+
* For example BT_GAP_MS_TO_CONN_INTERVAL(21) will become 20 milliseconds
1003+
*/
1004+
#define BT_GAP_MS_TO_CONN_INTERVAL(_interval) \
1005+
(BT_GAP_US_TO_CONN_INTERVAL((_interval) * USEC_PER_MSEC))
1006+
1007+
/**
1008+
* @brief Convert milliseconds to connection supervision timeout units (10 ms)
1009+
*
1010+
* Value range of @p _timeout is 100 to 32000
1011+
*
1012+
* @note If @p _timeout is not a multiple of the unit, it will round down to nearest.
1013+
* For example BT_GAP_MS_TO_CONN_TIMEOUT(4005) will become 4000 milliseconds
1014+
*/
1015+
#define BT_GAP_MS_TO_CONN_TIMEOUT(_timeout) ((uint16_t)((_timeout) / 10U))
1016+
1017+
/**
1018+
* @brief Convert microseconds to connection supervision timeout units (10 ms)
1019+
1020+
* Value range of @p _timeout is 100000 to 32000000
1021+
*
1022+
* @note If @p _timeout is not a multiple of the unit, it will round down to nearest.
1023+
* For example BT_GAP_MS_TO_CONN_TIMEOUT(4005000) will become 4000000 microseconds
1024+
*/
1025+
#define BT_GAP_US_TO_CONN_TIMEOUT(_timeout) (BT_GAP_MS_TO_CONN_TIMEOUT((_timeout) / USEC_PER_MSEC))
1026+
1027+
/**
1028+
* @brief Convert milliseconds to connection event length units (0.625)
1029+
*
1030+
* Value range of @p _event_len is 0 to 40959375
1031+
*
1032+
* @note If @p _event_len is not a multiple of the unit, it will round down to nearest.
1033+
* For example BT_GAP_US_TO_CONN_EVENT_LEN(21000) will become 20625 milliseconds
1034+
*/
1035+
#define BT_GAP_US_TO_CONN_EVENT_LEN(_event_len) ((uint16_t)((_event_len) / 625U))
1036+
1037+
/**
1038+
* @brief Convert milliseconds to connection event length units (0.625)
1039+
*
1040+
* Value range of @p _event_len is 0 to 40959.375
1041+
*
1042+
* @note If @p _event_len is not a multiple of the unit, it will round down to nearest.
1043+
* For example BT_GAP_MS_TO_CONN_EVENT_LEN(21) will become 20.625 milliseconds
8321044
*/
833-
#define BT_GAP_PER_ADV_INTERVAL_TO_MS(interval) ((interval) * 5 / 4)
1045+
#define BT_GAP_MS_TO_CONN_EVENT_LEN(_event_len) \
1046+
(BT_GAP_US_TO_CONN_EVENT_LEN((_event_len) * USEC_PER_MSEC))
8341047

8351048
/** Constant Tone Extension (CTE) types */
8361049
enum {

samples/bluetooth/bap_broadcast_assistant/src/main.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -260,12 +260,13 @@ static uint16_t interval_to_sync_timeout(uint16_t pa_interval)
260260
/* Use maximum value to maximize chance of success */
261261
pa_timeout = BT_GAP_PER_ADV_MAX_TIMEOUT;
262262
} else {
263-
uint32_t interval_ms;
263+
uint32_t interval_us;
264264
uint32_t timeout;
265265

266266
/* Add retries and convert to unit in 10's of ms */
267-
interval_ms = BT_GAP_PER_ADV_INTERVAL_TO_MS(pa_interval);
268-
timeout = (interval_ms * PA_SYNC_INTERVAL_TO_TIMEOUT_RATIO) / 10;
267+
interval_us = BT_GAP_PER_ADV_INTERVAL_TO_US(pa_interval);
268+
timeout = BT_GAP_US_TO_PER_ADV_SYNC_TIMEOUT(interval_us) *
269+
PA_SYNC_INTERVAL_TO_TIMEOUT_RATIO;
269270

270271
/* Enforce restraints */
271272
pa_timeout = CLAMP(timeout, BT_GAP_PER_ADV_MIN_TIMEOUT, BT_GAP_PER_ADV_MAX_TIMEOUT);

samples/bluetooth/bap_broadcast_sink/src/main.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -851,12 +851,13 @@ static uint16_t interval_to_sync_timeout(uint16_t pa_interval)
851851
/* Use maximum value to maximize chance of success */
852852
pa_timeout = BT_GAP_PER_ADV_MAX_TIMEOUT;
853853
} else {
854-
uint32_t interval_ms;
854+
uint32_t interval_us;
855855
uint32_t timeout;
856856

857857
/* Add retries and convert to unit in 10's of ms */
858-
interval_ms = BT_GAP_PER_ADV_INTERVAL_TO_MS(pa_interval);
859-
timeout = (interval_ms * PA_SYNC_INTERVAL_TO_TIMEOUT_RATIO) / 10;
858+
interval_us = BT_GAP_PER_ADV_INTERVAL_TO_US(pa_interval);
859+
timeout = BT_GAP_US_TO_PER_ADV_SYNC_TIMEOUT(interval_us) *
860+
PA_SYNC_INTERVAL_TO_TIMEOUT_RATIO;
860861

861862
/* Enforce restraints */
862863
pa_timeout = CLAMP(timeout, BT_GAP_PER_ADV_MIN_TIMEOUT, BT_GAP_PER_ADV_MAX_TIMEOUT);

samples/bluetooth/bap_broadcast_source/src/main.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ BUILD_ASSERT(strlen(CONFIG_BROADCAST_CODE) <= BT_ISO_BROADCAST_CODE_SIZE, "Inval
3939
* And, for 10 ms ISO interval, can use 90 ms minus 10 ms ==> 80 ms advertising
4040
* interval.
4141
*/
42-
#define BT_LE_EXT_ADV_CUSTOM BT_LE_ADV_PARAM(BT_LE_ADV_OPT_EXT_ADV, 0x0080, 0x0080, NULL)
42+
#define BT_LE_EXT_ADV_CUSTOM \
43+
BT_LE_ADV_PARAM(BT_LE_ADV_OPT_EXT_ADV, BT_GAP_MS_TO_ADV_INTERVAL(80), \
44+
BT_GAP_MS_TO_ADV_INTERVAL(80), NULL)
4345

4446
/* When BROADCAST_ENQUEUE_COUNT > 1 we can enqueue enough buffers to ensure that
4547
* the controller is never idle

samples/bluetooth/cap_acceptor/src/cap_acceptor_broadcast.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -291,12 +291,13 @@ static uint16_t interval_to_sync_timeout(uint16_t pa_interval)
291291
/* Use maximum value to maximize chance of success */
292292
pa_timeout = BT_GAP_PER_ADV_MAX_TIMEOUT;
293293
} else {
294-
uint32_t interval_ms;
294+
uint32_t interval_us;
295295
uint32_t timeout;
296296

297297
/* Add retries and convert to unit in 10's of ms */
298-
interval_ms = BT_GAP_PER_ADV_INTERVAL_TO_MS(pa_interval);
299-
timeout = (interval_ms * PA_SYNC_INTERVAL_TO_TIMEOUT_RATIO) / 10;
298+
interval_us = BT_GAP_PER_ADV_INTERVAL_TO_US(pa_interval);
299+
timeout = BT_GAP_US_TO_PER_ADV_SYNC_TIMEOUT(interval_us) *
300+
PA_SYNC_INTERVAL_TO_TIMEOUT_RATIO;
300301

301302
/* Enforce restraints */
302303
pa_timeout = CLAMP(timeout, BT_GAP_PER_ADV_MIN_TIMEOUT, BT_GAP_PER_ADV_MAX_TIMEOUT);

samples/bluetooth/central_past/src/main.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,27 @@
11
/*
2-
* Copyright (c) 2021 Nordic Semiconductor ASA
2+
* Copyright (c) 2021-2024 Nordic Semiconductor ASA
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7+
#include <stdint.h>
8+
9+
#include <zephyr/bluetooth/gap.h>
710
#include <zephyr/device.h>
811
#include <zephyr/devicetree.h>
912
#include <zephyr/drivers/gpio.h>
1013
#include <zephyr/bluetooth/bluetooth.h>
1114
#include <zephyr/bluetooth/conn.h>
1215
#include <zephyr/bluetooth/hci.h>
16+
#include <zephyr/sys/util.h>
1317

1418
#define NAME_LEN 30
1519

1620
static bool per_adv_found;
1721
static bt_addr_le_t per_addr;
1822
static uint8_t per_sid;
1923
static struct bt_conn *default_conn;
20-
static uint32_t per_adv_interval_ms;
24+
static uint16_t per_adv_sync_timeout;
2125

2226
static K_SEM_DEFINE(sem_conn, 0, 1);
2327
static K_SEM_DEFINE(sem_conn_lost, 0, 1);
@@ -106,8 +110,22 @@ static void scan_recv(const struct bt_le_scan_recv_info *info,
106110
} else {
107111
/* If info->interval it is a periodic advertiser, mark for sync */
108112
if (!per_adv_found && info->interval) {
113+
uint32_t interval_us;
114+
uint32_t timeout;
115+
109116
per_adv_found = true;
110-
per_adv_interval_ms = BT_GAP_PER_ADV_INTERVAL_TO_MS(info->interval);
117+
118+
/* Add retries and convert to unit in 10's of ms */
119+
interval_us = BT_GAP_PER_ADV_INTERVAL_TO_US(info->interval);
120+
121+
timeout = BT_GAP_US_TO_PER_ADV_SYNC_TIMEOUT(interval_us);
122+
123+
/* 10 attempts */
124+
timeout *= 10;
125+
126+
/* Enforce restraints */
127+
per_adv_sync_timeout = CLAMP(timeout, BT_GAP_PER_ADV_MIN_TIMEOUT,
128+
BT_GAP_PER_ADV_MAX_TIMEOUT);
111129

112130
per_sid = info->sid;
113131
bt_addr_le_copy(&per_addr, info->addr);
@@ -296,7 +314,7 @@ int main(void)
296314
sync_create_param.options = 0;
297315
sync_create_param.sid = per_sid;
298316
sync_create_param.skip = 0;
299-
sync_create_param.timeout = per_adv_interval_ms * 10 / 10; /* 10 attempts */
317+
sync_create_param.timeout = per_adv_sync_timeout;
300318
err = bt_le_per_adv_sync_create(&sync_create_param, &sync);
301319
if (err != 0) {
302320
printk("failed (err %d)\n", err);

0 commit comments

Comments
 (0)