Skip to content

Commit 008fd88

Browse files
ppryga-nordiccarlescufi
authored andcommitted
Bluetooth: Controller: Add sampling and switching offset configuration
Start of the antenna switching and sampling CTE is configured by use of DFECTRL2 register in Nodric Radio peripheral. As of now the configuration was set to defaults, so antenna switching has started immediately after CTE procedure was started (end of CRC). Sampling was started at the very beginning of a sampling slot. It should be delayed for at least 125 ns from beginning of sampling slot and not more than 125 ns to the end of sampling slot. This is a requirement from BT 5.3 Core specification Vol 6, Part B section 2.5.4 IQ sampling. Although it seems to me that when samples are taken depends on implementation and used hardware. Taking that into account there is provided a set of KConfig options to configure samples offset for PHY 1M, PHY 2M and sapling slots 1 us and 2us separetely. Signed-off-by: Piotr Pryga <[email protected]>
1 parent b7bbe4b commit 008fd88

File tree

8 files changed

+126
-24
lines changed

8 files changed

+126
-24
lines changed

subsys/bluetooth/controller/Kconfig.df

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,61 @@ config BT_CTLR_DF_PER_SCAN_CTE_NUM_MAX
195195
periodic advertising chain. The range is taken from BT Core spec 5.1, Vol 4 Part E
196196
section 7.8.82 HCI_LE_Set_Connectionless_IQ_Sampling_Enable Max_Sampled_CTEs parameter.
197197

198+
config BT_CTLR_DF_SWITCH_OFFSET
199+
int "Antenna switch offset relative to end of CRC"
200+
depends on SOC_COMPATIBLE_NRF
201+
range -2048 2047
202+
default 0
203+
help
204+
Offset of start of antenna switching after end of the CRC. It is a signed value in number
205+
of 16M cycles. Decreasing the offset value beyond the trigger of the AoA/AoD procedure
206+
will have no effect.
207+
208+
config BT_CTLR_DF_SAMPLE_OFFSET_PHY_1M_SAMPLING_1US
209+
int "CTE sampling offset relative for PHY 1M and 1US samples spacing"
210+
depends on SOC_COMPATIBLE_NRF
211+
range -2048 2047
212+
default 1
213+
help
214+
Offset of sampling start from beginning of sampling slot. The value is a signed number
215+
of 16M cycles relative. It is used when PHY is set to PHY 1M and sampling slot duarion
216+
is 1 us. Decreasing the offset beyond the trigger of the AoA/AoD procedure will have
217+
no effect.
218+
219+
config BT_CTLR_DF_SAMPLE_OFFSET_PHY_2M_SAMPLING_1US
220+
int "CTE sampling offset relative for PHY 1M and 1US samples spacing"
221+
depends on SOC_COMPATIBLE_NRF
222+
range -2048 2047
223+
default 15
224+
help
225+
Offset of sampling start from beginning of sampling slot. The value is a signed number
226+
of 16M cycles relative. It is used when PHY is set to PHY 1M and sampling slot duarion
227+
is 1 us. Decreasing the offset beyond the trigger of the AoA/AoD procedure will have
228+
no effect.
229+
230+
231+
config BT_CTLR_DF_SAMPLE_OFFSET_PHY_1M_SAMPLING_2US
232+
int "CTE sampling offset relative for PHY 1M and 2US samples spacing"
233+
depends on SOC_COMPATIBLE_NRF
234+
range -2048 2047
235+
default 6
236+
help
237+
Offset of sampling start from beginning of sampling slot. The value is a signed number
238+
of 16M cycles relative. It is used when PHY is set to PHY 1M and sampling slot duarion
239+
is 2 us. Decreasing the offset beyond the trigger of the AoA/AoD procedure will have
240+
no effect.
241+
242+
config BT_CTLR_DF_SAMPLE_OFFSET_PHY_2M_SAMPLING_2US
243+
int "CTE sampling offset relative for PHY 1M and 2US samples spacing"
244+
depends on SOC_COMPATIBLE_NRF
245+
range -2048 2047
246+
default 20
247+
help
248+
Offset of sampling start from beginning of sampling slot. The value is a signed number
249+
of 16M cycles relative. It is used when PHY is set to PHY 1M and sampling slot duarion
250+
is 2 us. Decreasing the offset beyond the trigger of the AoA/AoD procedure will have
251+
no effect.
252+
198253
config BT_CTLR_DF_DEBUG_ENABLE
199254
bool "Bluetooth Direction Finding debug support enable"
200255
help

subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_df.c

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#include <hal/nrf_gpio.h>
1414
#include <hal/ccm.h>
1515

16+
#include "ll_sw/pdu.h"
17+
1618
#include "radio_nrf5.h"
1719
#include "radio.h"
1820
#include "radio_df.h"
@@ -244,8 +246,10 @@ static void radio_df_cte_inline_set_disabled(void)
244246

