Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bluetooth: Host: Add conversion macros from ms to various units #81068

Merged
merged 1 commit into from
Nov 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
217 changes: 215 additions & 2 deletions include/zephyr/bluetooth/gap.h
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't sure where to put these. We already have various conversion functions like BT_GAP_PER_ADV_INTERVAL_TO_MS and BT_CONN_INTERVAL_TO_MS, but they are placed here and there.

Original file line number Diff line number Diff line change
Expand Up @@ -825,12 +825,225 @@ 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 microseconds
*
* Value range of @p _interval is @ref BT_LE_ADV_INTERVAL_MIN to @ref BT_LE_ADV_INTERVAL_MAX
*/
#define BT_GAP_ADV_INTERVAL_TO_US(_interval) ((uint32_t)((_interval) * 625U))

/**
* @brief Convert periodic advertising interval (N * 0.625 ms) to milliseconds
*
* Value range of @p _interval is @ref BT_LE_ADV_INTERVAL_MIN to @ref BT_LE_ADV_INTERVAL_MAX
*
* @note When intervals cannot be represented in milliseconds, this will round down.
* For example BT_GAP_ADV_INTERVAL_TO_MS(0x0021) will become 20 ms instead of 20.625 ms
*/
#define BT_GAP_ADV_INTERVAL_TO_MS(_interval) (BT_GAP_ADV_INTERVAL_TO_US(_interval) / USEC_PER_MSEC)

/**
* @brief Convert isochronous interval (N * 1.25 ms) to microseconds
*
* Value range of @p _interval is @ref BT_HCI_ISO_INTERVAL_MIN to @ref BT_HCI_ISO_INTERVAL_MAX
*/
#define BT_GAP_ISO_INTERVAL_TO_US(_interval) ((uint32_t)((_interval) * 1250U))

/**
* @brief Convert isochronous interval (N * 1.25 ms) to milliseconds
*
* Value range of @p _interval is @ref BT_HCI_ISO_INTERVAL_MIN to @ref BT_HCI_ISO_INTERVAL_MAX
*
* @note When intervals cannot be represented in milliseconds, this will round down.
* For example BT_GAP_ISO_INTERVAL_TO_MS(0x0005) will become 6 ms instead of 6.25 ms
*/
#define BT_GAP_ISO_INTERVAL_TO_MS(_interval) (BT_GAP_ISO_INTERVAL_TO_US(_interval) / USEC_PER_MSEC)

/** @brief Convert periodic advertising interval (N * 1.25 ms) to microseconds *
*
* Value range of @p _interval is @ref BT_HCI_LE_PER_ADV_INTERVAL_MIN to @ref
* BT_HCI_LE_PER_ADV_INTERVAL_MAX
*/
#define BT_GAP_PER_ADV_INTERVAL_TO_US(_interval) ((uint32_t)((_interval) * 1250U))

/**
* @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(0x0009) will become 11 ms instead of 11.25 ms
*/
#define BT_GAP_PER_ADV_INTERVAL_TO_MS(_interval) \
(BT_GAP_PER_ADV_INTERVAL_TO_US(_interval) / USEC_PER_MSEC)

/**
* @brief Convert microseconds to advertising interval units (0.625 ms)
*
* Value range of @p _interval is 20000 to 1024000
*
* @note If @p _interval is not a multiple of the unit, it will round down to nearest.
* For example BT_GAP_US_TO_ADV_INTERVAL(21000) will become 20625 microseconds
*/
#define BT_GAP_US_TO_ADV_INTERVAL(_interval) ((uint16_t)((_interval) / 625U))

/**
* @brief Convert milliseconds to advertising interval units (0.625 ms)
*
* Value range of @p _interval is 20 to 1024
*
* @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(21) will become 20.625 milliseconds
*/
#define BT_GAP_MS_TO_ADV_INTERVAL(_interval) \
(BT_GAP_US_TO_ADV_INTERVAL((_interval) * USEC_PER_MSEC))

