Skip to content

Commit

Permalink
Bluetooth: Host: Add conversion macros from ms to various units
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
Thalley committed Nov 11, 2024
1 parent c50777a commit 4bd2837
Show file tree
Hide file tree
Showing 11 changed files with 136 additions and 45 deletions.
6 changes: 3 additions & 3 deletions include/zephyr/bluetooth/conn.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ struct bt_le_conn_param {
* Latency: 0
* Timeout: 4 s
*/
#define BT_LE_CONN_PARAM_DEFAULT BT_LE_CONN_PARAM(BT_GAP_INIT_CONN_INT_MIN, \
BT_GAP_INIT_CONN_INT_MAX, \
0, 400)
#define BT_LE_CONN_PARAM_DEFAULT \
BT_LE_CONN_PARAM(BT_GAP_INIT_CONN_INT_MIN, BT_GAP_INIT_CONN_INT_MAX, 0, \
BT_GAP_MS_TO_CONN_TIMEOUT(4000))

/** Connection PHY information for LE connections */
struct bt_conn_le_phy_info {
Expand Down
85 changes: 83 additions & 2 deletions include/zephyr/bluetooth/gap.h
Original file line number Diff line number Diff line change
Expand Up @@ -825,12 +825,93 @@ enum {
/** Maximum Periodic Advertising Interval (N * 1.25 ms) */
#define BT_GAP_PER_ADV_MAX_INTERVAL 0xFFFF /* 81.91875 s */

/**
* @brief Convert periodic advertising interval (N * 0.625 ms) to milliseconds
*
* @note When intervals cannot be represented in milliseconds, this will round down. For example
* BT_GAP_ADV_INTERVAL_TO_MS(6) will become 7 ms instead of 7.5 ms
*/
#define BT_GAP_ADV_INTERVAL_TO_MS(_interval) ((_interval) * 5U / 8U)

/**
* @brief Convert isochronous interval (N * 1.25 ms) to milliseconds
*
* @note When intervals cannot be represented in milliseconds, this will round down. For example
* BT_GAP_ISO_INTERVAL_TO_MS(6) will become 7 ms instead of 7.5 ms
*/
#define BT_GAP_ISO_INTERVAL_TO_MS(_interval) ((_interval) * 5U / 4U)

/**
* @brief Convert periodic advertising interval (N * 1.25 ms) to milliseconds
*
* 5 / 4 represents 1.25 ms unit.
* @note When intervals cannot be represented in milliseconds, this will round down. For example
* BT_GAP_PER_ADV_INTERVAL_TO_MS(6) will become 7 ms instead of 7.5 ms
*/
#define BT_GAP_PER_ADV_INTERVAL_TO_MS(_interval) ((_interval) * 5U / 4U)

/**
* @brief Convert milliseconds to advertising interval units (0.625 ms)
*
* @note If @p _interval is not a multiple of the unit, it will round down to nearest. For example
* BT_GAP_MS_TO_ADV_INTERVAL(23) will become 22.5 milliseconds
*/
#define BT_GAP_MS_TO_ADV_INTERVAL(_interval) ((uint16_t)((_interval) * 8U / 5U))

/**
* @brief Convert milliseconds to periodic advertising interval units (1.25 ms)
*
* @note If @p _interval is not a multiple of the unit, it will round down to nearest. For example
* BT_GAP_MS_TO_PER_ADV_INTERVAL(23) will become 22.5 milliseconds
*/
#define BT_GAP_MS_TO_PER_ADV_INTERVAL(_interval) ((uint16_t)((_interval) * 4U / 5U))

/**
* @brief Convert milliseconds to periodic advertising sync timeout (10 ms)
*
* @note If @p _timeout is not a multiple of the unit, it will round down to nearest. For example
* BT_GAP_MS_TO_PER_ADV_SYNC_TIMEOUT(4005) will become 4000 milliseconds
*/
#define BT_GAP_MS_TO_PER_ADV_SYNC_TIMEOUT(_timeout) ((uint16_t)((_timeout) / 10U))

/**
* @brief Convert milliseconds to scan interval units (0.625 ms)
*
* @note If @p _interval is not a multiple of the unit, it will round down to nearest. For example
* BT_GAP_MS_TO_SCAN_INTERVAL(23) will become 22.5 milliseconds
*/
#define BT_GAP_MS_TO_SCAN_INTERVAL(_interval) ((uint16_t)((_interval) * 8U / 5U))

/**
* @brief Convert milliseconds to scan window units (0.625 ms)
*
* @note If @p _window is not a multiple of the unit, it will round down to nearest. For example
* BT_GAP_MS_TO_SCAN_WINDOW(23) will become 22.5 milliseconds
*/
#define BT_GAP_MS_TO_SCAN_WINDOW(_window) ((uint16_t)((_window) * 8U / 5U))

/**
* @brief Convert milliseconds to connection interval units (1.25 ms)
*
* @note If @p _interval is not a multiple of the unit, it will round down to nearest. For example
* BT_GAP_MS_TO_CONN_INTERVAL(23) will become 22.5 milliseconds
*/
#define BT_GAP_MS_TO_CONN_INTERVAL(_interval) ((uint16_t)((_interval) * 4U / 5U))

/**
* @brief Convert milliseconds to connection supervision timeout units (10 ms)
*
* @note If @p _timeout is not a multiple of the unit, it will round down to nearest. For example
* BT_GAP_MS_TO_CONN_TIMEOUT(4005) will become 4000 milliseconds
*/
#define BT_GAP_MS_TO_CONN_TIMEOUT(_timeout) ((uint16_t)((_timeout) / 10U))

/**
* @brief Convert milliseconds to connection event length units (0.625)
*
* @note If @p _event_len is not a multiple of the unit, it will round down to nearest. For example
* BT_GAP_MS_TO_CONN_EVENT_LEN(23) will become 22.5 milliseconds
*/
#define BT_GAP_PER_ADV_INTERVAL_TO_MS(interval) ((interval) * 5 / 4)
#define BT_GAP_MS_TO_CONN_EVENT_LEN(_event_len) ((uint16_t)((_event_len) * 8U / 5U))

/** Constant Tone Extension (CTE) types */
enum {
Expand Down
4 changes: 3 additions & 1 deletion samples/bluetooth/bap_broadcast_source/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ BUILD_ASSERT(strlen(CONFIG_BROADCAST_CODE) <= BT_ISO_BROADCAST_CODE_SIZE, "Inval
* And, for 10 ms ISO interval, can use 90 ms minus 10 ms ==> 80 ms advertising
* interval.
*/
#define BT_LE_EXT_ADV_CUSTOM BT_LE_ADV_PARAM(BT_LE_ADV_OPT_EXT_ADV, 0x0080, 0x0080, NULL)
#define BT_LE_EXT_ADV_CUSTOM \
BT_LE_ADV_PARAM(BT_LE_ADV_OPT_EXT_ADV, BT_GAP_MS_TO_ADV_INTERVAL(80), \
BT_GAP_MS_TO_ADV_INTERVAL(80), NULL)

/* When BROADCAST_ENQUEUE_COUNT > 1 we can enqueue enough buffers to ensure that
* the controller is never idle
Expand Down
5 changes: 3 additions & 2 deletions samples/bluetooth/hci_pwr_ctrl/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr/bluetooth/gap.h>
#include <zephyr/types.h>
#include <stddef.h>
#include <zephyr/sys/printk.h>
Expand Down Expand Up @@ -42,8 +43,8 @@ static K_THREAD_STACK_DEFINE(pwr_thread_stack, 512);

static const int8_t txpower[DEVICE_BEACON_TXPOWER_NUM] = {4, 0, -3, -8,
-15, -18, -23, -30};
static const struct bt_le_adv_param *param =
BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONN, 0x0020, 0x0020, NULL);
static const struct bt_le_adv_param *param = BT_LE_ADV_PARAM(
BT_LE_ADV_OPT_CONN, BT_GAP_MS_TO_ADV_INTERVAL(20), BT_GAP_MS_TO_ADV_INTERVAL(20), NULL);

static void read_conn_rssi(uint16_t handle, int8_t *rssi)
{
Expand Down
3 changes: 2 additions & 1 deletion tests/bluetooth/tester/src/btp_gap.c
Original file line number Diff line number Diff line change
Expand Up @@ -989,7 +989,8 @@ static uint8_t connect(const void *cmd, uint16_t cmd_len,
void *rsp, uint16_t *rsp_len)
{
const struct bt_le_conn_param *conn_param =
BT_LE_CONN_PARAM(BT_GAP_INIT_CONN_INT_MIN, BT_GAP_INIT_CONN_INT_MIN, 0, 400);
BT_LE_CONN_PARAM(BT_GAP_INIT_CONN_INT_MIN, BT_GAP_INIT_CONN_INT_MIN, 0,
BT_GAP_MS_TO_CONN_TIMEOUT(4000));
const struct btp_gap_connect_cmd *cp = cmd;
int err;

Expand Down
8 changes: 4 additions & 4 deletions tests/bsim/bluetooth/audio/src/cap_commander_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -586,10 +586,10 @@ static void cap_device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type
return;
}

err = bt_conn_le_create(
addr, BT_CONN_LE_CREATE_CONN,
BT_LE_CONN_PARAM(BT_GAP_INIT_CONN_INT_MIN, BT_GAP_INIT_CONN_INT_MIN, 0, 400),
&connected_conns[connected_conn_cnt]);
err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN,
BT_LE_CONN_PARAM(BT_GAP_INIT_CONN_INT_MIN, BT_GAP_INIT_CONN_INT_MIN,
0, BT_GAP_MS_TO_CONN_TIMEOUT(4000)),
&connected_conns[connected_conn_cnt]);
if (err) {
FAIL("Could not connect to peer: %d", err);
}
Expand Down
15 changes: 7 additions & 8 deletions tests/bsim/bluetooth/audio/src/cap_initiator_broadcast_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,13 @@
* required to place the AUX_ADV_IND PDUs in a non-overlapping interval with the
* Broadcast ISO radio events.
*/
#define BT_LE_EXT_ADV_CUSTOM \
BT_LE_ADV_PARAM(BT_LE_ADV_OPT_EXT_ADV, \
0x0080, 0x0080, NULL)

#define BT_LE_PER_ADV_CUSTOM \
BT_LE_PER_ADV_PARAM(0x0048, \
0x0048, \
BT_LE_PER_ADV_OPT_NONE)
#define BT_LE_EXT_ADV_CUSTOM \
BT_LE_ADV_PARAM(BT_LE_ADV_OPT_EXT_ADV, BT_GAP_MS_TO_ADV_INTERVAL(80), \
BT_GAP_MS_TO_ADV_INTERVAL(80), NULL)

#define BT_LE_PER_ADV_CUSTOM \
BT_LE_PER_ADV_PARAM(BT_GAP_MS_TO_PER_ADV_INTERVAL(90), BT_GAP_MS_TO_PER_ADV_INTERVAL(90), \
BT_LE_PER_ADV_OPT_NONE)

#define BROADCAST_STREMT_CNT CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT
#define BROADCAST_ENQUEUE_COUNT 2U
Expand Down
8 changes: 4 additions & 4 deletions tests/bsim/bluetooth/audio/src/cap_initiator_unicast_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -438,10 +438,10 @@ static void cap_device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type
return;
}

err = bt_conn_le_create(
addr, BT_CONN_LE_CREATE_CONN,
BT_LE_CONN_PARAM(BT_GAP_INIT_CONN_INT_MIN, BT_GAP_INIT_CONN_INT_MIN, 0, 400),
&connected_conns[connected_conn_cnt]);
err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN,
BT_LE_CONN_PARAM(BT_GAP_INIT_CONN_INT_MIN, BT_GAP_INIT_CONN_INT_MIN,
0, BT_GAP_MS_TO_CONN_TIMEOUT(4000)),
&connected_conns[connected_conn_cnt]);
if (err) {
FAIL("Could not connect to peer: %d", err);
}
Expand Down
21 changes: 10 additions & 11 deletions tests/bsim/bluetooth/audio/src/gmap_ugg_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,13 @@
* required to place the AUX_ADV_IND PDUs in a non-overlapping interval with the
* Broadcast ISO radio events.
*/
#define BT_LE_EXT_ADV_CUSTOM \
BT_LE_ADV_PARAM(BT_LE_ADV_OPT_EXT_ADV, \
0x0080, 0x0080, NULL)
#define BT_LE_EXT_ADV_CUSTOM \
BT_LE_ADV_PARAM(BT_LE_ADV_OPT_EXT_ADV, BT_GAP_MS_TO_ADV_INTERVAL(80), \
BT_GAP_MS_TO_ADV_INTERVAL(80), NULL)

#define BT_LE_PER_ADV_CUSTOM \
BT_LE_PER_ADV_PARAM(0x0048, \
0x0048, \
BT_LE_PER_ADV_OPT_NONE)
#define BT_LE_PER_ADV_CUSTOM \
BT_LE_PER_ADV_PARAM(BT_GAP_MS_TO_PER_ADV_INTERVAL(90), BT_GAP_MS_TO_PER_ADV_INTERVAL(90), \
BT_LE_PER_ADV_OPT_NONE)

#define UNICAST_SINK_SUPPORTED (CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT > 0)
#define UNICAST_SRC_SUPPORTED (CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0)
Expand Down Expand Up @@ -546,10 +545,10 @@ static void gmap_device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t typ
return;
}

err = bt_conn_le_create(
addr, BT_CONN_LE_CREATE_CONN,
BT_LE_CONN_PARAM(BT_GAP_INIT_CONN_INT_MIN, BT_GAP_INIT_CONN_INT_MIN, 0, 400),
&connected_conns[connected_conn_cnt]);
err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN,
BT_LE_CONN_PARAM(BT_GAP_INIT_CONN_INT_MIN, BT_GAP_INIT_CONN_INT_MIN,
0, BT_GAP_MS_TO_CONN_TIMEOUT(4000)),
&connected_conns[connected_conn_cnt]);
if (err) {
FAIL("Could not connect to peer: %d", err);
}
Expand Down
6 changes: 5 additions & 1 deletion tests/bsim/bluetooth/audio/src/mcc_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <zephyr/bluetooth/audio/media_proxy.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/gap.h>
#include <zephyr/bluetooth/hci_types.h>
#include <zephyr/bluetooth/services/ots.h>
#include <zephyr/kernel.h>
Expand Down Expand Up @@ -2462,7 +2463,10 @@ void test_main(void)
bt_addr_le_to_str(bt_conn_get_dst(default_conn), addr, sizeof(addr));
printk("Connected: %s\n", addr);