245247
static inline void radio_df_ctrl_set(uint8_t cte_len,
246248
uint8_t switch_spacing,
247-
uint8_t sample_spacing)
249+
uint8_t sample_spacing,
250+
uint8_t phy)
248251
{
252+
uint16_t sample_offset;
249253
uint32_t conf;
250254

251255
/* Complete setup is done on purpose, to be sure that there isn't left
@@ -265,60 +269,99 @@ static inline void radio_df_ctrl_set(uint8_t cte_len,
265269
RADIO_DFECTRL1_AGCBACKOFFGAIN_Msk));
266270

267271
NRF_RADIO->DFECTRL1 = conf;
272+
273+
switch (phy) {
274+
case PHY_1M:
275+
if (switch_spacing == RADIO_DFECTRL1_TSWITCHSPACING_2us) {
276+
sample_offset = CONFIG_BT_CTLR_DF_SAMPLE_OFFSET_PHY_1M_SAMPLING_1US;
277+
} else if (switch_spacing == RADIO_DFECTRL1_TSWITCHSPACING_4us) {
278+
sample_offset = CONFIG_BT_CTLR_DF_SAMPLE_OFFSET_PHY_1M_SAMPLING_2US;
279+
} else {
280+
sample_offset = 0;
281+
}
282+
case PHY_2M:
283+
if (switch_spacing == RADIO_DFECTRL1_TSWITCHSPACING_2us) {
284+
sample_offset = CONFIG_BT_CTLR_DF_SAMPLE_OFFSET_PHY_2M_SAMPLING_1US;
285+
} else if (switch_spacing == RADIO_DFECTRL1_TSWITCHSPACING_4us) {
286+
sample_offset = CONFIG_BT_CTLR_DF_SAMPLE_OFFSET_PHY_2M_SAMPLING_2US;
287+
} else {
288+
sample_offset = 0;
289+
}
290+
break;
291+
case PHY_LEGACY:
292+
default:
293+
/* If phy is set to legacy, the function is called in TX context and actual value
294+
* does not matter, hence it is set to default zero.
295+
*/
296+
sample_offset = 0;
297+
}
298+
299+
conf = ((((uint32_t)sample_offset << RADIO_DFECTRL2_TSAMPLEOFFSET_Pos) &
300+
RADIO_DFECTRL2_TSAMPLEOFFSET_Msk) |
301+
(((uint32_t)CONFIG_BT_CTLR_DF_SWITCH_OFFSET << RADIO_DFECTRL2_TSWITCHOFFSET_Pos) &
302+
RADIO_DFECTRL2_TSWITCHOFFSET_Msk));
303+
304+
NRF_RADIO->DFECTRL2 = conf;
268305
}
269306

270307
void radio_df_cte_tx_aod_2us_set(uint8_t cte_len)
271308
{
272309
/* Sample spacing does not matter for AoD Tx. It is set to value
273310
* that is in DFECTRL1 register after reset. That is done instead of
274311
* adding conditions on the value and masking of the field before
275-
* storing configuration in the register.
312+
* storing configuration in the register. Also values in DFECTRL2,
313+
* that depend on PHY, are irrelevand for AoD Tx, hence use of
314+
* PHY_LEGACY here.
276315
*/
277316
radio_df_ctrl_set(cte_len, RADIO_DFECTRL1_TSWITCHSPACING_2us,
278-
RADIO_DFECTRL1_TSAMPLESPACING_2us);
317+
RADIO_DFECTRL1_TSAMPLESPACING_2us, PHY_LEGACY);
279318
}
280319

281320
void radio_df_cte_tx_aod_4us_set(uint8_t cte_len)
282321
{
283322
/* Sample spacing does not matter for AoD Tx. It is set to value
284323
* that is in DFECTRL1 register after reset. That is done instead of
285324
* adding conditions on the value and masking of the field before
286-
* storing configuration in the register.
325+
* storing configuration in the register. Also values in DFECTRL2,
326+
* that depend on PHY, are irrelevand for AoD Tx, hence use of
327+
* PHY_LEGACY here.
287328
*/
288329
radio_df_ctrl_set(cte_len, RADIO_DFECTRL1_TSWITCHSPACING_4us,
289-
RADIO_DFECTRL1_TSAMPLESPACING_2us);
330+
RADIO_DFECTRL1_TSAMPLESPACING_2us, PHY_LEGACY);
290331
}
291332