/**
* @brief Convert microseconds to periodic advertising interval units (1.25 ms)
*
* Value range of @p _interval is 7500 to 81918750
*
* @note If @p _interval is not a multiple of the unit, it will round down to nearest.
* For example BT_GAP_US_TO_PER_ADV_INTERVAL(11000) will become 10000 microseconds
*/
#define BT_GAP_US_TO_PER_ADV_INTERVAL(_interval) ((uint16_t)((_interval) / 1250U))

/**
* @brief Convert milliseconds to periodic advertising interval units (1.25 ms)
*
* Value range of @p _interval is 7.5 to 81918.75
*
* @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(11) will become 10 milliseconds
*/
#define BT_GAP_MS_TO_PER_ADV_INTERVAL(_interval) \
(BT_GAP_US_TO_PER_ADV_INTERVAL((_interval) * USEC_PER_MSEC))

/**
* @brief Convert milliseconds to periodic advertising sync timeout units (10 ms)
*
* Value range of @p _timeout is 100 to 163840
*
* @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 microseconds to periodic advertising sync timeout units (10 ms)
*
* Value range of @p _timeout is 100000 to 163840000
*
* @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(4005000) will become 4000000 microseconds
*/
#define BT_GAP_US_TO_PER_ADV_SYNC_TIMEOUT(_timeout) \
(BT_GAP_MS_TO_PER_ADV_SYNC_TIMEOUT((_timeout) / USEC_PER_MSEC))

/**
* @brief Convert microseconds to scan interval units (0.625 ms)
*
* Value range of @p _interval is 2500 to 40959375 if @kconfig{CONFIG_BT_EXT_ADV} else
* 2500 to 10240000
*
* @note If @p _interval is not a multiple of the unit, it will round down to nearest.
* For example BT_GAP_US_TO_SCAN_INTERVAL(21000) will become 20625 microseconds
*/
#define BT_GAP_US_TO_SCAN_INTERVAL(_interval) ((uint16_t)((_interval) / 625U))

/**
* @brief Convert milliseconds to scan interval units (0.625 ms)
*
* Value range of @p _interval is 2.5 to 40959.375 if @kconfig{CONFIG_BT_EXT_ADV} else
* 2500 to 10240
*
* @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(21) will become 20.625 milliseconds
*/
#define BT_GAP_MS_TO_SCAN_INTERVAL(_interval) \
(BT_GAP_US_TO_SCAN_INTERVAL((_interval) * USEC_PER_MSEC))

/**
* @brief Convert microseconds to scan window units (0.625 ms)
*
* Value range of @p _window is 2500 to 40959375 if @kconfig{CONFIG_BT_EXT_ADV} else
* 2500 to 10240000
*
* @note If @p _window is not a multiple of the unit, it will round down to nearest.
* For example BT_GAP_US_TO_SCAN_WINDOW(21000) will become 20625 microseconds
*/
#define BT_GAP_US_TO_SCAN_WINDOW(_window) ((uint16_t)((_window) / 625U))

/**
* @brief Convert milliseconds to scan window units (0.625 ms)
*
* Value range of @p _window is 2.5 to 40959.375 if @kconfig{CONFIG_BT_EXT_ADV} else
* 2500 to 10240
*
* @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(21) will become 20.625 milliseconds
*/
#define BT_GAP_MS_TO_SCAN_WINDOW(_window) (BT_GAP_US_TO_SCAN_WINDOW((_window) * USEC_PER_MSEC))

/**
* @brief Convert microseconds to connection interval units (1.25 ms)
*
* Value range of @p _interval is 7500 to 4000000
*
* @note If @p _interval is not a multiple of the unit, it will round down to nearest.
* For example BT_GAP_US_TO_CONN_INTERVAL(21000) will become 20000 microseconds
*/
#define BT_GAP_US_TO_CONN_INTERVAL(_interval) ((uint16_t)((_interval) / 1250U))

