Skip to content

Commit 4565038

Browse files
bluetooth: services: Add Channel Sounding Distance Estimation library
First draft of a mini-toolkit for processing CS results. Signed-off-by: Olivier Lesage <olivier.lesage@nordicsemi.no>
1 parent ed90a4e commit 4565038

File tree

14 files changed

+825
-391
lines changed

14 files changed

+825
-391
lines changed

doc/nrf/libraries/bluetooth/cs_de.rst

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
.. _cs_de_readme:
2+
3+
Bluetooth Channel Sounding Distance Estimation
4+
##############################################
5+
6+
.. contents::
7+
:local:
8+
:depth: 2
9+
10+
Overview
11+
********
12+
13+
This library ..... (TODO)
14+
15+
Configuration
16+
*************
17+
18+
To enable this library, use the :kconfig:option:`CONFIG_BT_CS_DE` Kconfig option.
19+
20+
Check and adjust the following Kconfig options:
21+
22+
* :kconfig:option:`CONFIG_BT_CS_DE_512_NFFT` - Uses 512 samples to compute the inverse fourier transform.
23+
24+
* :kconfig:option:`CONFIG_BT_CS_DE_1024_NFFT` - Uses 1024 samples to compute the inverse fourier transform.
25+
26+
* :kconfig:option:`CONFIG_BT_CS_DE_2048_NFFT` - Uses 2048 samples to compute the inverse fourier transform.
27+
28+
Usage
29+
*****
30+
31+
| See the sample: :file:`samples/bluetooth/channel_sounding_ras_initiator`
32+
33+
API documentation
34+
*****************
35+
36+
| Header file: :file:`include/bluetooth/cs_de.h`
37+
| Source files: :file:`subsys/bluetooth/cs_de`
38+
39+
.. doxygengroup:: bt_ras

include/bluetooth/cs_de.h

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
#ifndef CS_DE_H__
8+
#define CS_DE_H__
9+
10+
#include <zephyr/bluetooth/conn.h>
11+
#include <zephyr/net_buf.h>
12+
13+
/**
14+
* @brief Container of IQ values for local and remote measured tones
15+
*/
16+
typedef struct {
17+
/** In-phase measurements of tones on this device */
18+
float i_local[80];
19+
/** Quadrature-phase measurement of tones on this device */
20+
float q_local[80];
21+
/** In-phase measurements of tones from remote device */
22+
float i_remote[80];
23+
/** Quadrature-phase measurements of tones from remote device */
24+
float q_remote[80];
25+
} cs_de_iq_tones_t;
26+
27+
typedef enum {
28+
CS_DE_TONE_QUALITY_OK,
29+
CS_DE_TONE_QUALITY_BAD,
30+
} cs_de_tone_quality_t;
31+
32+
/**
33+
* @brief Container of distance estimate results for a number of different
34+
* methods, in meters.
35+
*/
36+
typedef struct {
37+
/** Distance estimate based on IFFT of spectrum */
38+
float ifft;
39+
/** Distance estimate based on average phase slope estimation */
40+
float phase_slope;
41+
/** Distance estimate based on RTT. */
42+
float rtt;
43+
/** Best effort distance estimate.
44+
*
45+
* This is a convenience value which is automatically set to the most
46+
* accurate of the estimation methods.
47+
*/
48+
float best;
49+
} cs_de_dist_estimates_t;
50+
51+
/**
52+
* @brief Quality of the procedure
53+
*/
54+
typedef enum {
55+
CS_DE_QUALITY_OK,
56+
CS_DE_QUALITY_DO_NOT_USE,
57+
} cs_de_quality_t;
58+
59+
/**
60+
* @brief Output data for distance estimation
61+
*/
62+
typedef struct {
63+
/** CS Role. */
64+
enum bt_conn_le_cs_role role;
65+
66+
/** Number of antenna paths present in data. */
67+
uint8_t n_ap;
68+
69+
/** IQ values for local and remote measured tones. */
70+
cs_de_iq_tones_t iq_tones[CONFIG_BT_RAS_MAX_ANTENNA_PATHS];
71+
72+
/** Tone quality indicators */
73+
cs_de_tone_quality_t tone_quality[CONFIG_BT_RAS_MAX_ANTENNA_PATHS];
74+
75+
/** Distance estimate results */
76+
cs_de_dist_estimates_t distance_estimates[CONFIG_BT_RAS_MAX_ANTENNA_PATHS];
77+
78+
/** Total time measured during RTT measurements */
79+
int32_t rtt_accumulated_half_ns;
80+
81+
/** Number of RTT measurements taken */
82+
uint8_t rtt_count;
83+
} cs_de_report_t;
84+
85+
/**
86+
* @brief Partially populate the report.
87+
* This populates the report but does not set the distance estimates and the quality.
88+
* @param[in] local_steps Buffer to the local step data to parse.
89+
* @param[in] peer_steps Buffer to the peer ranging data to parse.
90+
* @param[in] role Role of the local controller.
91+
* @param[out] p_report Report populated with the raw data from the last ranging.
92+
*/
93+
void cs_de_populate_report(struct net_buf_simple *local_steps, struct net_buf_simple *peer_steps,
94+
enum bt_conn_le_cs_role role, cs_de_report_t *p_report);
95+
96+
/* Takes partially populated report and calculates distance estimates and quality. */
97+
cs_de_quality_t cs_de_calc(cs_de_report_t *p_report);
98+
99+
#endif /* CS_DE_H__ */