bt_conn_le_param_update(default_conn, BT_LE_CONN_PARAM(0x06U, 0x10U, 0U, 400U));
bt_conn_le_param_update(default_conn,
BT_LE_CONN_PARAM(BT_GAP_MS_TO_CONN_INTERVAL(7.5),
BT_GAP_MS_TO_CONN_INTERVAL(20), 0U,
BT_GAP_MS_TO_CONN_TIMEOUT(4000U)));
WAIT_FOR_FLAG(flag_conn_updated);

test_discover();
Expand Down
20 changes: 12 additions & 8 deletions tests/bsim/bluetooth/ll/cis/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr/bluetooth/gap.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys/byteorder.h>
Expand All @@ -14,6 +15,8 @@
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/iso.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/sys/util.h>
#include <zephyr/sys_clock.h>

#include "bs_types.h"
#include "bs_tracing.h"
Expand Down Expand Up @@ -49,22 +52,23 @@ static bt_addr_le_t peer_addr;
#define CREATE_CONN_WINDOW 0x0010

#define ISO_INTERVAL_US 10000U
#define ISO_INTERVAL_MS (ISO_INTERVAL_US / USEC_PER_MSEC)
#define ISO_LATENCY_MS DIV_ROUND_UP(ISO_INTERVAL_US, USEC_PER_MSEC)
#define ISO_LATENCY_FT_MS 20U