/**
* @brief Convert milliseconds to connection interval units (1.25 ms)
*
* Value range of @p _interval is 7.5 to 4000
*
* @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(21) will become 20 milliseconds
*/
#define BT_GAP_MS_TO_CONN_INTERVAL(_interval) \
(BT_GAP_US_TO_CONN_INTERVAL((_interval) * USEC_PER_MSEC))

/**
* @brief Convert milliseconds to connection supervision timeout units (10 ms)
*
* Value range of @p _timeout is 100 to 32000
*
* @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 microseconds to connection supervision timeout units (10 ms)

* Value range of @p _timeout is 100000 to 32000000
*
* @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(4005000) will become 4000000 microseconds
*/
#define BT_GAP_US_TO_CONN_TIMEOUT(_timeout) (BT_GAP_MS_TO_CONN_TIMEOUT((_timeout) / USEC_PER_MSEC))

/**
* @brief Convert milliseconds to connection event length units (0.625)
*
* Value range of @p _event_len is 0 to 40959375
*
* @note If @p _event_len is not a multiple of the unit, it will round down to nearest.
* For example BT_GAP_US_TO_CONN_EVENT_LEN(21000) will become 20625 milliseconds
*/
#define BT_GAP_US_TO_CONN_EVENT_LEN(_event_len) ((uint16_t)((_event_len) / 625U))

/**
* @brief Convert milliseconds to connection event length units (0.625)
*
* Value range of @p _event_len is 0 to 40959.375
*
* @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(21) will become 20.625 milliseconds
*/
#define BT_GAP_PER_ADV_INTERVAL_TO_MS(interval) ((interval) * 5 / 4)
#define BT_GAP_MS_TO_CONN_EVENT_LEN(_event_len) \
(BT_GAP_US_TO_CONN_EVENT_LEN((_event_len) * USEC_PER_MSEC))