292333
void radio_df_cte_tx_aoa_set(uint8_t cte_len)
293334
{
294335
/* Switch and sample spacing does not matter for AoA Tx. It is set to
295336
* value that is in DFECTRL1 register after reset. That is done instead
296337
* of adding conditions on the value and masking of the field before
297-
* storing configuration in the register.
338+
* storing configuration in the register. Also values in DFECTRL2,
339+
* that depend on PHY, are irrelevand for AoA Tx, hence use of
340+
* PHY_LEGACY here.
298341
*/
299342
radio_df_ctrl_set(cte_len, RADIO_DFECTRL1_TSWITCHSPACING_4us,
300-
RADIO_DFECTRL1_TSAMPLESPACING_2us);
343+
RADIO_DFECTRL1_TSAMPLESPACING_2us, PHY_LEGACY);
301344
}
302345

303-
void radio_df_cte_rx_2us_switching(bool cte_info_in_s1)
346+
void radio_df_cte_rx_2us_switching(bool cte_info_in_s1, uint8_t phy)
304347
{
305348
/* BT spec requires single sample for a single switching slot, so
306349
* spacing for slot and samples is the same.
307350
* CTE duation is used only when CTEINLINE config is disabled.
308351
*/
309352
radio_df_ctrl_set(0, RADIO_DFECTRL1_TSWITCHSPACING_2us,
310-
RADIO_DFECTRL1_TSAMPLESPACING_2us);
353+
RADIO_DFECTRL1_TSAMPLESPACING_2us, phy);
311354
radio_df_cte_inline_set_enabled(cte_info_in_s1);
312355
}
313356

314-
void radio_df_cte_rx_4us_switching(bool cte_info_in_s1)
357+
void radio_df_cte_rx_4us_switching(bool cte_info_in_s1, uint8_t phy)
315358
{
316359
/* BT spec requires single sample for a single switching slot, so
317360
* spacing for slot and samples is the same.
318361
* CTE duation is used only when CTEINLINE config is disabled.
319362
*/
320363
radio_df_ctrl_set(0, RADIO_DFECTRL1_TSWITCHSPACING_4us,
321-
RADIO_DFECTRL1_TSAMPLESPACING_4us);
364+
RADIO_DFECTRL1_TSAMPLESPACING_4us, phy);
322365
radio_df_cte_inline_set_enabled(cte_info_in_s1);
323366
}
324367

subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_df.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ void radio_df_cte_tx_aod_4us_set(uint8_t cte_len);
3434
/* Configure CTE transmission with for AoA. */
3535
void radio_df_cte_tx_aoa_set(uint8_t cte_len);
3636
/* Configure CTE reception with optionall AoA mode and 2us antenna switching. */
37-
void radio_df_cte_rx_2us_switching(bool cte_info_in_s1);
37+
void radio_df_cte_rx_2us_switching(bool cte_info_in_s1, uint8_t phy);
3838
/* Configure CTE reception with optionall AoA mode and 4us antenna switching. */
39-
void radio_df_cte_rx_4us_switching(bool cte_info_in_s1);
39+
void radio_df_cte_rx_4us_switching(bool cte_info_in_s1, uint8_t phy);
4040

4141
/* Clears antenna switch pattern. */
4242
void radio_df_ant_switch_pattern_clear(void);

subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,8 @@ void lll_conn_isr_tx(void *param)
490490
if (df_rx_params->is_enabled) {
491491
lll_df_conf_cte_rx_enable(df_rx_params->slot_durations,
492492
df_rx_params->ant_sw_len, df_rx_params->ant_ids,
493-
df_rx_cfg->chan, CTE_INFO_IN_S1_BYTE);
493+
df_rx_cfg->chan, CTE_INFO_IN_S1_BYTE,
494+
lll->phy_rx);
494495
} else {
495496
lll_df_conf_cte_info_parsing_enable();
496497
}