include/bluetooth/services/ras.h

+14-1
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,18 @@ int bt_ras_rreq_rd_overwritten_unsubscribe(struct bt_conn *conn);
505505
*/
506506
int bt_ras_rreq_read_features(struct bt_conn *conn, bt_ras_rreq_features_read_cb_t cb);
507507

508-
/** @brief Provide step header for each step back to the user.
508+
/** @brief Provide ranging header for the ranging data back to the user.
509+
*
510+
* @param[in] ranging_header Ranging header data.
511+
* @param[in] user_data User data.
512+
*
513+
* @retval true if data parsing should continue.
514+
* false if data parsing should be stopped.
515+
*/
516+
typedef bool (*bt_ras_rreq_ranging_header_cb_t)(struct ras_ranging_header *ranging_header,
517+
void *user_data);
518+
519+
/** @brief Provide subevent header for each subevent back to the user.
509520
*
510521
* @param[in] subevent_header Subevent header data.
511522
* @param[in] user_data User data.
@@ -541,13 +552,15 @@ typedef bool (*bt_ras_rreq_step_data_cb_t)(struct bt_le_cs_subevent_step *local_
541552
* @param[in] peer_ranging_data_buf Buffer to the peer ranging data to parse.
542553
* @param[in] local_step_data_buf Buffer to the local step data to parse.
543554
* @param[in] cs_role Channel sounding role of local device.
555+
* @param[in] ranging_header_cb Callback called (once) for the ranging header.
544556
* @param[in] subevent_header_cb Callback called with each subevent header.
545557
* @param[in] step_data_cb Callback called with each peer and local step data.
546558
* @param[in] user_data User data to be passed to the callbacks.
547559
*/
548560
void bt_ras_rreq_rd_subevent_data_parse(struct net_buf_simple *peer_ranging_data_buf,
549561
struct net_buf_simple *local_step_data_buf,
550562
enum bt_conn_le_cs_role cs_role,
563+
bt_ras_rreq_ranging_header_cb_t ranging_header_cb,
551564
bt_ras_rreq_subevent_header_cb_t subevent_header_cb,
552565
bt_ras_rreq_step_data_cb_t step_data_cb, void *user_data);
553566

samples/bluetooth/channel_sounding_ras_initiator/prj.conf

+11-6
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,16 @@ CONFIG_BT_CTLR_DATA_LENGTH_MAX=251
3434
# This reduces RAM usage. Additional RAM is needed to support optional
3535
# features such as mode 3 or multiantenna. Change or remove these if
3636
# using those features
37-
CONFIG_BT_RAS_MODE_3_SUPPORTED=n
38-
CONFIG_BT_RAS_MAX_ANTENNA_PATHS=1
39-
CONFIG_BT_CTLR_SDC_CS_MAX_ANTENNA_PATHS=1
40-
CONFIG_BT_CTLR_SDC_CS_NUM_ANTENNAS=1
41-
CONFIG_BT_CTLR_SDC_CS_STEP_MODE3=n
37+
CONFIG_BT_RAS_MODE_3_SUPPORTED=y
38+
CONFIG_BT_RAS_MAX_ANTENNA_PATHS=4
39+
CONFIG_BT_CTLR_SDC_CS_MAX_ANTENNA_PATHS=4
40+
CONFIG_BT_CTLR_SDC_CS_NUM_ANTENNAS=4
41+
CONFIG_BT_CTLR_SDC_CS_STEP_MODE3=y
4242

4343
# This size assumes the largest step size is mode 2 with one antenna path:
4444
# 12 bytes * 160 steps in a subevent. Change or remove this if using mode 3
4545
# or multiantenna.
46-
CONFIG_BT_CHANNEL_SOUNDING_REASSEMBLY_BUFFER_SIZE=1920
46+
# CONFIG_BT_CHANNEL_SOUNDING_REASSEMBLY_BUFFER_SIZE=1920
4747

4848
# This allows CS and ACL to use different PHYs
4949
CONFIG_BT_TRANSMIT_POWER_CONTROL=y
@@ -53,3 +53,8 @@ CONFIG_FPU=y
5353
CONFIG_FPU_SHARING=y
5454

5555
CONFIG_CBPRINTF_FP_SUPPORT=y
56+
57+
CONFIG_BT_CS_DE=y
58+
CONFIG_BT_CS_DE_2048_NFFT=y
59+
60+
CONFIG_BT_USE_DEBUG_KEYS=y

0 commit comments

Comments
 (0)