#define BT_CONN_US_TO_INTERVAL(t) ((uint16_t)((t) * 4U / 5U / USEC_PER_MSEC))

#if (CONFIG_BT_CTLR_CENTRAL_SPACING == 0)
#define CONN_INTERVAL_MIN BT_CONN_US_TO_INTERVAL(ISO_INTERVAL_US)
#define CONN_INTERVAL_MIN_MS ISO_INTERVAL_MS
#else /* CONFIG_BT_CTLR_CENTRAL_SPACING > 0 */
#define CONN_INTERVAL_MIN BT_CONN_US_TO_INTERVAL(ISO_INTERVAL_US * CONFIG_BT_MAX_CONN)
#define CONN_INTERVAL_MIN_MS (ISO_INTERVAL_MS * CONFIG_BT_MAX_CONN)
#endif /* CONFIG_BT_CTLR_CENTRAL_SPACING > 0 */
#define CONN_INTERVAL_MAX_MS CONN_INTERVAL_MIN_MS

#define CONN_INTERVAL_MAX CONN_INTERVAL_MIN
#define CONN_TIMEOUT MAX((BT_CONN_INTERVAL_TO_MS(CONN_INTERVAL_MAX) * 6U / 10U), 10U)
#define CONN_INTERVAL_MIN BT_GAP_MS_TO_CONN_INTERVAL(CONN_INTERVAL_MIN_MS)
#define CONN_INTERVAL_MAX BT_GAP_MS_TO_CONN_INTERVAL(CONN_INTERVAL_MAX_MS)
#define CONN_TIMEOUT BT_GAP_MS_TO_CONN_TIMEOUT(MAX((CONN_INTERVAL_MAX_MS * 6U), 100U))