subsys/bluetooth/controller/ll_sw/nordic/lll/lll_df.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,22 +217,23 @@ struct lll_df_sync_cfg *lll_df_sync_cfg_latest_get(struct lll_df_sync *df_cfg,
217217
* @param chan_idx Channel used to receive PDU with CTE
218218
* @param cte_info_in_s1 Inform if CTEInfo is in S1 byte for conn. PDU or in extended advertising
219219
* header of per. adv. PDU.
220+
* @param phy Current PHY
220221
*
221222
* In case of AoA mode ant_num and ant_ids parameters are not used.
222223
*/
223224
void lll_df_conf_cte_rx_enable(uint8_t slot_duration, uint8_t ant_num, const uint8_t *ant_ids,
224-
uint8_t chan_idx, bool cte_info_in_s1)
225+
uint8_t chan_idx, bool cte_info_in_s1, uint8_t phy)
225226
{
226227
struct node_rx_iq_report *node_rx;
227228

228229
/* ToDo change to appropriate HCI constant */
229230
#if defined(CONFIG_BT_CTLR_DF_ANT_SWITCH_1US)
230231
if (slot_duration == 0x1) {
231-
radio_df_cte_rx_2us_switching(cte_info_in_s1);
232+
radio_df_cte_rx_2us_switching(cte_info_in_s1, phy);
232233
} else
233234
#endif /* CONFIG_BT_CTLR_DF_ANT_SWITCH_1US */
234235
{
235-
radio_df_cte_rx_4us_switching(cte_info_in_s1);
236+
radio_df_cte_rx_4us_switching(cte_info_in_s1, phy);
236237
}
237238

238239
#if defined(CONFIG_BT_CTLR_DF_ANT_SWITCH_RX)
@@ -261,8 +262,10 @@ void lll_df_conf_cte_info_parsing_enable(void)
261262
/* Use of mandatory 2 us switching and sampling slots for CTEInfo parsing.
262263
* The configuration here does not matter for actual IQ sampling.
263264
* The collected data will not be reported to host.
265+
* Also sampling offset does not matter so, provided PHY is legacy to setup
266+
* the offset to default zero value.
264267
*/
265-
radio_df_cte_rx_4us_switching(true);
268+
radio_df_cte_rx_4us_switching(true, PHY_LEGACY);
266269

267270
#if defined(CONFIG_BT_CTLR_DF_ANT_SWITCH_RX)
268271
/* Use PDU_ANTENNA so no actual antenna change will be done. */

subsys/bluetooth/controller/ll_sw/nordic/lll/lll_df_internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ static inline uint8_t lll_df_sync_cfg_is_modified(struct lll_df_sync *df_cfg)
5757

5858
/* Enables CTE reception according to provided configuration */
5959
void lll_df_conf_cte_rx_enable(uint8_t slot_duration, uint8_t ant_num, const uint8_t *ant_ids,
60-
uint8_t chan_idx, bool cte_info_in_s1);
60+
uint8_t chan_idx, bool cte_info_in_s1, uint8_t phy);
6161

6262
/* Configure CTE transmission */
6363
void lll_df_cte_tx_configure(uint8_t cte_type, uint8_t cte_length, uint8_t num_ant_ids,

subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ static int prepare_cb(struct lll_prepare_param *p)
229229
if (df_rx_params->is_enabled == true) {
230230
lll_df_conf_cte_rx_enable(df_rx_params->slot_durations,
231231
df_rx_params->ant_sw_len, df_rx_params->ant_ids,
232-
data_chan_use, CTE_INFO_IN_S1_BYTE);
232+
data_chan_use, CTE_INFO_IN_S1_BYTE, lll->phy_rx);
233233
lll->df_rx_cfg.chan = data_chan_use;
234234
} else {
235235
lll_df_conf_cte_info_parsing_enable();

subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ void lll_sync_aux_prepare_cb(struct lll_sync *lll,
172172

173173
if (cfg->is_enabled) {
174174
lll_df_conf_cte_rx_enable(cfg->slot_durations, cfg->ant_sw_len, cfg->ant_ids,
175-
lll_aux->chan, CTE_INFO_IN_PAYLOAD);
175+
lll_aux->chan, CTE_INFO_IN_PAYLOAD, lll_aux->phy);
176176
cfg->cte_count = 0;
177177
}
178178
#endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */
@@ -280,7 +280,7 @@ static int create_prepare_cb(struct lll_prepare_param *p)
280280
} else if (cfg->is_enabled) {
281281

282282
lll_df_conf_cte_rx_enable(cfg->slot_durations, cfg->ant_sw_len, cfg->ant_ids,
283-
chan_idx, CTE_INFO_IN_PAYLOAD);
283+
chan_idx, CTE_INFO_IN_PAYLOAD, lll->phy);
284284
cfg->cte_count = 0;
285285
#endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */
286286
} else if (IS_ENABLED(CONFIG_BT_CTLR_DF_SUPPORT)) {
@@ -339,7 +339,7 @@ static int prepare_cb(struct lll_prepare_param *p)
339339

340340
if (cfg->is_enabled) {
341341
lll_df_conf_cte_rx_enable(cfg->slot_durations, cfg->ant_sw_len, cfg->ant_ids,
342-
chan_idx, CTE_INFO_IN_PAYLOAD);
342+
chan_idx, CTE_INFO_IN_PAYLOAD, lll->phy);
343343
cfg->cte_count = 0;
344344
}
345345
#endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */
@@ -570,7 +570,7 @@ static void isr_aux_setup(void *param)
570570

571571
if (cfg->is_enabled && is_max_cte_reached(cfg->max_cte_count, cfg->cte_count)) {
572572
lll_df_conf_cte_rx_enable(cfg->slot_durations, cfg->ant_sw_len, cfg->ant_ids,
573-
aux_ptr->chan_idx, CTE_INFO_IN_PAYLOAD);
573+
aux_ptr->chan_idx, CTE_INFO_IN_PAYLOAD, aux_ptr->phy);
574574
}
575575
#endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */
576576
radio_switch_complete_and_disable();

0 commit comments

Comments
 (0)