/** Constant Tone Extension (CTE) types */
enum {
Expand Down
7 changes: 4 additions & 3 deletions samples/bluetooth/bap_broadcast_assistant/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,12 +260,13 @@ static uint16_t interval_to_sync_timeout(uint16_t pa_interval)
/* Use maximum value to maximize chance of success */
pa_timeout = BT_GAP_PER_ADV_MAX_TIMEOUT;
} else {
uint32_t interval_ms;
uint32_t interval_us;
uint32_t timeout;

/* Add retries and convert to unit in 10's of ms */
interval_ms = BT_GAP_PER_ADV_INTERVAL_TO_MS(pa_interval);
timeout = (interval_ms * PA_SYNC_INTERVAL_TO_TIMEOUT_RATIO) / 10;
interval_us = BT_GAP_PER_ADV_INTERVAL_TO_US(pa_interval);
timeout = BT_GAP_US_TO_PER_ADV_SYNC_TIMEOUT(interval_us) *
PA_SYNC_INTERVAL_TO_TIMEOUT_RATIO;

/* Enforce restraints */
pa_timeout = CLAMP(timeout, BT_GAP_PER_ADV_MIN_TIMEOUT, BT_GAP_PER_ADV_MAX_TIMEOUT);
Expand Down
7 changes: 4 additions & 3 deletions samples/bluetooth/bap_broadcast_sink/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -851,12 +851,13 @@ static uint16_t interval_to_sync_timeout(uint16_t pa_interval)
/* Use maximum value to maximize chance of success */
pa_timeout = BT_GAP_PER_ADV_MAX_TIMEOUT;
} else {
uint32_t interval_ms;
uint32_t interval_us;
uint32_t timeout;

/* Add retries and convert to unit in 10's of ms */
interval_ms = BT_GAP_PER_ADV_INTERVAL_TO_MS(pa_interval);
timeout = (interval_ms * PA_SYNC_INTERVAL_TO_TIMEOUT_RATIO) / 10;
interval_us = BT_GAP_PER_ADV_INTERVAL_TO_US(pa_interval);
timeout = BT_GAP_US_TO_PER_ADV_SYNC_TIMEOUT(interval_us) *
PA_SYNC_INTERVAL_TO_TIMEOUT_RATIO;

/* Enforce restraints */
pa_timeout = CLAMP(timeout, BT_GAP_PER_ADV_MIN_TIMEOUT, BT_GAP_PER_ADV_MAX_TIMEOUT);
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
7 changes: 4 additions & 3 deletions samples/bluetooth/cap_acceptor/src/cap_acceptor_broadcast.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,12 +291,13 @@ static uint16_t interval_to_sync_timeout(uint16_t pa_interval)
/* Use maximum value to maximize chance of success */
pa_timeout = BT_GAP_PER_ADV_MAX_TIMEOUT;
} else {
uint32_t interval_ms;
uint32_t interval_us;
uint32_t timeout;

/* Add retries and convert to unit in 10's of ms */
interval_ms = BT_GAP_PER_ADV_INTERVAL_TO_MS(pa_interval);
timeout = (interval_ms * PA_SYNC_INTERVAL_TO_TIMEOUT_RATIO) / 10;
interval_us = BT_GAP_PER_ADV_INTERVAL_TO_US(pa_interval);
timeout = BT_GAP_US_TO_PER_ADV_SYNC_TIMEOUT(interval_us) *
PA_SYNC_INTERVAL_TO_TIMEOUT_RATIO;

/* Enforce restraints */
pa_timeout = CLAMP(timeout, BT_GAP_PER_ADV_MIN_TIMEOUT, BT_GAP_PER_ADV_MAX_TIMEOUT);
Expand Down
26 changes: 22 additions & 4 deletions samples/bluetooth/central_past/src/main.c
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
/*
* Copyright (c) 2021 Nordic Semiconductor ASA
* Copyright (c) 2021-2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <stdint.h>

#include <zephyr/bluetooth/gap.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/sys/util.h>

#define NAME_LEN 30

static bool per_adv_found;
static bt_addr_le_t per_addr;
static uint8_t per_sid;
static struct bt_conn *default_conn;
static uint32_t per_adv_interval_ms;
static uint16_t per_adv_sync_timeout;

static K_SEM_DEFINE(sem_conn, 0, 1);
static K_SEM_DEFINE(sem_conn_lost, 0, 1);
Expand Down Expand Up @@ -106,8 +110,22 @@ static void scan_recv(const struct bt_le_scan_recv_info *info,
} else {
/* If info->interval it is a periodic advertiser, mark for sync */
if (!per_adv_found && info->interval) {
uint32_t interval_us;
uint32_t timeout;

per_adv_found = true;
per_adv_interval_ms = BT_GAP_PER_ADV_INTERVAL_TO_MS(info->interval);

/* Add retries and convert to unit in 10's of ms */
interval_us = BT_GAP_PER_ADV_INTERVAL_TO_US(info->interval);

timeout = BT_GAP_US_TO_PER_ADV_SYNC_TIMEOUT(interval_us);

/* 10 attempts */
timeout *= 10;

/* Enforce restraints */
per_adv_sync_timeout = CLAMP(timeout, BT_GAP_PER_ADV_MIN_TIMEOUT,
BT_GAP_PER_ADV_MAX_TIMEOUT);

per_sid = info->sid;
bt_addr_le_copy(&per_addr, info->addr);
Expand Down Expand Up @@ -296,7 +314,7 @@ int main(void)
sync_create_param.options = 0;
sync_create_param.sid = per_sid;
sync_create_param.skip = 0;
sync_create_param.timeout = per_adv_interval_ms * 10 / 10; /* 10 attempts */
sync_create_param.timeout = per_adv_sync_timeout;
err = bt_le_per_adv_sync_create(&sync_create_param, &sync);
if (err != 0) {
printk("failed (err %d)\n", err);
Expand Down
Loading
Loading