Check notice on line 69 in tests/bsim/bluetooth/ll/cis/src/main.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

tests/bsim/bluetooth/ll/cis/src/main.c:69 -#define CONN_INTERVAL_MIN BT_GAP_MS_TO_CONN_INTERVAL(CONN_INTERVAL_MIN_MS) -#define CONN_INTERVAL_MAX BT_GAP_MS_TO_CONN_INTERVAL(CONN_INTERVAL_MAX_MS) -#define CONN_TIMEOUT BT_GAP_MS_TO_CONN_TIMEOUT(MAX((CONN_INTERVAL_MAX_MS * 6U), 100U)) +#define CONN_INTERVAL_MIN BT_GAP_MS_TO_CONN_INTERVAL(CONN_INTERVAL_MIN_MS) +#define CONN_INTERVAL_MAX BT_GAP_MS_TO_CONN_INTERVAL(CONN_INTERVAL_MAX_MS) +#define CONN_TIMEOUT BT_GAP_MS_TO_CONN_TIMEOUT(MAX((CONN_INTERVAL_MAX_MS * 6U), 100U))
#define ADV_INTERVAL_MIN 0x0020
#define ADV_INTERVAL_MAX 0x0020
#define ADV_INTERVAL_MIN BT_GAP_MS_TO_ADV_INTERVAL(20)
#define ADV_INTERVAL_MAX BT_GAP_MS_TO_ADV_INTERVAL(20)

#define BT_CONN_LE_CREATE_CONN_CUSTOM \
BT_CONN_LE_CREATE_PARAM(BT_CONN_LE_OPT_NONE, \
Expand Down

0 comments on commit 4bd2837

Please sign in to comment.