1 /*
2 * Copyright (c) 2016 - 2020 Nordic Semiconductor ASA
3 * Copyright (c) 2016 Vinayak Kariappa Chettimada
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #include <zephyr/toolchain.h>
9 #include <zephyr/dt-bindings/gpio/gpio.h>
10 #include <zephyr/sys/byteorder.h>
11 #include <soc.h>
12
13 #include <nrfx_gpiote.h>
14
15 #include "util/mem.h"
16
17 #include "hal/cpu.h"
18 #include "hal/ccm.h"
19 #include "hal/cntr.h"
20 #include "hal/radio.h"
21 #include "hal/radio_df.h"
22 #include "hal/ticker.h"
23
24 #include "ll_sw/pdu_df.h"
25 #include "lll/pdu_vendor.h"
26 #include "ll_sw/pdu.h"
27
28 #include "radio_internal.h"
29
30 /* Converts the GPIO controller in a FEM property's GPIO specification
31 * to its nRF register map pointer.
32 *
33 * Make sure to use NRF_DT_CHECK_GPIO_CTLR_IS_SOC to check the GPIO
34 * controller has the right compatible wherever you use this.
35 */
36 #define NRF_FEM_GPIO(prop) \
37 ((NRF_GPIO_Type *)DT_REG_ADDR(DT_GPIO_CTLR(FEM_NODE, prop)))
38
39 /* Converts GPIO specification to a PSEL value. */
40 #define NRF_FEM_PSEL(prop) NRF_DT_GPIOS_TO_PSEL(FEM_NODE, prop)
41
42 /* Check if GPIO flags are active low. */
43 #define ACTIVE_LOW(flags) ((flags) & GPIO_ACTIVE_LOW)
44
45 /* Check if GPIO flags contain unsupported values. */
46 #define BAD_FLAGS(flags) ((flags) & ~GPIO_ACTIVE_LOW)
47
48 /* GPIOTE OUTINIT setting for a pin's inactive level, from its
49 * devicetree flags.
50 */
51 #define OUTINIT_INACTIVE(flags) \
52 (ACTIVE_LOW(flags) ? \
53 GPIOTE_CONFIG_OUTINIT_High : \
54 GPIOTE_CONFIG_OUTINIT_Low)
55
56 #if defined(FEM_NODE)
57 BUILD_ASSERT(!HAL_RADIO_GPIO_PA_OFFSET_MISSING,
58 "fem node " DT_NODE_PATH(FEM_NODE) " has property "
59 HAL_RADIO_GPIO_PA_PROP_NAME " set, so you must also set "
60 HAL_RADIO_GPIO_PA_OFFSET_PROP_NAME);
61
62 BUILD_ASSERT(!HAL_RADIO_GPIO_LNA_OFFSET_MISSING,
63 "fem node " DT_NODE_PATH(FEM_NODE) " has property "
64 HAL_RADIO_GPIO_LNA_PROP_NAME " set, so you must also set "
65 HAL_RADIO_GPIO_LNA_OFFSET_PROP_NAME);
66 #endif /* FEM_NODE */
67
68 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN) || defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
69 static const nrfx_gpiote_t gpiote_palna = NRFX_GPIOTE_INSTANCE(
70 NRF_DT_GPIOTE_INST(FEM_NODE, HAL_RADIO_GPIO_PA_PROP));
71 static uint8_t gpiote_ch_palna;
72
73 BUILD_ASSERT(NRF_DT_GPIOTE_INST(FEM_NODE, HAL_RADIO_GPIO_PA_PROP) ==
74 NRF_DT_GPIOTE_INST(FEM_NODE, HAL_RADIO_GPIO_LNA_PROP),
75 HAL_RADIO_GPIO_PA_PROP_NAME " and " HAL_RADIO_GPIO_LNA_PROP_NAME
76 " GPIOs must use the same GPIOTE instance.");
77 #endif
78
79 #if defined(HAL_RADIO_FEM_IS_NRF21540)
80 static const nrfx_gpiote_t gpiote_pdn = NRFX_GPIOTE_INSTANCE(
81 NRF_DT_GPIOTE_INST(FEM_NODE, pdn_gpios));
82 static uint8_t gpiote_ch_pdn;
83 #endif
84
85 /* These headers require the above gpiote-related variables to be declared. */
86 #if defined(PPI_PRESENT)
87 #include "radio_nrf5_ppi_gpiote.h"
88 #elif defined(DPPI_PRESENT)
89 #include "radio_nrf5_dppi_gpiote.h"
90 #endif
91
92 /*
93 * "Manual" conversions of devicetree values to register bits. We
94 * can't use the Zephyr GPIO API here, so we need this extra
95 * boilerplate.
96 */
97
98 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN)
99 #define NRF_GPIO_PA NRF_FEM_GPIO(HAL_RADIO_GPIO_PA_PROP)
100 #define NRF_GPIO_PA_PIN DT_GPIO_PIN(FEM_NODE, HAL_RADIO_GPIO_PA_PROP)
101 #define NRF_GPIO_PA_FLAGS DT_GPIO_FLAGS(FEM_NODE, HAL_RADIO_GPIO_PA_PROP)
102 #define NRF_GPIO_PA_PSEL NRF_FEM_PSEL(HAL_RADIO_GPIO_PA_PROP)
103 NRF_DT_CHECK_GPIO_CTLR_IS_SOC(FEM_NODE, HAL_RADIO_GPIO_PA_PROP,
104 HAL_RADIO_GPIO_PA_PROP_NAME);
105 BUILD_ASSERT(!BAD_FLAGS(NRF_GPIO_PA_FLAGS),
106 "fem node " DT_NODE_PATH(FEM_NODE) " has invalid GPIO flags in "
107 HAL_RADIO_GPIO_PA_PROP_NAME
108 "; only GPIO_ACTIVE_LOW or GPIO_ACTIVE_HIGH are supported");
109 #endif /* HAL_RADIO_GPIO_HAVE_PA_PIN */
110
111 #if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
112 #define NRF_GPIO_LNA NRF_FEM_GPIO(HAL_RADIO_GPIO_LNA_PROP)
113 #define NRF_GPIO_LNA_PIN DT_GPIO_PIN(FEM_NODE, HAL_RADIO_GPIO_LNA_PROP)
114 #define NRF_GPIO_LNA_FLAGS DT_GPIO_FLAGS(FEM_NODE, HAL_RADIO_GPIO_LNA_PROP)
115 #define NRF_GPIO_LNA_PSEL NRF_FEM_PSEL(HAL_RADIO_GPIO_LNA_PROP)
116 NRF_DT_CHECK_GPIO_CTLR_IS_SOC(FEM_NODE, HAL_RADIO_GPIO_LNA_PROP,
117 HAL_RADIO_GPIO_LNA_PROP_NAME);
118 BUILD_ASSERT(!BAD_FLAGS(NRF_GPIO_LNA_FLAGS),
119 "fem node " DT_NODE_PATH(FEM_NODE) " has invalid GPIO flags in "
120 HAL_RADIO_GPIO_LNA_PROP_NAME
121 "; only GPIO_ACTIVE_LOW or GPIO_ACTIVE_HIGH are supported");
122 #endif /* HAL_RADIO_GPIO_HAVE_LNA_PIN */
123
124 #if defined(HAL_RADIO_FEM_IS_NRF21540)
125
126 #if DT_NODE_HAS_PROP(FEM_NODE, pdn_gpios)
127 #define NRF_GPIO_PDN NRF_FEM_GPIO(pdn_gpios)
128 #define NRF_GPIO_PDN_PIN DT_GPIO_PIN(FEM_NODE, pdn_gpios)
129 #define NRF_GPIO_PDN_FLAGS DT_GPIO_FLAGS(FEM_NODE, pdn_gpios)
130 #define NRF_GPIO_PDN_PSEL NRF_FEM_PSEL(pdn_gpios)
131 #define NRF_GPIO_PDN_OFFSET DT_PROP(FEM_NODE, pdn_settle_time_us)
132 NRF_DT_CHECK_GPIO_CTLR_IS_SOC(FEM_NODE, pdn_gpios, "pdn-gpios");
133 #endif /* DT_NODE_HAS_PROP(FEM_NODE, pdn_gpios) */
134
135 #endif /* HAL_RADIO_FEM_IS_NRF21540 */
136
137 /* CTEINLINE S0_MASK for periodic advertising PUDs. It allows to accept all types of extended
138 * advertising PDUs to have CTE included.
139 */
140 #define DF_S0_ALLOW_ALL_PER_ADV_PDU 0x0
141 /* CTEINLINE S0_MASK for data channel PDUs. It points to CP bit in S0 byte to check if is it set
142 * to 0x1. In that is true then S1 byte (CTEInfo) is considered as present in a PDU.
143 */
144 #define DF_S0_MASK_CP_BIT_IN_DATA_CHANNEL_PDU 0x20
145
146 static radio_isr_cb_t isr_cb;
147 static void *isr_cb_param;
148
isr_radio(void)149 void isr_radio(void)
150 {
151 if (radio_has_disabled()) {
152 isr_cb(isr_cb_param);
153 }
154 }
155
radio_isr_set(radio_isr_cb_t cb,void * param)156 void radio_isr_set(radio_isr_cb_t cb, void *param)
157 {
158 irq_disable(HAL_RADIO_IRQn);
159
160 isr_cb_param = param;
161 isr_cb = cb;
162
163 nrf_radio_int_enable(NRF_RADIO, HAL_RADIO_INTENSET_DISABLED_Msk);
164
165 NVIC_ClearPendingIRQ(HAL_RADIO_IRQn);
166 irq_enable(HAL_RADIO_IRQn);
167 }
168
radio_setup(void)169 void radio_setup(void)
170 {
171 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN)
172 NRF_GPIO_PA->DIRSET = BIT(NRF_GPIO_PA_PIN);
173 if (ACTIVE_LOW(NRF_GPIO_PA_FLAGS)) {
174 NRF_GPIO_PA->OUTSET = BIT(NRF_GPIO_PA_PIN);
175 } else {
176 NRF_GPIO_PA->OUTCLR = BIT(NRF_GPIO_PA_PIN);
177 }
178 #endif /* HAL_RADIO_GPIO_HAVE_PA_PIN */
179
180 #if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
181 NRF_GPIO_LNA->DIRSET = BIT(NRF_GPIO_LNA_PIN);
182
183 radio_gpio_lna_off();
184 #endif /* HAL_RADIO_GPIO_HAVE_LNA_PIN */
185
186 #if defined(NRF_GPIO_PDN_PIN)
187 NRF_GPIO_PDN->DIRSET = BIT(NRF_GPIO_PDN_PIN);
188 if (ACTIVE_LOW(NRF_GPIO_PDN_FLAGS)) {
189 NRF_GPIO_PDN->OUTSET = BIT(NRF_GPIO_PDN_PIN);
190 } else {
191 NRF_GPIO_PDN->OUTCLR = BIT(NRF_GPIO_PDN_PIN);
192 }
193 #endif /* NRF_GPIO_PDN_PIN */
194
195 hal_radio_ram_prio_setup();
196 }
197
radio_reset(void)198 void radio_reset(void)
199 {
200 irq_disable(HAL_RADIO_IRQn);
201
202 /* nRF SoC generic radio reset/initializations
203 * Note: Only registers whose bits are partially modified across
204 * functions are assigned back the power-on reset values.
205 * Ignore other registers for reset which will have all bits
206 * explicitly assigned by functions in this file.
207 */
208 NRF_RADIO->PCNF1 = HAL_RADIO_RESET_VALUE_PCNF1;
209
210 #if defined(CONFIG_BT_CTLR_DF) && !defined(CONFIG_ZTEST)
211 radio_df_reset();
212 #endif /* CONFIG_BT_CTLR_DF && !CONFIG_ZTEST */
213
214 /* nRF SoC specific reset/initializations, if any */
215 hal_radio_reset();
216
217 #if !defined(CONFIG_BT_CTLR_TIFS_HW)
218 hal_radio_sw_switch_ppi_group_setup();
219 #endif
220
221 #if defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
222 #if defined(CONFIG_BT_CTLR_TIFS_HW)
223 NRF_RADIO->TIMING = (RADIO_TIMING_RU_Legacy << RADIO_TIMING_RU_Pos) &
224 RADIO_TIMING_RU_Msk;
225 #else /* !CONFIG_BT_CTLR_TIFS_HW */
226 NRF_RADIO->TIMING = (RADIO_TIMING_RU_Fast << RADIO_TIMING_RU_Pos) &
227 RADIO_TIMING_RU_Msk;
228 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
229
230 NRF_POWER->TASKS_CONSTLAT = 1U;
231 #endif /* CONFIG_SOC_COMPATIBLE_NRF54LX */
232
233 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN) || defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
234 hal_palna_ppi_setup();
235 #endif
236 #if defined(HAL_RADIO_FEM_IS_NRF21540)
237 hal_fem_ppi_setup();
238 #endif
239 }
240
radio_stop(void)241 void radio_stop(void)
242 {
243 /* nRF SoC specific radio stop/cleanup, if any */
244 hal_radio_stop();
245
246 /* nRF SoC generic radio stop/cleanup
247 * TODO: Initialize NRF_RADIO registers used by Controller to power-on
248 * reset values.
249 * This is required in case NRF_RADIO is share/used between
250 * Bluetooth radio events by application defined radio protocols.
251 * The application too shall restore the registers it uses to the
252 * power-on reset values once it has stopped using the radio.
253 *
254 * Registers used for Bluetooth Low Energy Controller:
255 * - MODE
256 * - MODECNF0
257 * - TXPOWER
258 * - FREQUENCY
259 * - DATAWHITEIV
260 * - PCNF0
261 * - PCNF1
262 * - TXADDRESS
263 * - RXADDRESSES
264 * - PREFIX0
265 * - BASE0
266 * - PACKETPTR
267 * - CRCCNF
268 * - CRCPOLY
269 * - CRCINIT
270 * - DAB
271 * - DAP
272 * - DACNF
273 * - BCC
274 * - TIFS
275 * - SHORTS
276 *
277 * Additional registers used for Direction Finding feature:
278 * - SWITCHPATTERN
279 * - DFEMODE
280 * - CTEINLINECONF
281 * - DFECTRL1
282 * - DEFCTRL2
283 * - CLEARPATTERN
284 * - PSEL.DFEGPIO[n]
285 * - DFEPACKET.PTR
286 */
287 }
288
radio_phy_set(uint8_t phy,uint8_t flags)289 void radio_phy_set(uint8_t phy, uint8_t flags)
290 {
291 uint32_t mode;
292
293 mode = hal_radio_phy_mode_get(phy, flags);
294
295 NRF_RADIO->MODE = (mode << RADIO_MODE_MODE_Pos) & RADIO_MODE_MODE_Msk;
296
297 #if !defined(CONFIG_SOC_SERIES_NRF51X) && !defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
298 #if defined(CONFIG_BT_CTLR_RADIO_ENABLE_FAST)
299 NRF_RADIO->MODECNF0 = ((RADIO_MODECNF0_DTX_Center <<
300 RADIO_MODECNF0_DTX_Pos) &
301 RADIO_MODECNF0_DTX_Msk) |
302 ((RADIO_MODECNF0_RU_Fast <<
303 RADIO_MODECNF0_RU_Pos) &
304 RADIO_MODECNF0_RU_Msk);
305 #else /* !CONFIG_BT_CTLR_RADIO_ENABLE_FAST */
306 NRF_RADIO->MODECNF0 = (RADIO_MODECNF0_DTX_Center <<
307 RADIO_MODECNF0_DTX_Pos) &
308 RADIO_MODECNF0_DTX_Msk;
309 #endif /* !CONFIG_BT_CTLR_RADIO_ENABLE_FAST */
310 #endif /* !CONFIG_SOC_SERIES_NRF51X && !CONFIG_SOC_COMPATIBLE_NRF54LX */
311 }
312
radio_tx_power_set(int8_t power)313 void radio_tx_power_set(int8_t power)
314 {
315 #if defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
316 uint32_t value;
317
318 value = hal_radio_tx_power_value(power);
319 NRF_RADIO->TXPOWER = value;
320
321 #elif defined(CONFIG_SOC_COMPATIBLE_NRF53X)
322 uint32_t value;
323
324 /* NOTE: TXPOWER register only accepts upto 0dBm, hence use the HAL
325 * floor value for the TXPOWER register. Permit +3dBm by using high
326 * voltage being set for radio.
327 */
328 value = hal_radio_tx_power_floor(power);
329 NRF_RADIO->TXPOWER = value;
330 hal_radio_tx_power_high_voltage_set(power);
331
332 #else /* !CONFIG_SOC_COMPATIBLE_NRF53X && !CONFIG_SOC_COMPATIBLE_NRF54LX */
333
334 /* NOTE: valid value range is passed by Kconfig define. */
335 NRF_RADIO->TXPOWER = (uint32_t)power;
336
337 #endif /* !CONFIG_SOC_COMPATIBLE_NRF53X && !CONFIG_SOC_COMPATIBLE_NRF54LX */
338 }
339
radio_tx_power_max_set(void)340 void radio_tx_power_max_set(void)
341 {
342 int8_t power;
343
344 power = radio_tx_power_max_get();
345 radio_tx_power_set(power);
346 }
347
radio_tx_power_min_get(void)348 int8_t radio_tx_power_min_get(void)
349 {
350 return (int8_t)hal_radio_tx_power_min_get();
351 }
352
radio_tx_power_max_get(void)353 int8_t radio_tx_power_max_get(void)
354 {
355 #if defined(CONFIG_SOC_COMPATIBLE_NRF53X)
356 return RADIO_TXPOWER_TXPOWER_Pos3dBm;
357
358 #else /* !CONFIG_SOC_COMPATIBLE_NRF53X */
359 return (int8_t)hal_radio_tx_power_max_get();
360
361 #endif /* !CONFIG_SOC_COMPATIBLE_NRF53X */
362 }
363
radio_tx_power_floor(int8_t power)364 int8_t radio_tx_power_floor(int8_t power)
365 {
366 #if defined(CONFIG_SOC_COMPATIBLE_NRF53X)
367 /* NOTE: TXPOWER register only accepts upto 0dBm, +3dBm permitted by
368 * use of high voltage being set for radio when TXPOWER register is set.
369 */
370 if (power >= (int8_t)RADIO_TXPOWER_TXPOWER_Pos3dBm) {
371 return RADIO_TXPOWER_TXPOWER_Pos3dBm;
372 }
373 #endif /* CONFIG_SOC_COMPATIBLE_NRF53X */
374
375 return (int8_t)hal_radio_tx_power_floor(power);
376 }
377
radio_freq_chan_set(uint32_t chan)378 void radio_freq_chan_set(uint32_t chan)
379 {
380 NRF_RADIO->FREQUENCY = chan;
381 }
382
radio_whiten_iv_set(uint32_t iv)383 void radio_whiten_iv_set(uint32_t iv)
384 {
385 #if defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
386 #if defined(RADIO_DATAWHITEIV_DATAWHITEIV_Msk)
387 NRF_RADIO->DATAWHITEIV = HAL_RADIO_RESET_VALUE_DATAWHITE | iv;
388 #else /* !RADIO_DATAWHITEIV_DATAWHITEIV_Msk */
389 NRF_RADIO->DATAWHITE = HAL_RADIO_RESET_VALUE_DATAWHITE | iv;
390 #endif /* !RADIO_DATAWHITEIV_DATAWHITEIV_Msk */
391 #else /* !CONFIG_SOC_COMPATIBLE_NRF54LX */
392 nrf_radio_datawhiteiv_set(NRF_RADIO, iv);
393 #endif /* !CONFIG_SOC_COMPATIBLE_NRF54LX */
394
395 NRF_RADIO->PCNF1 &= ~RADIO_PCNF1_WHITEEN_Msk;
396 NRF_RADIO->PCNF1 |= ((1UL) << RADIO_PCNF1_WHITEEN_Pos) &
397 RADIO_PCNF1_WHITEEN_Msk;
398 }
399
radio_aa_set(const uint8_t * aa)400 void radio_aa_set(const uint8_t *aa)
401 {
402 NRF_RADIO->TXADDRESS =
403 (((0UL) << RADIO_TXADDRESS_TXADDRESS_Pos) &
404 RADIO_TXADDRESS_TXADDRESS_Msk);
405 NRF_RADIO->RXADDRESSES =
406 ((RADIO_RXADDRESSES_ADDR0_Enabled) << RADIO_RXADDRESSES_ADDR0_Pos);
407 NRF_RADIO->PREFIX0 = aa[3];
408 NRF_RADIO->BASE0 = sys_get_le24(aa) << 8;
409 }
410
radio_pkt_configure(uint8_t bits_len,uint8_t max_len,uint8_t flags)411 void radio_pkt_configure(uint8_t bits_len, uint8_t max_len, uint8_t flags)
412 {
413 const uint8_t pdu_type = RADIO_PKT_CONF_PDU_TYPE_GET(flags); /* Adv or Data channel */
414 uint8_t bits_s1;
415 uint32_t extra;
416 uint8_t phy;
417
418 #if defined(CONFIG_SOC_SERIES_NRF51X)
419 ARG_UNUSED(phy);
420
421 extra = 0U;
422
423 /* nRF51 supports only 27 byte PDU when using h/w CCM for encryption. */
424 if (!IS_ENABLED(CONFIG_BT_CTLR_DATA_LENGTH_CLEAR) &&
425 pdu_type == RADIO_PKT_CONF_PDU_TYPE_DC) {
426 bits_len = RADIO_PKT_CONF_LENGTH_5BIT;
427 }
428 bits_s1 = RADIO_PKT_CONF_LENGTH_8BIT - bits_len;
429
430 #elif defined(CONFIG_SOC_COMPATIBLE_NRF52X) || \
431 defined(CONFIG_SOC_COMPATIBLE_NRF53X) || \
432 defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
433 extra = 0U;
434
435 phy = RADIO_PKT_CONF_PHY_GET(flags);
436 switch (phy) {
437 case PHY_1M:
438 default:
439 extra |= (RADIO_PCNF0_PLEN_8bit << RADIO_PCNF0_PLEN_Pos) &
440 RADIO_PCNF0_PLEN_Msk;
441 break;
442
443 case PHY_2M:
444 extra |= (RADIO_PCNF0_PLEN_16bit << RADIO_PCNF0_PLEN_Pos) &
445 RADIO_PCNF0_PLEN_Msk;
446 break;
447
448 #if defined(CONFIG_BT_CTLR_PHY_CODED)
449 #if defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED)
450 case PHY_CODED:
451 extra |= (RADIO_PCNF0_PLEN_LongRange << RADIO_PCNF0_PLEN_Pos) &
452 RADIO_PCNF0_PLEN_Msk;
453 extra |= (2UL << RADIO_PCNF0_CILEN_Pos) & RADIO_PCNF0_CILEN_Msk;
454 extra |= (3UL << RADIO_PCNF0_TERMLEN_Pos) &
455 RADIO_PCNF0_TERMLEN_Msk;
456 break;
457 #endif /* CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */
458 #endif /* CONFIG_BT_CTLR_PHY_CODED */
459 }
460
461 /* To use same Data Channel PDU structure with nRF5 specific overhead
462 * byte, include the S1 field in radio packet configuration.
463 */
464 if ((pdu_type == RADIO_PKT_CONF_PDU_TYPE_DC) ||
465 (pdu_type == RADIO_PKT_CONF_PDU_TYPE_BIS) ||
466 (pdu_type == RADIO_PKT_CONF_PDU_TYPE_CIS)) {
467 extra |= (RADIO_PCNF0_S1INCL_Include <<
468 RADIO_PCNF0_S1INCL_Pos) & RADIO_PCNF0_S1INCL_Msk;
469 #if defined(CONFIG_BT_CTLR_DF)
470 if (RADIO_PKT_CONF_CTE_GET(flags) == RADIO_PKT_CONF_CTE_ENABLED) {
471 bits_s1 = RADIO_PKT_CONF_S1_8BIT;
472 } else
473 #endif /* CONFIG_BT_CTLR_DF */
474 {
475 bits_s1 = 0U;
476 }
477 } else {
478 bits_s1 = 0U;
479 }
480 #endif /* CONFIG_SOC_COMPATIBLE_NRF52X */
481
482 NRF_RADIO->PCNF0 =
483 (((1UL) << RADIO_PCNF0_S0LEN_Pos) & RADIO_PCNF0_S0LEN_Msk) |
484 ((((uint32_t)bits_len) << RADIO_PCNF0_LFLEN_Pos) & RADIO_PCNF0_LFLEN_Msk) |
485 ((((uint32_t)bits_s1) << RADIO_PCNF0_S1LEN_Pos) & RADIO_PCNF0_S1LEN_Msk) | extra;
486
487 NRF_RADIO->PCNF1 &= ~(RADIO_PCNF1_MAXLEN_Msk | RADIO_PCNF1_STATLEN_Msk |
488 RADIO_PCNF1_BALEN_Msk | RADIO_PCNF1_ENDIAN_Msk);
489 NRF_RADIO->PCNF1 |=
490 ((((uint32_t)max_len) << RADIO_PCNF1_MAXLEN_Pos) & RADIO_PCNF1_MAXLEN_Msk) |
491 (((0UL) << RADIO_PCNF1_STATLEN_Pos) & RADIO_PCNF1_STATLEN_Msk) |
492 (((3UL) << RADIO_PCNF1_BALEN_Pos) & RADIO_PCNF1_BALEN_Msk) |
493 (((RADIO_PCNF1_ENDIAN_Little) << RADIO_PCNF1_ENDIAN_Pos) & RADIO_PCNF1_ENDIAN_Msk);
494 }
495
radio_pkt_rx_set(void * rx_packet)496 void radio_pkt_rx_set(void *rx_packet)
497 {
498 NRF_RADIO->PACKETPTR = (uint32_t)rx_packet;
499 }
500
radio_pkt_tx_set(void * tx_packet)501 void radio_pkt_tx_set(void *tx_packet)
502 {
503 NRF_RADIO->PACKETPTR = (uint32_t)tx_packet;
504 }
505
radio_tx_ready_delay_get(uint8_t phy,uint8_t flags)506 uint32_t radio_tx_ready_delay_get(uint8_t phy, uint8_t flags)
507 {
508 return hal_radio_tx_ready_delay_us_get(phy, flags);
509 }
510
radio_tx_chain_delay_get(uint8_t phy,uint8_t flags)511 uint32_t radio_tx_chain_delay_get(uint8_t phy, uint8_t flags)
512 {
513 return hal_radio_tx_chain_delay_us_get(phy, flags);
514 }
515
radio_rx_ready_delay_get(uint8_t phy,uint8_t flags)516 uint32_t radio_rx_ready_delay_get(uint8_t phy, uint8_t flags)
517 {
518 return hal_radio_rx_ready_delay_us_get(phy, flags);
519 }
520
radio_rx_chain_delay_get(uint8_t phy,uint8_t flags)521 uint32_t radio_rx_chain_delay_get(uint8_t phy, uint8_t flags)
522 {
523 return hal_radio_rx_chain_delay_us_get(phy, flags);
524 }
525
radio_rx_enable(void)526 void radio_rx_enable(void)
527 {
528 #if !defined(CONFIG_BT_CTLR_TIFS_HW)
529 #if defined(CONFIG_SOC_COMPATIBLE_NRF53X) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
530 /* NOTE: Timer clear DPPI configuration is needed only for nRF53
531 * because of calls to radio_disable() and
532 * radio_switch_complete_and_disable() inside a radio event call
533 * hal_radio_sw_switch_disable(), which in the case of nRF53
534 * cancels the task subscription.
535 */
536 /* FIXME: hal_sw_switch_timer_clear_ppi_config() sets both task and
537 * event. Consider a new interface to only set the task, or
538 * change the design to not clear task subscription inside a
539 * radio event but when the radio event is done.
540 */
541 hal_sw_switch_timer_clear_ppi_config();
542 #endif /* CONFIG_SOC_COMPATIBLE_NRF53X || CONFIG_SOC_COMPATIBLE_NRF54LX */
543 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
544
545 nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_RXEN);
546 }
547
radio_tx_enable(void)548 void radio_tx_enable(void)
549 {
550 #if !defined(CONFIG_BT_CTLR_TIFS_HW)
551 #if defined(CONFIG_SOC_COMPATIBLE_NRF53X) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
552 /* NOTE: Timer clear DPPI configuration is needed only for nRF53
553 * because of calls to radio_disable() and
554 * radio_switch_complete_and_disable() inside a radio event call
555 * hal_radio_sw_switch_disable(), which in the case of nRF53
556 * cancels the task subscription.
557 */
558 /* FIXME: hal_sw_switch_timer_clear_ppi_config() sets both task and
559 * event. Consider a new interface to only set the task, or
560 * change the design to not clear task subscription inside a
561 * radio event but when the radio event is done.
562 */
563 hal_sw_switch_timer_clear_ppi_config();
564 #endif /* CONFIG_SOC_COMPATIBLE_NRF53X || CONFIG_SOC_COMPATIBLE_NRF54LX */
565 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
566
567 nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_TXEN);
568 }
569
radio_disable(void)570 void radio_disable(void)
571 {
572 #if !defined(CONFIG_BT_CTLR_TIFS_HW)
573 hal_radio_sw_switch_cleanup();
574 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
575
576 NRF_RADIO->SHORTS = 0;
577 nrf_radio_task_trigger(NRF_RADIO, NRF_RADIO_TASK_DISABLE);
578 }
579
radio_status_reset(void)580 void radio_status_reset(void)
581 {
582 /* NOTE: Only EVENTS_* registers read (checked) by software needs reset
583 * between Radio IRQs. In PPI use, irrespective of stored EVENT_*
584 * register value, PPI task will be triggered. Hence, other
585 * EVENT_* registers are not reset to save code and CPU time.
586 */
587 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_READY);
588 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_ADDRESS);
589 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_END);
590 #if defined(CONFIG_BT_CTLR_DF_SUPPORT) && !defined(CONFIG_ZTEST)
591 /* Clear it only for SoCs supporting DF extension */
592 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_PHYEND);
593 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_CTEPRESENT);
594 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_BCMATCH);
595 #endif /* CONFIG_BT_CTLR_DF_SUPPORT && !CONFIG_ZTEST */
596 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_DISABLED);
597 #if defined(CONFIG_BT_CTLR_PHY_CODED)
598 #if defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED)
599 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_RATEBOOST);
600 #endif /* CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */
601 #endif /* CONFIG_BT_CTLR_PHY_CODED */
602 }
603
radio_is_ready(void)604 uint32_t radio_is_ready(void)
605 {
606 return (NRF_RADIO->EVENTS_READY != 0);
607 }
608
radio_is_address(void)609 uint32_t radio_is_address(void)
610 {
611 return (NRF_RADIO->EVENTS_ADDRESS != 0);
612 }
613
614 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
615 static uint32_t last_pdu_end_latency_us;
616 static uint32_t last_pdu_end_us;
617
last_pdu_end_us_init(uint32_t latency_us)618 static void last_pdu_end_us_init(uint32_t latency_us)
619 {
620 last_pdu_end_latency_us = latency_us;
621 last_pdu_end_us = 0U;
622 }
623
radio_is_done(void)624 uint32_t radio_is_done(void)
625 {
626 if (NRF_RADIO->HAL_RADIO_TRX_EVENTS_END != 0) {
627 /* On packet END event increment last packet end time value.
628 * Note: this depends on the function being called exactly once
629 * in the ISR function.
630 */
631 last_pdu_end_us += EVENT_TIMER->CC[HAL_EVENT_TIMER_TRX_END_CC_OFFSET];
632 return 1;
633 } else {
634 return 0;
635 }
636 }
637
638 #else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
radio_is_done(void)639 uint32_t radio_is_done(void)
640 {
641 return (NRF_RADIO->HAL_RADIO_TRX_EVENTS_END != 0);
642 }
643 #endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
644
radio_is_tx_done(void)645 uint32_t radio_is_tx_done(void)
646 {
647 if (IS_ENABLED(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)) {
648 return radio_is_done();
649 } else {
650 return 1U;
651 }
652 }
653
radio_has_disabled(void)654 uint32_t radio_has_disabled(void)
655 {
656 return (NRF_RADIO->EVENTS_DISABLED != 0);
657 }
658
radio_is_idle(void)659 uint32_t radio_is_idle(void)
660 {
661 return (NRF_RADIO->STATE == 0);
662 }
663
radio_crc_configure(uint32_t polynomial,uint32_t iv)664 void radio_crc_configure(uint32_t polynomial, uint32_t iv)
665 {
666 nrf_radio_crc_configure(NRF_RADIO,
667 RADIO_CRCCNF_LEN_Three,
668 NRF_RADIO_CRC_ADDR_SKIP,
669 polynomial);
670 NRF_RADIO->CRCINIT = iv;
671 }
672
radio_crc_is_valid(void)673 uint32_t radio_crc_is_valid(void)
674 {
675 return (NRF_RADIO->CRCSTATUS != 0);
676 }
677
678 /* Note: Only 3 bytes (PDU_EM_LL_SIZE_MAX) is required for empty PDU
679 * transmission, but in case of Radio ISR latency if rx packet pointer
680 * is not setup then Radio DMA will use previously assigned buffer which
681 * can be this empty PDU buffer. Radio DMA will overrun this buffer and
682 * cause memory corruption. Any detection of ISR latency will not happen
683 * if the ISR function pointer in RAM is corrupted by this overrun.
684 * Increasing ISR latencies in OS and CPU usage in the ULL_HIGH priority
685 * if it is same as LLL priority in Controller implementation then it is
686 * making it tight to execute Controller code in the tIFS between Tx-Rx
687 * PDU's Radio ISRs.
688 */
689 static uint8_t MALIGN(4) _pkt_empty[MAX(HAL_RADIO_PDU_LEN_MAX,
690 PDU_EM_LL_SIZE_MAX)];
691 static uint8_t MALIGN(4) _pkt_scratch[MAX((HAL_RADIO_PDU_LEN_MAX + 3),
692 PDU_AC_LL_SIZE_MAX)];
693
radio_pkt_empty_get(void)694 void *radio_pkt_empty_get(void)
695 {
696 return _pkt_empty;
697 }
698
radio_pkt_scratch_get(void)699 void *radio_pkt_scratch_get(void)
700 {
701 return _pkt_scratch;
702 }
703
704 #if defined(CONFIG_SOC_NRF52832) && \
705 defined(CONFIG_BT_CTLR_LE_ENC) && \
706 defined(HAL_RADIO_PDU_LEN_MAX) && \
707 (!defined(CONFIG_BT_CTLR_DATA_LENGTH_MAX) || \
708 (CONFIG_BT_CTLR_DATA_LENGTH_MAX < (HAL_RADIO_PDU_LEN_MAX - 4)))
709 static uint8_t MALIGN(4) _pkt_decrypt[MAX((HAL_RADIO_PDU_LEN_MAX + 3),
710 PDU_AC_LL_SIZE_MAX)];
711
radio_pkt_decrypt_get(void)712 void *radio_pkt_decrypt_get(void)
713 {
714 return _pkt_decrypt;
715 }
716 #elif !defined(HAL_RADIO_PDU_LEN_MAX)
717 #error "Undefined HAL_RADIO_PDU_LEN_MAX."
718 #endif
719
720 #if defined(CONFIG_BT_CTLR_ADV_ISO) || defined(CONFIG_BT_CTLR_SYNC_ISO)
721 /* Dedicated Rx PDU Buffer for Control PDU independent of node_rx with BIS Data
722 * PDU buffer. Note this buffer will be used to store whole PDUs, not just the BIG control payload.
723 */
724 static uint8_t pkt_big_ctrl[offsetof(struct pdu_bis, payload) + sizeof(struct pdu_big_ctrl)];
725
radio_pkt_big_ctrl_get(void)726 void *radio_pkt_big_ctrl_get(void)
727 {
728 return pkt_big_ctrl;
729 }
730 #endif /* CONFIG_BT_CTLR_ADV_ISO || CONFIG_BT_CTLR_SYNC_ISO */
731
732 #if !defined(CONFIG_BT_CTLR_TIFS_HW)
733 static uint8_t sw_tifs_toggle;
734 /**
735 * @brief Implementation of Radio operation software switch.
736 *
737 * In case the switch is from RX to TX or from RX to RX and CTEINLINE is enabled then PDU end event
738 * (EVENTS_PHYEND) may be delayed after actual PDU end. The delay occurs when received PDU does not
739 * include CTE. To maintain TIFS the delay must be compensated.
740 * To handle that, two timer EVENTS_COMPARE are prepared: without and without delay compensation.
741 * If EVENTS_CTEPRESENT is fired then EVENTS_COMPARE for delayed EVENTS_PHYEND event is cancelled.
742 * In other case EVENTS_COMPARE for delayed compensation will timeout first and disable group of
743 * PPIs related with the Radio operation switch.
744 * Enable of end event compensation is controller by @p end_evt_delay_en.
745 *
746 * @param dir_curr Current direction the Radio is working: SW_SWITCH_TX or SW_SWITCH_RX
747 * @param dir_next Next direction the Radio is preparing for: SW_SWITCH_TX or SW_SWITCH_RX
748 * @param phy_curr PHY the Radio is working on.
749 * @param flags_curr Flags related with current PHY, the Radio is working on.
750 * @param phy_next Next PHY the Radio is preparing for.
751 * @param flags_next Flags related with next PHY, the Radio is preparing for.
752 * @param end_evt_delay_en Enable end event delay compensation for TIFS after switch from current
753 * direction to next direction.
754 */
sw_switch(uint8_t dir_curr,uint8_t dir_next,uint8_t phy_curr,uint8_t flags_curr,uint8_t phy_next,uint8_t flags_next,enum radio_end_evt_delay_state end_evt_delay_en)755 void sw_switch(uint8_t dir_curr, uint8_t dir_next, uint8_t phy_curr, uint8_t flags_curr,
756 uint8_t phy_next, uint8_t flags_next,
757 enum radio_end_evt_delay_state end_evt_delay_en)
758 {
759 uint8_t ppi = HAL_SW_SWITCH_RADIO_ENABLE_PPI(sw_tifs_toggle);
760 uint8_t cc = SW_SWITCH_TIMER_EVTS_COMP(sw_tifs_toggle);
761 #if defined(CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE)
762 uint8_t phyend_delay_cc =
763 SW_SWITCH_TIMER_PHYEND_DELAY_COMPENSATION_EVTS_COMP(sw_tifs_toggle);
764 uint8_t radio_enable_ppi =
765 HAL_SW_SWITCH_RADIO_ENABLE_PHYEND_DELAY_COMPENSATION_PPI(sw_tifs_toggle);
766 #endif /* CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE */
767 uint32_t delay;
768
769 hal_radio_sw_switch_setup(sw_tifs_toggle);
770
771 /* NOTE: As constants are passed to dir_curr and dir_next, the
772 * compiler should optimize out the redundant code path
773 * during the optimization.
774 */
775 if (dir_next == SW_SWITCH_TX) {
776 /* TX */
777
778 /* Calculate delay with respect to current and next PHY.
779 */
780 if (dir_curr == SW_SWITCH_TX) {
781 delay = HAL_RADIO_NS2US_ROUND(
782 hal_radio_tx_ready_delay_ns_get(phy_next,
783 flags_next) +
784 hal_radio_tx_chain_delay_ns_get(phy_curr,
785 flags_curr));
786
787 hal_radio_b2b_txen_on_sw_switch(cc, ppi);
788 } else {
789 /* If RX PHY is LE Coded, calculate for S8 coding.
790 * Assumption being, S8 has higher delay.
791 */
792 delay = HAL_RADIO_NS2US_ROUND(
793 hal_radio_tx_ready_delay_ns_get(phy_next,
794 flags_next) +
795 hal_radio_rx_chain_delay_ns_get(phy_curr, 1));
796
797 hal_radio_txen_on_sw_switch(cc, ppi);
798 }
799
800 #if defined(CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE)
801 if (dir_curr == SW_SWITCH_RX && end_evt_delay_en == END_EVT_DELAY_ENABLED &&
802 !(phy_curr & PHY_CODED)) {
803 nrf_timer_cc_set(SW_SWITCH_TIMER, phyend_delay_cc,
804 SW_SWITCH_TIMER->CC[cc] - RADIO_EVENTS_PHYEND_DELAY_US);
805 if (delay < SW_SWITCH_TIMER->CC[cc]) {
806 nrf_timer_cc_set(SW_SWITCH_TIMER, phyend_delay_cc,
807 (SW_SWITCH_TIMER->CC[phyend_delay_cc] - delay));
808 } else {
809 nrf_timer_cc_set(SW_SWITCH_TIMER, phyend_delay_cc, 1);
810 }
811
812 hal_radio_sw_switch_phyend_delay_compensation_config_set(radio_enable_ppi,
813 phyend_delay_cc);
814 } else {
815 hal_radio_sw_switch_phyend_delay_compensation_config_clear(radio_enable_ppi,
816 phyend_delay_cc);
817 }
818 #endif /* CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE */
819
820 #if defined(CONFIG_BT_CTLR_PHY_CODED)
821 #if defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED)
822 uint8_t ppi_en = HAL_SW_SWITCH_RADIO_ENABLE_S2_PPI(sw_tifs_toggle);
823 uint8_t ppi_dis = HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(sw_tifs_toggle);
824 uint8_t cc_s2 = SW_SWITCH_TIMER_S2_EVTS_COMP(sw_tifs_toggle);
825
826 if (dir_curr == SW_SWITCH_RX && (phy_curr & PHY_CODED)) {
827 /* Switching to TX after RX on LE Coded PHY. */
828 uint32_t delay_s2;
829 uint32_t new_cc_s2_value;
830
831 /* Calculate assuming reception on S2 coding scheme. */
832 delay_s2 = HAL_RADIO_NS2US_ROUND(
833 hal_radio_tx_ready_delay_ns_get(phy_next,
834 flags_next) +
835 hal_radio_rx_chain_delay_ns_get(phy_curr, 0));
836
837 new_cc_s2_value = SW_SWITCH_TIMER->CC[cc];
838
839 if (delay_s2 < new_cc_s2_value) {
840 new_cc_s2_value -= delay_s2;
841 } else {
842 new_cc_s2_value = 1;
843 }
844 nrf_timer_cc_set(SW_SWITCH_TIMER, cc_s2,
845 new_cc_s2_value);
846
847 /* Setup the Tx start for S2 using a dedicated compare,
848 * setup a PPI to disable PPI group on that compare
849 * event, and then importantly setup a capture PPI to
850 * disable the Tx start for S8 on RATEBOOST event.
851 */
852 hal_radio_sw_switch_coded_tx_config_set(ppi_en, ppi_dis,
853 cc_s2, sw_tifs_toggle);
854
855 } else {
856 /* Switching to TX after RX on LE 1M/2M PHY.
857 *
858 * NOTE: PHYEND delay compensation and switching between Coded S2 and S8 PHY
859 * may not happen at once. PHYEND delay may not happen when Code PHY
860 * is used. Both functionalities use the same EVENTS_COMPARE channels,
861 * hence when PHYEND delay is applied, coded config clear may not be
862 * called.
863 *
864 * TODO: This has to be refactored. It is temporarily implemented this way
865 * because the code is very fragile and hard to debug.
866 */
867 if (end_evt_delay_en != END_EVT_DELAY_ENABLED) {
868 hal_radio_sw_switch_coded_config_clear(ppi_en, ppi_dis, cc_s2,
869 sw_tifs_toggle);
870 }
871
872 hal_radio_sw_switch_disable_group_clear(ppi_dis, cc, sw_tifs_toggle);
873 }
874 #endif /* CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */
875 #endif /* CONFIG_BT_CTLR_PHY_CODED */
876 } else {
877 /* RX */
878
879 /* Calculate delay with respect to current and next PHY. */
880 if (dir_curr) {
881 delay = HAL_RADIO_NS2US_CEIL(
882 hal_radio_rx_ready_delay_ns_get(phy_next,
883 flags_next) +
884 hal_radio_tx_chain_delay_ns_get(phy_curr,
885 flags_curr)) +
886 (EVENT_CLOCK_JITTER_US << 1);
887
888 hal_radio_rxen_on_sw_switch(cc, ppi);
889 } else {
890 delay = HAL_RADIO_NS2US_CEIL(
891 hal_radio_rx_ready_delay_ns_get(phy_next,
892 flags_next) +
893 hal_radio_rx_chain_delay_ns_get(phy_curr,
894 flags_curr)) +
895 (EVENT_CLOCK_JITTER_US << 1);
896
897 hal_radio_b2b_rxen_on_sw_switch(cc, ppi);
898 }
899
900
901 #if defined(CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE)
902 hal_radio_sw_switch_phyend_delay_compensation_config_clear(radio_enable_ppi,
903 phyend_delay_cc);
904 #endif /* CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE */
905
906 #if defined(CONFIG_BT_CTLR_PHY_CODED)
907 #if defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED)
908 if (1) {
909 uint8_t ppi_en = HAL_SW_SWITCH_RADIO_ENABLE_S2_PPI(sw_tifs_toggle);
910 uint8_t ppi_dis = HAL_SW_SWITCH_GROUP_TASK_DISABLE_PPI(sw_tifs_toggle);
911 uint8_t cc_s2 = SW_SWITCH_TIMER_S2_EVTS_COMP(sw_tifs_toggle);
912
913 hal_radio_sw_switch_coded_config_clear(ppi_en, ppi_dis, cc_s2,
914 sw_tifs_toggle);
915 hal_radio_sw_switch_disable_group_clear(ppi_dis, cc, sw_tifs_toggle);
916 }
917 #endif /* CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */
918 #endif /* CONFIG_BT_CTLR_PHY_CODED */
919 }
920
921 if (delay < SW_SWITCH_TIMER->CC[cc]) {
922 nrf_timer_cc_set(SW_SWITCH_TIMER,
923 cc,
924 (SW_SWITCH_TIMER->CC[cc] - delay));
925 } else {
926 nrf_timer_cc_set(SW_SWITCH_TIMER, cc, 1);
927 }
928
929 hal_radio_nrf_ppi_channels_enable(BIT(HAL_SW_SWITCH_TIMER_CLEAR_PPI) |
930 BIT(HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI));
931
932 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
933 /* NOTE: For single timer configuration nRF5340 shares the DPPI channel being
934 * triggered by Radio End for End time capture and sw_switch DPPI channel toggling
935 * hence always need to capture End time. Or when using single event timer since
936 * the timer is cleared on Radio End, we always need to capture the Radio End
937 * time-stamp.
938 */
939 hal_radio_end_time_capture_ppi_config();
940 #if !defined(CONFIG_SOC_COMPATIBLE_NRF53X) && !defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
941 /* The function is not called for nRF5340 single timer configuration because
942 * HAL_SW_SWITCH_TIMER_CLEAR_PPI is equal to HAL_RADIO_END_TIME_CAPTURE_PPI,
943 * so channel is already enabled.
944 */
945 hal_radio_nrf_ppi_channels_enable(BIT(HAL_RADIO_END_TIME_CAPTURE_PPI));
946 #endif /* !CONFIG_SOC_COMPATIBLE_NRF53X && !CONFIG_SOC_COMPATIBLE_NRF54LX */
947 #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
948
949 sw_tifs_toggle += 1U;
950 sw_tifs_toggle &= 1U;
951 }
952 #endif /* CONFIG_BT_CTLR_TIFS_HW */
953
radio_switch_complete_and_rx(uint8_t phy_rx)954 void radio_switch_complete_and_rx(uint8_t phy_rx)
955 {
956 #if defined(CONFIG_BT_CTLR_TIFS_HW)
957 NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk |
958 NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk |
959 RADIO_SHORTS_DISABLED_RXEN_Msk;
960 #else /* !CONFIG_BT_CTLR_TIFS_HW */
961 NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk;
962
963 /* NOTE: As Tx chain delays are negligible constant values (~1 us)
964 * across nRF5x radios, sw_switch assumes the 1M chain delay for
965 * calculations.
966 */
967 sw_switch(SW_SWITCH_TX, SW_SWITCH_RX, SW_SWITCH_PHY_1M, SW_SWITCH_FLAGS_DONTCARE, phy_rx,
968 SW_SWITCH_FLAGS_DONTCARE, END_EVT_DELAY_DISABLED);
969 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
970 }
971
radio_switch_complete_and_tx(uint8_t phy_rx,uint8_t flags_rx,uint8_t phy_tx,uint8_t flags_tx)972 void radio_switch_complete_and_tx(uint8_t phy_rx, uint8_t flags_rx,
973 uint8_t phy_tx, uint8_t flags_tx)
974 {
975 #if defined(CONFIG_BT_CTLR_TIFS_HW)
976 NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk |
977 NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk |
978 RADIO_SHORTS_DISABLED_TXEN_Msk;
979 #else /* !CONFIG_BT_CTLR_TIFS_HW */
980 NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk;
981
982 sw_switch(SW_SWITCH_RX, SW_SWITCH_TX, phy_rx, flags_rx, phy_tx, flags_tx,
983 END_EVT_DELAY_DISABLED);
984 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
985 }
986
radio_switch_complete_with_delay_compensation_and_tx(uint8_t phy_rx,uint8_t flags_rx,uint8_t phy_tx,uint8_t flags_tx,enum radio_end_evt_delay_state end_delay_en)987 void radio_switch_complete_with_delay_compensation_and_tx(
988 uint8_t phy_rx, uint8_t flags_rx, uint8_t phy_tx, uint8_t flags_tx,
989 enum radio_end_evt_delay_state end_delay_en)
990 {
991 #if defined(CONFIG_BT_CTLR_TIFS_HW)
992 NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk |
993 RADIO_SHORTS_DISABLED_TXEN_Msk;
994 #else /* !CONFIG_BT_CTLR_TIFS_HW */
995 NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk;
996
997 sw_switch(SW_SWITCH_RX, SW_SWITCH_TX, phy_rx, flags_rx, phy_tx, flags_tx, end_delay_en);
998 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
999 }
1000
radio_switch_complete_and_b2b_tx(uint8_t phy_curr,uint8_t flags_curr,uint8_t phy_next,uint8_t flags_next)1001 void radio_switch_complete_and_b2b_tx(uint8_t phy_curr, uint8_t flags_curr,
1002 uint8_t phy_next, uint8_t flags_next)
1003 {
1004 #if defined(CONFIG_BT_CTLR_TIFS_HW)
1005 NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk |
1006 NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk |
1007 RADIO_SHORTS_DISABLED_TXEN_Msk;
1008 #else /* !CONFIG_BT_CTLR_TIFS_HW */
1009 NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk;
1010
1011 sw_switch(SW_SWITCH_TX, SW_SWITCH_TX, phy_curr, flags_curr, phy_next, flags_next,
1012 END_EVT_DELAY_DISABLED);
1013 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1014 }
1015
radio_switch_complete_and_b2b_rx(uint8_t phy_curr,uint8_t flags_curr,uint8_t phy_next,uint8_t flags_next)1016 void radio_switch_complete_and_b2b_rx(uint8_t phy_curr, uint8_t flags_curr,
1017 uint8_t phy_next, uint8_t flags_next)
1018 {
1019 #if defined(CONFIG_BT_CTLR_TIFS_HW)
1020 NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk |
1021 NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk |
1022 RADIO_SHORTS_DISABLED_RXEN_Msk;
1023 #else /* !CONFIG_BT_CTLR_TIFS_HW */
1024 NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk;
1025
1026 sw_switch(SW_SWITCH_RX, SW_SWITCH_RX, phy_curr, flags_curr, phy_next, flags_next,
1027 END_EVT_DELAY_DISABLED);
1028 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1029 }
1030
radio_switch_complete_and_b2b_tx_disable(void)1031 void radio_switch_complete_and_b2b_tx_disable(void)
1032 {
1033 #if defined(CONFIG_BT_CTLR_TIFS_HW)
1034 NRF_RADIO->SHORTS = (RADIO_SHORTS_READY_START_Msk | NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk);
1035 #else /* CONFIG_BT_CTLR_TIFS_HW */
1036 NRF_RADIO->SHORTS = (RADIO_SHORTS_READY_START_Msk | NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk);
1037 hal_radio_sw_switch_b2b_tx_disable(sw_tifs_toggle);
1038 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1039 }
1040
radio_switch_complete_and_b2b_rx_disable(void)1041 void radio_switch_complete_and_b2b_rx_disable(void)
1042 {
1043 #if defined(CONFIG_BT_CTLR_TIFS_HW)
1044 NRF_RADIO->SHORTS = (RADIO_SHORTS_READY_START_Msk | NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk);
1045 #else /* CONFIG_BT_CTLR_TIFS_HW */
1046 NRF_RADIO->SHORTS = (RADIO_SHORTS_READY_START_Msk | NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk);
1047 hal_radio_sw_switch_b2b_rx_disable(sw_tifs_toggle);
1048 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1049 }
1050
radio_switch_complete_and_disable(void)1051 void radio_switch_complete_and_disable(void)
1052 {
1053 #if defined(CONFIG_BT_CTLR_TIFS_HW)
1054 NRF_RADIO->SHORTS = (RADIO_SHORTS_READY_START_Msk | NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk);
1055 #else /* CONFIG_BT_CTLR_TIFS_HW */
1056 NRF_RADIO->SHORTS = (RADIO_SHORTS_READY_START_Msk | NRF_RADIO_SHORTS_TRX_END_DISABLE_Msk);
1057 hal_radio_sw_switch_disable();
1058 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1059 }
1060
radio_phy_flags_rx_get(void)1061 uint8_t radio_phy_flags_rx_get(void)
1062 {
1063 #if defined(CONFIG_BT_CTLR_PHY_CODED)
1064 #if defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED)
1065 return (NRF_RADIO->EVENTS_RATEBOOST) ? 0U : 1U;
1066 #else /* !CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */
1067 return 0;
1068 #endif /* !CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */
1069 #else /* !CONFIG_BT_CTLR_PHY_CODED */
1070 return 0;
1071 #endif /* !CONFIG_BT_CTLR_PHY_CODED */
1072 }
1073
radio_rssi_measure(void)1074 void radio_rssi_measure(void)
1075 {
1076 NRF_RADIO->SHORTS |=
1077 (RADIO_SHORTS_ADDRESS_RSSISTART_Msk |
1078 #if defined(CONFIG_SOC_SERIES_NRF51X) || \
1079 defined(CONFIG_SOC_COMPATIBLE_NRF52X) || \
1080 defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET)
1081 RADIO_SHORTS_DISABLED_RSSISTOP_Msk |
1082 #endif
1083 0);
1084 }
1085
radio_rssi_get(void)1086 uint32_t radio_rssi_get(void)
1087 {
1088 return NRF_RADIO->RSSISAMPLE;
1089 }
1090
radio_rssi_status_reset(void)1091 void radio_rssi_status_reset(void)
1092 {
1093 #if defined(CONFIG_SOC_SERIES_NRF51X) || \
1094 defined(CONFIG_SOC_COMPATIBLE_NRF52X) || \
1095 defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET)
1096 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_RSSIEND);
1097 #endif
1098 }
1099
radio_rssi_is_ready(void)1100 uint32_t radio_rssi_is_ready(void)
1101 {
1102 #if defined(CONFIG_SOC_SERIES_NRF51X) || \
1103 defined(CONFIG_SOC_COMPATIBLE_NRF52X) || \
1104 defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET)
1105 return (NRF_RADIO->EVENTS_RSSIEND != 0);
1106 #else
1107 return 1U;
1108 #endif
1109 }
1110
radio_filter_configure(uint8_t bitmask_enable,uint8_t bitmask_addr_type,uint8_t * bdaddr)1111 void radio_filter_configure(uint8_t bitmask_enable, uint8_t bitmask_addr_type,
1112 uint8_t *bdaddr)
1113 {
1114 uint8_t index;
1115
1116 for (index = 0U; index < 8; index++) {
1117 NRF_RADIO->DAB[index] = ((uint32_t)bdaddr[3] << 24) |
1118 ((uint32_t)bdaddr[2] << 16) |
1119 ((uint32_t)bdaddr[1] << 8) |
1120 bdaddr[0];
1121 NRF_RADIO->DAP[index] = ((uint32_t)bdaddr[5] << 8) | bdaddr[4];
1122 bdaddr += 6;
1123 }
1124
1125 NRF_RADIO->DACNF = ((uint32_t)bitmask_addr_type << 8) | bitmask_enable;
1126 }
1127
radio_filter_disable(void)1128 void radio_filter_disable(void)
1129 {
1130 NRF_RADIO->DACNF &= ~(0x000000FF);
1131 }
1132
radio_filter_status_reset(void)1133 void radio_filter_status_reset(void)
1134 {
1135 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_DEVMATCH);
1136 }
1137
radio_filter_has_match(void)1138 uint32_t radio_filter_has_match(void)
1139 {
1140 return (NRF_RADIO->EVENTS_DEVMATCH != 0);
1141 }
1142
radio_filter_match_get(void)1143 uint32_t radio_filter_match_get(void)
1144 {
1145 return NRF_RADIO->DAI;
1146 }
1147
radio_bc_configure(uint32_t n)1148 void radio_bc_configure(uint32_t n)
1149 {
1150 NRF_RADIO->BCC = n;
1151 NRF_RADIO->SHORTS |= RADIO_SHORTS_ADDRESS_BCSTART_Msk;
1152 }
1153
radio_bc_status_reset(void)1154 void radio_bc_status_reset(void)
1155 {
1156 nrf_radio_event_clear(NRF_RADIO, NRF_RADIO_EVENT_BCMATCH);
1157 }
1158
radio_bc_has_match(void)1159 uint32_t radio_bc_has_match(void)
1160 {
1161 return (NRF_RADIO->EVENTS_BCMATCH != 0);
1162 }
1163
1164 #if defined(CONFIG_BT_CTLR_RADIO_TIMER_ISR)
1165 static radio_isr_cb_t isr_radio_tmr_cb;
1166 static void *isr_radio_tmr_cb_param;
1167
isr_radio_tmr(void)1168 void isr_radio_tmr(void)
1169 {
1170 irq_disable(TIMER0_IRQn);
1171 nrf_timer_int_disable(EVENT_TIMER, TIMER_INTENSET_COMPARE2_Msk);
1172 nrf_timer_event_clear(EVENT_TIMER, HAL_EVENT_TIMER_DEFERRED_TX_EVENT);
1173
1174 isr_radio_tmr_cb(isr_radio_tmr_cb_param);
1175 }
1176
radio_tmr_isr_set(uint32_t start_us,radio_isr_cb_t cb,void * param)1177 uint32_t radio_tmr_isr_set(uint32_t start_us, radio_isr_cb_t cb, void *param)
1178 {
1179 irq_disable(TIMER0_IRQn);
1180
1181 isr_radio_tmr_cb_param = param;
1182 isr_radio_tmr_cb = cb;
1183
1184 /* start_us could be the current count in the timer */
1185 uint32_t now_us = start_us;
1186
1187 /* Setup timer compare while determining the latency in doing so */
1188 do {
1189 /* Set start to be, now plus the determined latency */
1190 start_us = (now_us << 1) - start_us;
1191
1192 /* Setup compare event with min. 1 us offset */
1193 nrf_timer_event_clear(EVENT_TIMER, HAL_EVENT_TIMER_DEFERRED_TX_EVENT);
1194 nrf_timer_cc_set(EVENT_TIMER, HAL_EVENT_TIMER_DEFERRED_TRX_CC_OFFSET,
1195 start_us + 1U);
1196
1197 /* Capture the current time */
1198 nrf_timer_task_trigger(EVENT_TIMER, HAL_EVENT_TIMER_SAMPLE_TASK);
1199
1200 now_us = EVENT_TIMER->CC[HAL_EVENT_TIMER_SAMPLE_CC_OFFSET];
1201 } while ((now_us > start_us) &&
1202 (EVENT_TIMER->EVENTS_COMPARE[HAL_EVENT_TIMER_DEFERRED_TRX_CC_OFFSET] == 0U));
1203
1204 nrf_timer_int_enable(EVENT_TIMER, TIMER_INTENSET_COMPARE2_Msk);
1205
1206 NVIC_ClearPendingIRQ(TIMER0_IRQn);
1207
1208 irq_enable(TIMER0_IRQn);
1209
1210 return start_us + 1U;
1211 }
1212 #endif /* CONFIG_BT_CTLR_RADIO_TIMER_ISR */
1213
radio_tmr_status_reset(void)1214 void radio_tmr_status_reset(void)
1215 {
1216 #if defined(CONFIG_BT_CTLR_NRF_GRTC)
1217 nrf_grtc_sys_counter_compare_event_disable(NRF_GRTC, HAL_CNTR_GRTC_CC_IDX_RADIO);
1218 #else /* !CONFIG_BT_CTLR_NRF_GRTC */
1219 nrf_rtc_event_disable(NRF_RTC, RTC_EVTENCLR_COMPARE2_Msk);
1220 #endif /* !CONFIG_BT_CTLR_NRF_GRTC */
1221
1222 #if defined(CONFIG_BT_CTLR_LE_ENC) || defined(CONFIG_BT_CTLR_BROADCAST_ISO_ENC)
1223 hal_trigger_crypt_ppi_disable();
1224 #endif /* CONFIG_BT_CTLR_LE_ENC || CONFIG_BT_CTLR_BROADCAST_ISO_ENC */
1225
1226 hal_radio_nrf_ppi_channels_disable(
1227 BIT(HAL_RADIO_ENABLE_TX_ON_TICK_PPI) |
1228 BIT(HAL_RADIO_ENABLE_RX_ON_TICK_PPI) |
1229 BIT(HAL_EVENT_TIMER_START_PPI) |
1230 BIT(HAL_RADIO_READY_TIME_CAPTURE_PPI) |
1231 BIT(HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI) |
1232 BIT(HAL_RADIO_DISABLE_ON_HCTO_PPI) |
1233 BIT(HAL_RADIO_END_TIME_CAPTURE_PPI) |
1234 #if !defined(CONFIG_BT_CTLR_TIFS_HW)
1235 BIT(HAL_SW_SWITCH_TIMER_CLEAR_PPI) |
1236 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1237 #if defined(CONFIG_BT_CTLR_PHY_CODED)
1238 #if defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED)
1239 BIT(HAL_TRIGGER_RATEOVERRIDE_PPI) |
1240 #if !defined(CONFIG_BT_CTLR_TIFS_HW)
1241 BIT(HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI) |
1242 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1243 #endif /* CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */
1244 #endif /* CONFIG_BT_CTLR_PHY_CODED */
1245 #if defined(CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE)
1246 BIT(HAL_SW_SWITCH_TIMER_PHYEND_DELAY_COMPENSATION_DISABLE_PPI) |
1247 #endif /* CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE */
1248 #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RX)
1249 BIT(HAL_TRIGGER_CRYPT_DELAY_PPI) |
1250 #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RX */
1251 #if defined(CONFIG_BT_CTLR_LE_ENC) || defined(CONFIG_BT_CTLR_BROADCAST_ISO_ENC)
1252 BIT(HAL_TRIGGER_CRYPT_PPI) |
1253 #endif /* CONFIG_BT_CTLR_LE_ENC || CONFIG_BT_CTLR_BROADCAST_ISO_ENC */
1254 0);
1255 }
1256
radio_tmr_tx_status_reset(void)1257 void radio_tmr_tx_status_reset(void)
1258 {
1259 #if defined(CONFIG_BT_CTLR_NRF_GRTC)
1260 nrf_grtc_sys_counter_compare_event_disable(NRF_GRTC, HAL_CNTR_GRTC_CC_IDX_RADIO);
1261 #else /* !CONFIG_BT_CTLR_NRF_GRTC */
1262 nrf_rtc_event_disable(NRF_RTC, RTC_EVTENCLR_COMPARE2_Msk);
1263 #endif /* !CONFIG_BT_CTLR_NRF_GRTC */
1264
1265 #if defined(CONFIG_BT_CTLR_LE_ENC) || defined(CONFIG_BT_CTLR_BROADCAST_ISO_ENC)
1266 hal_trigger_crypt_ppi_disable();
1267 #endif /* CONFIG_BT_CTLR_LE_ENC || CONFIG_BT_CTLR_BROADCAST_ISO_ENC */
1268
1269 hal_radio_nrf_ppi_channels_disable(
1270 #if (HAL_RADIO_ENABLE_TX_ON_TICK_PPI != HAL_RADIO_ENABLE_RX_ON_TICK_PPI) && \
1271 !defined(DPPI_PRESENT)
1272 BIT(HAL_RADIO_ENABLE_TX_ON_TICK_PPI) |
1273 #endif /* (HAL_RADIO_ENABLE_TX_ON_TICK_PPI !=
1274 * HAL_RADIO_ENABLE_RX_ON_TICK_PPI) && !DPPI_PRESENT
1275 */
1276 BIT(HAL_EVENT_TIMER_START_PPI) |
1277 BIT(HAL_RADIO_READY_TIME_CAPTURE_PPI) |
1278 BIT(HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI) |
1279 BIT(HAL_RADIO_DISABLE_ON_HCTO_PPI) |
1280 BIT(HAL_RADIO_END_TIME_CAPTURE_PPI) |
1281 #if !defined(CONFIG_BT_CTLR_TIFS_HW)
1282 BIT(HAL_SW_SWITCH_TIMER_CLEAR_PPI) |
1283 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1284 #if defined(CONFIG_BT_CTLR_PHY_CODED)
1285 #if defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED)
1286 BIT(HAL_TRIGGER_RATEOVERRIDE_PPI) |
1287 #if !defined(CONFIG_BT_CTLR_TIFS_HW)
1288 BIT(HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI) |
1289 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1290 #endif /* CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */
1291 #endif /* CONFIG_BT_CTLR_PHY_CODED */
1292 #if defined(CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE)
1293 BIT(HAL_SW_SWITCH_TIMER_PHYEND_DELAY_COMPENSATION_DISABLE_PPI) |
1294 #endif /* CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE */
1295 #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RX)
1296 BIT(HAL_TRIGGER_CRYPT_DELAY_PPI) |
1297 #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RX */
1298 #if defined(CONFIG_BT_CTLR_LE_ENC) || defined(CONFIG_BT_CTLR_BROADCAST_ISO_ENC)
1299 BIT(HAL_TRIGGER_CRYPT_PPI) |
1300 #endif /* CONFIG_BT_CTLR_LE_ENC || CONFIG_BT_CTLR_BROADCAST_ISO_ENC */
1301 0);
1302 }
1303
radio_tmr_rx_status_reset(void)1304 void radio_tmr_rx_status_reset(void)
1305 {
1306 #if defined(CONFIG_BT_CTLR_NRF_GRTC)
1307 nrf_grtc_sys_counter_compare_event_disable(NRF_GRTC, HAL_CNTR_GRTC_CC_IDX_RADIO);
1308 #else /* !CONFIG_BT_CTLR_NRF_GRTC */
1309 nrf_rtc_event_disable(NRF_RTC, RTC_EVTENCLR_COMPARE2_Msk);
1310 #endif /* !CONFIG_BT_CTLR_NRF_GRTC */
1311
1312 #if defined(CONFIG_BT_CTLR_LE_ENC) || defined(CONFIG_BT_CTLR_BROADCAST_ISO_ENC)
1313 hal_trigger_crypt_ppi_disable();
1314 #endif /* CONFIG_BT_CTLR_LE_ENC || CONFIG_BT_CTLR_BROADCAST_ISO_ENC */
1315
1316 hal_radio_nrf_ppi_channels_disable(
1317 #if (HAL_RADIO_ENABLE_TX_ON_TICK_PPI != HAL_RADIO_ENABLE_RX_ON_TICK_PPI) && \
1318 !defined(DPPI_PRESENT)
1319 BIT(HAL_RADIO_ENABLE_RX_ON_TICK_PPI) |
1320 #endif /* (HAL_RADIO_ENABLE_TX_ON_TICK_PPI !=
1321 * HAL_RADIO_ENABLE_RX_ON_TICK_PPI) && !DPPI_PRESENT
1322 */
1323 BIT(HAL_EVENT_TIMER_START_PPI) |
1324 BIT(HAL_RADIO_READY_TIME_CAPTURE_PPI) |
1325 BIT(HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI) |
1326 BIT(HAL_RADIO_DISABLE_ON_HCTO_PPI) |
1327 BIT(HAL_RADIO_END_TIME_CAPTURE_PPI) |
1328 #if !defined(CONFIG_BT_CTLR_TIFS_HW)
1329 BIT(HAL_SW_SWITCH_TIMER_CLEAR_PPI) |
1330 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1331 #if defined(CONFIG_BT_CTLR_PHY_CODED)
1332 #if defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED)
1333 BIT(HAL_TRIGGER_RATEOVERRIDE_PPI) |
1334 #if !defined(CONFIG_BT_CTLR_TIFS_HW)
1335 BIT(HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI) |
1336 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1337 #endif /* CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */
1338 #endif /* CONFIG_BT_CTLR_PHY_CODED */
1339 #if defined(CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE)
1340 BIT(HAL_SW_SWITCH_TIMER_PHYEND_DELAY_COMPENSATION_DISABLE_PPI) |
1341 #endif /* CONFIG_BT_CTLR_DF_PHYEND_OFFSET_COMPENSATION_ENABLE */
1342 #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RX)
1343 BIT(HAL_TRIGGER_CRYPT_DELAY_PPI) |
1344 #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RX */
1345 #if defined(CONFIG_BT_CTLR_LE_ENC) || defined(CONFIG_BT_CTLR_BROADCAST_ISO_ENC)
1346 BIT(HAL_TRIGGER_CRYPT_PPI) |
1347 #endif /* CONFIG_BT_CTLR_LE_ENC || CONFIG_BT_CTLR_BROADCAST_ISO_ENC */
1348 0);
1349 }
1350
radio_tmr_tx_enable(void)1351 void radio_tmr_tx_enable(void)
1352 {
1353 #if defined(CONFIG_SOC_COMPATIBLE_NRF53X) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
1354 #else /* !CONFIG_SOC_COMPATIBLE_NRF53X && !CONFIG_SOC_COMPATIBLE_NRF54LX */
1355 #if (HAL_RADIO_ENABLE_TX_ON_TICK_PPI == HAL_RADIO_ENABLE_RX_ON_TICK_PPI)
1356 hal_radio_enable_on_tick_ppi_config_and_enable(1U);
1357 #endif /* HAL_RADIO_ENABLE_TX_ON_TICK_PPI == HAL_RADIO_ENABLE_RX_ON_TICK_PPI */
1358 #endif /* !CONFIG_SOC_COMPATIBLE_NRF53X && !CONFIG_SOC_COMPATIBLE_NRF54LX */
1359 }
1360
radio_tmr_rx_enable(void)1361 void radio_tmr_rx_enable(void)
1362 {
1363 #if defined(CONFIG_SOC_COMPATIBLE_NRF53X) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
1364 #else /* !CONFIG_SOC_COMPATIBLE_NRF53X && !CONFIG_SOC_COMPATIBLE_NRF54LX */
1365 #if (HAL_RADIO_ENABLE_TX_ON_TICK_PPI == HAL_RADIO_ENABLE_RX_ON_TICK_PPI)
1366 hal_radio_enable_on_tick_ppi_config_and_enable(0U);
1367 #endif /* HAL_RADIO_ENABLE_TX_ON_TICK_PPI == HAL_RADIO_ENABLE_RX_ON_TICK_PPI */
1368 #endif /* !CONFIG_SOC_COMPATIBLE_NRF53X && !CONFIG_SOC_COMPATIBLE_NRF54LX */
1369 }
1370
radio_tmr_tx_disable(void)1371 void radio_tmr_tx_disable(void)
1372 {
1373 #if defined(CONFIG_SOC_COMPATIBLE_NRF53X) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
1374 nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_TXEN);
1375 #else /* !CONFIG_SOC_COMPATIBLE_NRF53X && !CONFIG_SOC_COMPATIBLE_NRF54LX */
1376 #endif /* !CONFIG_SOC_COMPATIBLE_NRF53X && !CONFIG_SOC_COMPATIBLE_NRF54LX */
1377 }
1378
radio_tmr_rx_disable(void)1379 void radio_tmr_rx_disable(void)
1380 {
1381 #if defined(CONFIG_SOC_COMPATIBLE_NRF53X) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
1382 nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_RXEN);
1383 #else /* !CONFIG_SOC_COMPATIBLE_NRF53X && !CONFIG_SOC_COMPATIBLE_NRF54LX */
1384 #endif /* !CONFIG_SOC_COMPATIBLE_NRF53X && !CONFIG_SOC_COMPATIBLE_NRF54LX */
1385 }
1386
radio_tmr_tifs_set(uint32_t tifs)1387 void radio_tmr_tifs_set(uint32_t tifs)
1388 {
1389 #if defined(CONFIG_BT_CTLR_TIFS_HW)
1390 NRF_RADIO->TIFS = tifs;
1391 #else /* !CONFIG_BT_CTLR_TIFS_HW */
1392 nrf_timer_cc_set(SW_SWITCH_TIMER,
1393 SW_SWITCH_TIMER_EVTS_COMP(sw_tifs_toggle), tifs);
1394 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1395 }
1396
radio_tmr_start(uint8_t trx,uint32_t ticks_start,uint32_t remainder)1397 uint32_t radio_tmr_start(uint8_t trx, uint32_t ticks_start, uint32_t remainder)
1398 {
1399 uint32_t remainder_us;
1400
1401 /* Convert jitter to positive offset remainder in microseconds */
1402 hal_ticker_remove_jitter(&ticks_start, &remainder);
1403 remainder_us = remainder;
1404
1405 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1406 /* When using single timer for software tIFS switching, ensure that
1407 * the timer compare value is large enough to consider radio ISR
1408 * latency so that the ISR is able to disable the PPI/DPPI that again
1409 * could trigger the TXEN/RXEN task.
1410 * The timer is cleared on Radio End and if the PPI/DPPI is not disabled
1411 * by the Radio ISR, the compare will trigger again.
1412 */
1413 uint32_t latency_ticks;
1414 uint32_t latency_us;
1415
1416 latency_us = MAX(remainder_us, HAL_RADIO_ISR_LATENCY_MAX_US) - remainder_us;
1417 latency_ticks = HAL_TICKER_US_TO_TICKS(latency_us);
1418 ticks_start -= latency_ticks;
1419 remainder_us += latency_us;
1420 #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1421
1422 nrf_timer_task_trigger(EVENT_TIMER, NRF_TIMER_TASK_CLEAR);
1423 EVENT_TIMER->MODE = 0;
1424 EVENT_TIMER->PRESCALER = HAL_EVENT_TIMER_PRESCALER_VALUE;
1425 EVENT_TIMER->BITMODE = 2; /* 24 - bit */
1426
1427 nrf_timer_cc_set(EVENT_TIMER, HAL_EVENT_TIMER_TRX_CC_OFFSET, remainder_us);
1428
1429 #if defined(CONFIG_BT_CTLR_NRF_GRTC)
1430 uint32_t cntr_l, cntr_h, cntr_h_overflow, stale;
1431
1432 /* Disable capture/compare */
1433 nrf_grtc_sys_counter_compare_event_disable(NRF_GRTC, HAL_CNTR_GRTC_CC_IDX_RADIO);
1434
1435 /* NOTE: We are going to use TASKS_CAPTURE to read current
1436 * SYSCOUNTER H and L, so that COMPARE registers can be set
1437 * considering that we need to set H compare value too.
1438 */
1439
1440 /* Read current syscounter value */
1441 do {
1442 cntr_h = nrf_grtc_sys_counter_high_get(NRF_GRTC);
1443 cntr_l = nrf_grtc_sys_counter_low_get(NRF_GRTC);
1444 cntr_h_overflow = nrf_grtc_sys_counter_high_get(NRF_GRTC);
1445 } while ((cntr_h & GRTC_SYSCOUNTER_SYSCOUNTERH_BUSY_Msk) ||
1446 (cntr_h_overflow & GRTC_SYSCOUNTER_SYSCOUNTERH_OVERFLOW_Msk));
1447
1448 /* Set a stale value in capture value */
1449 stale = cntr_l - 1U;
1450 NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].CCL = stale;
1451
1452 /* Trigger a capture */
1453 nrf_grtc_task_trigger(NRF_GRTC, (NRF_GRTC_TASK_CAPTURE_0 +
1454 (HAL_CNTR_GRTC_CC_IDX_RADIO * sizeof(uint32_t))));
1455
1456 /* Wait to get a new L value */
1457 do {
1458 cntr_l = NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].CCL;
1459 } while (cntr_l == stale);
1460
1461 /* Read H value */
1462 cntr_h = NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].CCH;
1463
1464 /* NOTE: HERE, we have cntr_h and cntr_l in sync. */
1465
1466 /* Handle rollover between current and expected value */
1467 if (ticks_start < cntr_l) {
1468 cntr_h++;
1469 }
1470
1471 /* Clear compare event, if any */
1472 nrf_grtc_event_clear(NRF_GRTC, HAL_CNTR_GRTC_EVENT_COMPARE_RADIO);
1473
1474 /* Set compare register values */
1475 nrf_grtc_sys_counter_cc_set(NRF_GRTC, HAL_CNTR_GRTC_CC_IDX_RADIO,
1476 ((((uint64_t)cntr_h & GRTC_CC_CCH_CCH_Msk) << 32) |
1477 ticks_start));
1478
1479 /* Enable compare */
1480 nrf_grtc_sys_counter_compare_event_enable(NRF_GRTC, HAL_CNTR_GRTC_CC_IDX_RADIO);
1481
1482 #else /* !CONFIG_BT_CTLR_NRF_GRTC */
1483 nrf_rtc_cc_set(NRF_RTC, 2, ticks_start);
1484 nrf_rtc_event_enable(NRF_RTC, RTC_EVTENSET_COMPARE2_Msk);
1485 #endif /* !CONFIG_BT_CTLR_NRF_GRTC */
1486
1487 hal_event_timer_start_ppi_config();
1488 hal_radio_nrf_ppi_channels_enable(BIT(HAL_EVENT_TIMER_START_PPI));
1489
1490 hal_radio_enable_on_tick_ppi_config_and_enable(trx);
1491
1492 #if !defined(CONFIG_BT_CTLR_TIFS_HW)
1493 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1494 last_pdu_end_us_init(latency_us);
1495
1496 #else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1497 nrf_timer_task_trigger(SW_SWITCH_TIMER, NRF_TIMER_TASK_CLEAR);
1498 SW_SWITCH_TIMER->MODE = 0;
1499 SW_SWITCH_TIMER->PRESCALER = HAL_EVENT_TIMER_PRESCALER_VALUE;
1500 SW_SWITCH_TIMER->BITMODE = 0; /* 16 bit */
1501 /* FIXME: start along with EVENT_TIMER, to save power */
1502 nrf_timer_task_trigger(SW_SWITCH_TIMER, NRF_TIMER_TASK_START);
1503 #endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1504
1505 hal_sw_switch_timer_clear_ppi_config();
1506
1507 #if !defined(CONFIG_BT_CTLR_PHY_CODED) || \
1508 !defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED)
1509 /* Software switch group's disable PPI can be configured one time here
1510 * at timer setup when only 1M and/or 2M is supported.
1511 */
1512 hal_radio_group_task_disable_ppi_setup();
1513
1514 #else /* CONFIG_BT_CTLR_PHY_CODED && CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */
1515 /* Software switch group's disable PPI needs to be configured at every
1516 * sw_switch() as they depend on the actual PHYs used in TX/RX mode.
1517 */
1518 #endif /* CONFIG_BT_CTLR_PHY_CODED && CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */
1519 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1520
1521 return remainder_us;
1522 }
1523
radio_tmr_start_tick(uint8_t trx,uint32_t ticks_start)1524 uint32_t radio_tmr_start_tick(uint8_t trx, uint32_t ticks_start)
1525 {
1526 uint32_t remainder_us;
1527
1528 /* Setup compare event with min. 1 us offset */
1529 remainder_us = 1U;
1530
1531 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1532 /* When using single timer for software tIFS switching, ensure that
1533 * the timer compare value is large enough to consider radio ISR
1534 * latency so that the ISR is able to disable the PPI/DPPI that again
1535 * could trigger the TXEN/RXEN task.
1536 * The timer is cleared on Radio End and if the PPI/DPPI is not disabled
1537 * by the Radio ISR, the compare will trigger again.
1538 */
1539 uint32_t latency_ticks;
1540 uint32_t latency_us;
1541
1542 latency_us = MAX(remainder_us, HAL_RADIO_ISR_LATENCY_MAX_US) - remainder_us;
1543 latency_ticks = HAL_TICKER_US_TO_TICKS(latency_us);
1544 ticks_start -= latency_ticks;
1545 remainder_us += latency_us;
1546 #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1547
1548 nrf_timer_task_trigger(EVENT_TIMER, NRF_TIMER_TASK_STOP);
1549 nrf_timer_task_trigger(EVENT_TIMER, NRF_TIMER_TASK_CLEAR);
1550
1551 nrf_timer_cc_set(EVENT_TIMER, HAL_EVENT_TIMER_TRX_CC_OFFSET, remainder_us);
1552
1553 #if defined(CONFIG_BT_CTLR_NRF_GRTC)
1554 uint32_t cntr_l, cntr_h, cntr_h_overflow, stale;
1555
1556 /* Disable capture/compare */
1557 nrf_grtc_sys_counter_compare_event_disable(NRF_GRTC, HAL_CNTR_GRTC_CC_IDX_RADIO);
1558
1559 /* NOTE: We are going to use TASKS_CAPTURE to read current
1560 * SYSCOUNTER H and L, so that COMPARE registers can be set
1561 * considering that we need to set H compare value too.
1562 */
1563
1564 /* Read current syscounter value */
1565 do {
1566 cntr_h = nrf_grtc_sys_counter_high_get(NRF_GRTC);
1567 cntr_l = nrf_grtc_sys_counter_low_get(NRF_GRTC);
1568 cntr_h_overflow = nrf_grtc_sys_counter_high_get(NRF_GRTC);
1569 } while ((cntr_h & GRTC_SYSCOUNTER_SYSCOUNTERH_BUSY_Msk) ||
1570 (cntr_h_overflow & GRTC_SYSCOUNTER_SYSCOUNTERH_OVERFLOW_Msk));
1571
1572 /* Set a stale value in capture value */
1573 stale = cntr_l - 1U;
1574 NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].CCL = stale;
1575
1576 /* Trigger a capture */
1577 nrf_grtc_task_trigger(NRF_GRTC, (NRF_GRTC_TASK_CAPTURE_0 +
1578 (HAL_CNTR_GRTC_CC_IDX_RADIO * sizeof(uint32_t))));
1579
1580 /* Wait to get a new L value */
1581 do {
1582 cntr_l = NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].CCL;
1583 } while (cntr_l == stale);
1584
1585 /* Read H value */
1586 cntr_h = NRF_GRTC->CC[HAL_CNTR_GRTC_CC_IDX_RADIO].CCH;
1587
1588 /* NOTE: HERE, we have cntr_h and cntr_l in sync. */
1589
1590 /* Handle rollover between current and expected value */
1591 if (ticks_start < cntr_l) {
1592 cntr_h++;
1593 }
1594
1595 /* Clear compare event, if any */
1596 nrf_grtc_event_clear(NRF_GRTC, HAL_CNTR_GRTC_EVENT_COMPARE_RADIO);
1597
1598 /* Set compare register values */
1599 nrf_grtc_sys_counter_cc_set(NRF_GRTC, HAL_CNTR_GRTC_CC_IDX_RADIO,
1600 ((((uint64_t)cntr_h & GRTC_CC_CCH_CCH_Msk) << 32) |
1601 ticks_start));
1602
1603 /* Enable compare */
1604 nrf_grtc_sys_counter_compare_event_enable(NRF_GRTC, HAL_CNTR_GRTC_CC_IDX_RADIO);
1605
1606 #else /* !CONFIG_BT_CTLR_NRF_GRTC */
1607 nrf_rtc_cc_set(NRF_RTC, 2, ticks_start);
1608 nrf_rtc_event_enable(NRF_RTC, RTC_EVTENSET_COMPARE2_Msk);
1609 #endif /* !CONFIG_BT_CTLR_NRF_GRTC */
1610
1611 hal_event_timer_start_ppi_config();
1612 hal_radio_nrf_ppi_channels_enable(BIT(HAL_EVENT_TIMER_START_PPI));
1613
1614 hal_radio_enable_on_tick_ppi_config_and_enable(trx);
1615
1616 #if !defined(CONFIG_BT_CTLR_TIFS_HW)
1617 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1618 last_pdu_end_us_init(latency_us);
1619 #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1620 #if defined(CONFIG_SOC_COMPATIBLE_NRF53X) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
1621 /* NOTE: Timer clear DPPI configuration is needed only for nRF53
1622 * because of calls to radio_disable() and
1623 * radio_switch_complete_and_disable() inside a radio event call
1624 * hal_radio_sw_switch_disable(), which in the case of nRF53
1625 * cancels the task subscription.
1626 */
1627 /* FIXME: hal_sw_switch_timer_clear_ppi_config() sets both task and
1628 * event. Consider a new interface to only set the task, or
1629 * change the design to not clear task subscription inside a
1630 * radio event but when the radio event is done.
1631 */
1632 hal_sw_switch_timer_clear_ppi_config();
1633 #endif /* CONFIG_SOC_COMPATIBLE_NRF53X || CONFIG_SOC_COMPATIBLE_NRF54LX */
1634 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1635
1636 return remainder_us;
1637 }
1638
radio_tmr_start_us(uint8_t trx,uint32_t start_us)1639 uint32_t radio_tmr_start_us(uint8_t trx, uint32_t start_us)
1640 {
1641 hal_radio_enable_on_tick_ppi_config_and_enable(trx);
1642
1643 #if !defined(CONFIG_BT_CTLR_TIFS_HW)
1644 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1645 /* As timer is reset on every radio end, remove the accumulated
1646 * last_pdu_end_us in the given start_us.
1647 */
1648 start_us -= last_pdu_end_us;
1649 #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1650 #if defined(CONFIG_SOC_COMPATIBLE_NRF53X) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
1651 /* NOTE: Timer clear DPPI configuration is needed only for nRF53
1652 * because of calls to radio_disable() and
1653 * radio_switch_complete_and_disable() inside a radio event call
1654 * hal_radio_sw_switch_disable(), which in the case of nRF53
1655 * cancels the task subscription.
1656 */
1657 /* FIXME: hal_sw_switch_timer_clear_ppi_config() sets both task and
1658 * event. Consider a new interface to only set the task, or
1659 * change the design to not clear task subscription inside a
1660 * radio event but when the radio event is done.
1661 */
1662 hal_sw_switch_timer_clear_ppi_config();
1663 #endif /* CONFIG_SOC_COMPATIBLE_NRF53X || CONFIG_SOC_COMPATIBLE_NRF54LX */
1664 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1665
1666 /* start_us could be the current count in the timer */
1667 uint32_t now_us = start_us;
1668 uint32_t actual_us;
1669
1670 /* Setup timer compare while determining the latency in doing so */
1671 do {
1672 /* Set start to be, now plus the determined latency */
1673 start_us = (now_us << 1) - start_us;
1674
1675 /* Setup compare event with min. 1 us offset */
1676 actual_us = start_us + 1U;
1677
1678 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1679 /* When using single timer for software tIFS switching, ensure that
1680 * the timer compare value is large enough to consider radio ISR
1681 * latency so that the ISR is able to disable the PPI/DPPI that again
1682 * could trigger the TXEN/RXEN task.
1683 * The timer is cleared on Radio End and if the PPI/DPPI is not disabled
1684 * by the Radio ISR, the compare will trigger again.
1685 */
1686 uint32_t latency_us;
1687
1688 latency_us = MAX(actual_us, HAL_RADIO_ISR_LATENCY_MAX_US) - actual_us;
1689 actual_us += latency_us;
1690 #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1691
1692 nrf_timer_event_clear(EVENT_TIMER, HAL_EVENT_TIMER_TRX_EVENT);
1693 nrf_timer_cc_set(EVENT_TIMER, HAL_EVENT_TIMER_TRX_CC_OFFSET, actual_us);
1694
1695 /* Capture the current time */
1696 nrf_timer_task_trigger(EVENT_TIMER, HAL_EVENT_TIMER_SAMPLE_TASK);
1697
1698 now_us = EVENT_TIMER->CC[HAL_EVENT_TIMER_SAMPLE_CC_OFFSET];
1699 } while ((now_us > start_us) &&
1700 (EVENT_TIMER->EVENTS_COMPARE[HAL_EVENT_TIMER_TRX_CC_OFFSET] == 0U));
1701
1702 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1703 actual_us += last_pdu_end_us;
1704 #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1705
1706 return actual_us;
1707 }
1708
radio_tmr_start_now(uint8_t trx)1709 uint32_t radio_tmr_start_now(uint8_t trx)
1710 {
1711 uint32_t start_us;
1712
1713 /* PPI/DPPI configuration will be done in radio_tmr_start_us() */
1714
1715 /* Capture the current time */
1716 nrf_timer_task_trigger(EVENT_TIMER, HAL_EVENT_TIMER_SAMPLE_TASK);
1717 start_us = EVENT_TIMER->CC[HAL_EVENT_TIMER_SAMPLE_CC_OFFSET];
1718
1719 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1720 /* As timer is reset on every radio end, add the accumulated
1721 * last_pdu_end_us to the captured current time.
1722 */
1723 start_us += last_pdu_end_us;
1724 #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1725
1726 /* Setup radio start at current time */
1727 start_us = radio_tmr_start_us(trx, start_us);
1728
1729 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1730 /* Remove the single timer start latency used to mitigate use of too
1731 * small compare register value. Thus, start_us returned be always
1732 * the value corresponding to the captured radio ready timestamp.
1733 * This is used in the calculation of aux_offset in subsequent
1734 * ADV_EXT_IND PDUs.
1735 */
1736 start_us -= last_pdu_end_latency_us;
1737 #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1738
1739 return start_us;
1740 }
1741
radio_tmr_start_get(void)1742 uint32_t radio_tmr_start_get(void)
1743 {
1744 uint32_t start_ticks;
1745
1746 #if defined(CONFIG_BT_CTLR_NRF_GRTC)
1747 uint64_t cc;
1748
1749 cc = nrf_grtc_sys_counter_cc_get(NRF_GRTC, HAL_CNTR_GRTC_CC_IDX_RADIO);
1750
1751 start_ticks = cc & 0xffffffffUL;
1752
1753 #else /* !CONFIG_BT_CTLR_NRF_GRTC */
1754 start_ticks = nrf_rtc_cc_get(NRF_RTC, 2);
1755 #endif /* !CONFIG_BT_CTLR_NRF_GRTC */
1756
1757 return start_ticks;
1758 }
1759
radio_tmr_start_latency_get(void)1760 uint32_t radio_tmr_start_latency_get(void)
1761 {
1762 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1763 return last_pdu_end_latency_us;
1764 #else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1765 return 0U;
1766 #endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1767 }
1768
radio_tmr_stop(void)1769 void radio_tmr_stop(void)
1770 {
1771 nrf_timer_task_trigger(EVENT_TIMER, NRF_TIMER_TASK_STOP);
1772 #if defined(TIMER_TASKS_SHUTDOWN_TASKS_SHUTDOWN_Msk)
1773 nrf_timer_task_trigger(EVENT_TIMER, NRF_TIMER_TASK_SHUTDOWN);
1774 #endif /* TIMER_TASKS_SHUTDOWN_TASKS_SHUTDOWN_Msk */
1775
1776 #if !defined(CONFIG_BT_CTLR_TIFS_HW)
1777 #if !defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1778 nrf_timer_task_trigger(SW_SWITCH_TIMER, NRF_TIMER_TASK_STOP);
1779 #if defined(TIMER_TASKS_SHUTDOWN_TASKS_SHUTDOWN_Msk)
1780 nrf_timer_task_trigger(SW_SWITCH_TIMER, NRF_TIMER_TASK_SHUTDOWN);
1781 #endif /* TIMER_TASKS_SHUTDOWN_TASKS_SHUTDOWN_Msk */
1782 #endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1783 #endif /* !CONFIG_BT_CTLR_TIFS_HW */
1784
1785 #if defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
1786 NRF_POWER->TASKS_LOWPWR = 1U;
1787 #endif /* CONFIG_SOC_COMPATIBLE_NRF54LX */
1788 }
1789
radio_tmr_hcto_configure(uint32_t hcto_us)1790 void radio_tmr_hcto_configure(uint32_t hcto_us)
1791 {
1792 nrf_timer_cc_set(EVENT_TIMER, HAL_EVENT_TIMER_HCTO_CC_OFFSET, hcto_us);
1793
1794 hal_radio_recv_timeout_cancel_ppi_config();
1795 hal_radio_disable_on_hcto_ppi_config();
1796 hal_radio_nrf_ppi_channels_enable(
1797 BIT(HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI) |
1798 BIT(HAL_RADIO_DISABLE_ON_HCTO_PPI));
1799 }
1800
radio_tmr_hcto_configure_abs(uint32_t hcto_from_start_us)1801 void radio_tmr_hcto_configure_abs(uint32_t hcto_from_start_us)
1802 {
1803 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1804 /* As timer is reset on every radio end, remove the accumulated
1805 * last_pdu_end_us in the given hcto_us.
1806 */
1807 hcto_from_start_us -= last_pdu_end_us;
1808 #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1809
1810 radio_tmr_hcto_configure(hcto_from_start_us);
1811 }
1812
radio_tmr_aa_capture(void)1813 void radio_tmr_aa_capture(void)
1814 {
1815 hal_radio_ready_time_capture_ppi_config();
1816 hal_radio_recv_timeout_cancel_ppi_config();
1817 hal_radio_nrf_ppi_channels_enable(
1818 BIT(HAL_RADIO_READY_TIME_CAPTURE_PPI) |
1819 BIT(HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI));
1820 }
1821
radio_tmr_aa_get(void)1822 uint32_t radio_tmr_aa_get(void)
1823 {
1824 return EVENT_TIMER->CC[HAL_EVENT_TIMER_HCTO_CC_OFFSET];
1825 }
1826
1827 static uint32_t radio_tmr_aa;
1828
radio_tmr_aa_save(uint32_t aa)1829 void radio_tmr_aa_save(uint32_t aa)
1830 {
1831 radio_tmr_aa = aa;
1832 }
1833
radio_tmr_aa_restore(void)1834 uint32_t radio_tmr_aa_restore(void)
1835 {
1836 /* NOTE: we dont need to restore for now, but return the saved value. */
1837 return radio_tmr_aa;
1838 }
1839
radio_tmr_ready_get(void)1840 uint32_t radio_tmr_ready_get(void)
1841 {
1842 return EVENT_TIMER->CC[HAL_EVENT_TIMER_TRX_CC_OFFSET];
1843 }
1844
1845 static uint32_t radio_tmr_ready;
1846
radio_tmr_ready_save(uint32_t ready)1847 void radio_tmr_ready_save(uint32_t ready)
1848 {
1849 radio_tmr_ready = ready;
1850 }
1851
radio_tmr_ready_restore(void)1852 uint32_t radio_tmr_ready_restore(void)
1853 {
1854 return radio_tmr_ready;
1855 }
1856
radio_tmr_end_capture(void)1857 void radio_tmr_end_capture(void)
1858 {
1859 /* NOTE: nRF5340 for single timer configuration shares the DPPI channel being triggered
1860 * by Radio End for End time capture and sw_switch DPPI channel toggling hence
1861 * always need to capture End time. Hence, the below code is present in
1862 * hal_sw_switch_timer_clear_ppi_config() and sw_switch(). There is no need to
1863 * configure the channel again in this function.
1864 */
1865 #if (!defined(CONFIG_SOC_COMPATIBLE_NRF53X) && !defined(CONFIG_SOC_COMPATIBLE_NRF54LX)) || \
1866 ((defined(CONFIG_SOC_COMPATIBLE_NRF53X) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX)) && \
1867 !defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER))
1868 hal_radio_end_time_capture_ppi_config();
1869 hal_radio_nrf_ppi_channels_enable(BIT(HAL_RADIO_END_TIME_CAPTURE_PPI));
1870 #endif /* (!CONFIG_SOC_COMPATIBLE_NRF53X && !CONFIG_SOC_COMPATIBLE_NRF54LX) ||
1871 * ((CONFIG_SOC_COMPATIBLE_NRF53X || CONFIG_SOC_COMPATIBLE_NRF54LX) &&
1872 * !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1873 */
1874 }
1875
radio_tmr_end_get(void)1876 uint32_t radio_tmr_end_get(void)
1877 {
1878 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1879 return last_pdu_end_us;
1880 #else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1881 return EVENT_TIMER->CC[HAL_EVENT_TIMER_TRX_END_CC_OFFSET];
1882 #endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1883 }
1884
radio_tmr_tifs_base_get(void)1885 uint32_t radio_tmr_tifs_base_get(void)
1886 {
1887 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1888 return 0U;
1889 #else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1890 return radio_tmr_end_get();
1891 #endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1892 }
1893
1894 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1895 static uint32_t tmr_sample_val;
1896 #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1897
radio_tmr_sample(void)1898 void radio_tmr_sample(void)
1899 {
1900 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1901 uint32_t cc;
1902
1903 cc = EVENT_TIMER->CC[HAL_EVENT_TIMER_SAMPLE_CC_OFFSET];
1904 nrf_timer_task_trigger(EVENT_TIMER, HAL_EVENT_TIMER_SAMPLE_TASK);
1905
1906 tmr_sample_val = EVENT_TIMER->CC[HAL_EVENT_TIMER_SAMPLE_CC_OFFSET];
1907 nrf_timer_cc_set(EVENT_TIMER, HAL_EVENT_TIMER_SAMPLE_CC_OFFSET, cc);
1908
1909 #else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1910 nrf_timer_task_trigger(EVENT_TIMER, HAL_EVENT_TIMER_SAMPLE_TASK);
1911 #endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1912 }
1913
radio_tmr_sample_get(void)1914 uint32_t radio_tmr_sample_get(void)
1915 {
1916 #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)
1917 return tmr_sample_val;
1918 #else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1919 return EVENT_TIMER->CC[HAL_EVENT_TIMER_SAMPLE_CC_OFFSET];
1920 #endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */
1921 }
1922
1923 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN) || \
1924 defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
radio_gpio_pa_lna_init(void)1925 int radio_gpio_pa_lna_init(void)
1926 {
1927 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN) || defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
1928 if (nrfx_gpiote_channel_alloc(&gpiote_palna, &gpiote_ch_palna) != NRFX_SUCCESS) {
1929 return -ENOMEM;
1930 }
1931 #endif
1932
1933 #if defined(NRF_GPIO_PDN_PIN)
1934 if (nrfx_gpiote_channel_alloc(&gpiote_pdn, &gpiote_ch_pdn) != NRFX_SUCCESS) {
1935 return -ENOMEM;
1936 }
1937 #endif
1938
1939 return 0;
1940 }
1941
radio_gpio_pa_lna_deinit(void)1942 void radio_gpio_pa_lna_deinit(void)
1943 {
1944 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN) || defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
1945 (void)nrfx_gpiote_channel_free(&gpiote_palna, gpiote_ch_palna);
1946 #endif
1947
1948 #if defined(NRF_GPIO_PDN_PIN)
1949 (void)nrfx_gpiote_channel_free(&gpiote_pdn, gpiote_ch_pdn);
1950 #endif
1951 }
1952
1953 #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN)
radio_gpio_pa_setup(void)1954 void radio_gpio_pa_setup(void)
1955 {
1956 gpiote_palna.p_reg->CONFIG[gpiote_ch_palna] =
1957 (GPIOTE_CONFIG_MODE_Task <<
1958 GPIOTE_CONFIG_MODE_Pos) |
1959 (NRF_GPIO_PA_PSEL <<
1960 GPIOTE_CONFIG_PSEL_Pos) |
1961 (GPIOTE_CONFIG_POLARITY_Toggle <<
1962 GPIOTE_CONFIG_POLARITY_Pos) |
1963 (OUTINIT_INACTIVE(NRF_GPIO_PA_FLAGS) <<
1964 GPIOTE_CONFIG_OUTINIT_Pos);
1965
1966 #if defined(HAL_RADIO_FEM_IS_NRF21540)
1967 hal_pa_ppi_setup();
1968 radio_gpio_pdn_setup();
1969 #endif
1970 }
1971 #endif /* HAL_RADIO_GPIO_HAVE_PA_PIN */
1972
1973 #if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN)
radio_gpio_lna_setup(void)1974 void radio_gpio_lna_setup(void)
1975 {
1976 gpiote_palna.p_reg->CONFIG[gpiote_ch_palna] =
1977 (GPIOTE_CONFIG_MODE_Task <<
1978 GPIOTE_CONFIG_MODE_Pos) |
1979 (NRF_GPIO_LNA_PSEL <<
1980 GPIOTE_CONFIG_PSEL_Pos) |
1981 (GPIOTE_CONFIG_POLARITY_Toggle <<
1982 GPIOTE_CONFIG_POLARITY_Pos) |
1983 (OUTINIT_INACTIVE(NRF_GPIO_LNA_FLAGS) <<
1984 GPIOTE_CONFIG_OUTINIT_Pos);
1985
1986 #if defined(HAL_RADIO_FEM_IS_NRF21540)
1987 hal_lna_ppi_setup();
1988 radio_gpio_pdn_setup();
1989 #endif
1990 }
1991
radio_gpio_pdn_setup(void)1992 void radio_gpio_pdn_setup(void)
1993 {
1994 /* Note: the pdn-gpios property is optional. */
1995 #if defined(NRF_GPIO_PDN)
1996 gpiote_pdn.p_reg->CONFIG[gpiote_ch_pdn] =
1997 (GPIOTE_CONFIG_MODE_Task <<
1998 GPIOTE_CONFIG_MODE_Pos) |
1999 (NRF_GPIO_PDN_PSEL <<
2000 GPIOTE_CONFIG_PSEL_Pos) |
2001 (GPIOTE_CONFIG_POLARITY_Toggle <<
2002 GPIOTE_CONFIG_POLARITY_Pos) |
2003 (OUTINIT_INACTIVE(NRF_GPIO_PDN_FLAGS) <<
2004 GPIOTE_CONFIG_OUTINIT_Pos);
2005 #endif /* NRF_GPIO_PDN_PIN */
2006 }
2007
radio_gpio_lna_on(void)2008 void radio_gpio_lna_on(void)
2009 {
2010 if (ACTIVE_LOW(NRF_GPIO_LNA_FLAGS)) {
2011 NRF_GPIO_LNA->OUTCLR = BIT(NRF_GPIO_LNA_PIN);
2012 } else {
2013 NRF_GPIO_LNA->OUTSET = BIT(NRF_GPIO_LNA_PIN);
2014 }
2015 }
2016
radio_gpio_lna_off(void)2017 void radio_gpio_lna_off(void)
2018 {
2019 if (ACTIVE_LOW(NRF_GPIO_LNA_FLAGS)) {
2020 NRF_GPIO_LNA->OUTSET = BIT(NRF_GPIO_LNA_PIN);
2021 } else {
2022 NRF_GPIO_LNA->OUTCLR = BIT(NRF_GPIO_LNA_PIN);
2023 }
2024 }
2025 #endif /* HAL_RADIO_GPIO_HAVE_LNA_PIN */
2026
radio_gpio_pa_lna_enable(uint32_t trx_us)2027 void radio_gpio_pa_lna_enable(uint32_t trx_us)
2028 {
2029 nrf_timer_cc_set(EVENT_TIMER, HAL_EVENT_TIMER_PA_LNA_CC_OFFSET, trx_us);
2030 #if defined(HAL_RADIO_FEM_IS_NRF21540) && DT_NODE_HAS_PROP(FEM_NODE, pdn_gpios)
2031 nrf_timer_cc_set(EVENT_TIMER, HAL_EVENT_TIMER_PA_LNA_PDN_CC_OFFSET,
2032 (trx_us - NRF_GPIO_PDN_OFFSET));
2033 hal_radio_nrf_ppi_channels_enable(BIT(HAL_ENABLE_PALNA_PPI) |
2034 BIT(HAL_DISABLE_PALNA_PPI) |
2035 BIT(HAL_ENABLE_FEM_PPI) |
2036 BIT(HAL_DISABLE_FEM_PPI));
2037 #else
2038 hal_radio_nrf_ppi_channels_enable(BIT(HAL_ENABLE_PALNA_PPI) |
2039 BIT(HAL_DISABLE_PALNA_PPI));
2040 #endif
2041 }
2042
radio_gpio_pa_lna_disable(void)2043 void radio_gpio_pa_lna_disable(void)
2044 {
2045 #if defined(HAL_RADIO_FEM_IS_NRF21540)
2046 hal_radio_nrf_ppi_channels_disable(BIT(HAL_ENABLE_PALNA_PPI) |
2047 BIT(HAL_DISABLE_PALNA_PPI) |
2048 BIT(HAL_ENABLE_FEM_PPI) |
2049 BIT(HAL_DISABLE_FEM_PPI));
2050 gpiote_palna.p_reg->CONFIG[gpiote_ch_palna] = 0;
2051 gpiote_pdn.p_reg->CONFIG[gpiote_ch_pdn] = 0;
2052 #else
2053 hal_radio_nrf_ppi_channels_disable(BIT(HAL_ENABLE_PALNA_PPI) |
2054 BIT(HAL_DISABLE_PALNA_PPI));
2055 gpiote_palna.p_reg->CONFIG[gpiote_ch_palna] = 0;
2056 #endif
2057 }
2058 #endif /* HAL_RADIO_GPIO_HAVE_PA_PIN || HAL_RADIO_GPIO_HAVE_LNA_PIN */
2059
2060 #if defined(CONFIG_BT_CTLR_LE_ENC) || defined(CONFIG_BT_CTLR_BROADCAST_ISO_ENC)
2061 #if defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
2062 struct ccm_job_ptr {
2063 void *ptr;
2064 struct {
2065 uint32_t length:24;
2066 uint32_t attribute:8;
2067 } __packed;
2068 } __packed;
2069
2070 #define CCM_JOB_PTR_ATTRIBUTE_ALEN 11U
2071 #define CCM_JOB_PTR_ATTRIBUTE_MLEN 12U
2072 #define CCM_JOB_PTR_ATTRIBUTE_ADATA 13U
2073 #define CCM_JOB_PTR_ATTRIBUTE_MDATA 14U
2074
2075 static struct {
2076 uint16_t in_alen;
2077 uint16_t in_mlen;
2078 uint8_t in_mlen_msb;
2079 uint8_t out_mlen_msb;
2080 uint16_t out_alen;
2081 struct ccm_job_ptr in[6];
2082 struct ccm_job_ptr out[6];
2083 } ccm_job;
2084
2085 #else /* !CONFIG_SOC_COMPATIBLE_NRF54LX */
2086 static uint8_t MALIGN(4) _ccm_scratch[(HAL_RADIO_PDU_LEN_MAX - 4) + 16];
2087 #endif /* !CONFIG_SOC_COMPATIBLE_NRF54LX */
2088
2089 #if defined(CONFIG_BT_CTLR_LE_ENC) || defined(CONFIG_BT_CTLR_SYNC_ISO)
radio_ccm_ext_rx_pkt_set(struct ccm * cnf,uint8_t phy,uint8_t pdu_type,void * pkt)2090 static void *radio_ccm_ext_rx_pkt_set(struct ccm *cnf, uint8_t phy, uint8_t pdu_type, void *pkt)
2091 {
2092 uint32_t mode;
2093
2094 NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Disabled;
2095 NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Enabled;
2096
2097 mode = (CCM_MODE_MODE_Decryption << CCM_MODE_MODE_Pos) &
2098 CCM_MODE_MODE_Msk;
2099
2100 #if defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
2101 /* Enable CCM Protocol Mode Bluetooth LE */
2102 mode |= (CCM_MODE_PROTOCOL_Ble << CCM_MODE_PROTOCOL_Pos) &
2103 CCM_MODE_PROTOCOL_Msk;
2104
2105 /* Enable CCM MAC Length 4 bytes */
2106 mode |= (CCM_MODE_MACLEN_M4 << CCM_MODE_MACLEN_Pos) &
2107 CCM_MODE_MACLEN_Msk;
2108
2109 #elif !defined(CONFIG_SOC_SERIES_NRF51X)
2110 /* Enable CCM support for 8-bit length field PDUs. */
2111 mode |= (CCM_MODE_LENGTH_Extended << CCM_MODE_LENGTH_Pos) &
2112 CCM_MODE_LENGTH_Msk;
2113 #endif /* !CONFIG_SOC_SERIES_NRF51X */
2114
2115 /* Select CCM data rate based on current PHY in use. */
2116 switch (phy) {
2117 default:
2118 case PHY_1M:
2119 #if !defined(CONFIG_SOC_SERIES_NRF51X)
2120 mode |= (CCM_MODE_DATARATE_1Mbit <<
2121 CCM_MODE_DATARATE_Pos) &
2122 CCM_MODE_DATARATE_Msk;
2123 #endif /* !CONFIG_SOC_SERIES_NRF51X */
2124
2125 if (false) {
2126
2127 #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RX)
2128 } else if (pdu_type == RADIO_PKT_CONF_PDU_TYPE_DC) {
2129 /* When direction finding CTE receive feature is enabled then on-the-fly
2130 * PDU parsing for CTEInfo is always done. In such situation, the CCM
2131 * TASKS_CRYPT must be started with short delay. That give the Radio time
2132 * to store received bits in shared memory.
2133 */
2134 radio_bc_configure(CCM_TASKS_CRYPT_DELAY_BITS);
2135 radio_bc_status_reset();
2136 hal_trigger_crypt_by_bcmatch_ppi_config();
2137 hal_radio_nrf_ppi_channels_enable(BIT(HAL_TRIGGER_CRYPT_DELAY_PPI));
2138 #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RX */
2139 } else {
2140 hal_trigger_crypt_ppi_config();
2141 hal_radio_nrf_ppi_channels_enable(BIT(HAL_TRIGGER_CRYPT_PPI));
2142 }
2143 break;
2144
2145 case PHY_2M:
2146 #if !defined(CONFIG_SOC_SERIES_NRF51X)
2147 mode |= (CCM_MODE_DATARATE_2Mbit <<
2148 CCM_MODE_DATARATE_Pos) &
2149 CCM_MODE_DATARATE_Msk;
2150 #endif /* !CONFIG_SOC_SERIES_NRF51X */
2151
2152 hal_trigger_crypt_ppi_config();
2153 hal_radio_nrf_ppi_channels_enable(BIT(HAL_TRIGGER_CRYPT_PPI));
2154
2155 break;
2156
2157 #if defined(CONFIG_BT_CTLR_PHY_CODED)
2158 #if defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED)
2159 case PHY_CODED:
2160 mode |= (CCM_MODE_DATARATE_125Kbps <<
2161 CCM_MODE_DATARATE_Pos) &
2162 CCM_MODE_DATARATE_Msk;
2163
2164 NRF_CCM->RATEOVERRIDE =
2165 (CCM_RATEOVERRIDE_RATEOVERRIDE_500Kbps <<
2166 CCM_RATEOVERRIDE_RATEOVERRIDE_Pos) &
2167 CCM_RATEOVERRIDE_RATEOVERRIDE_Msk;
2168
2169 hal_trigger_rateoverride_ppi_config();
2170 hal_radio_nrf_ppi_channels_enable(
2171 BIT(HAL_TRIGGER_RATEOVERRIDE_PPI));
2172
2173 hal_trigger_crypt_ppi_config();
2174 hal_radio_nrf_ppi_channels_enable(BIT(HAL_TRIGGER_CRYPT_PPI));
2175
2176 break;
2177 #endif /* CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */
2178 #endif /* CONFIG_BT_CTLR_PHY_CODED */
2179 }
2180
2181 NRF_CCM->MODE = mode;
2182
2183 #if defined(CONFIG_HAS_HW_NRF_CCM_HEADERMASK) || \
2184 defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
2185 #if defined(CONFIG_HAS_HW_NRF_CCM_HEADERMASK)
2186 #define ADATAMASK HEADERMASK
2187 #endif /* CONFIG_HAS_HW_NRF_CCM_HEADERMASK */
2188 switch (pdu_type) {
2189 case RADIO_PKT_CONF_PDU_TYPE_BIS:
2190 NRF_CCM->ADATAMASK = 0xC3; /* mask CSSN and CSTF */
2191 break;
2192 case RADIO_PKT_CONF_PDU_TYPE_CIS:
2193 NRF_CCM->ADATAMASK = 0xA3; /* mask SN, NESN, CIE and NPI */
2194 break;
2195 default:
2196 /* Using default reset value of ADATAMASK */
2197 NRF_CCM->ADATAMASK = 0xE3; /* mask SN, NESN and MD */
2198 break;
2199 }
2200 #if defined(CONFIG_HAS_HW_NRF_CCM_HEADERMASK)
2201 #undef ADATAMASK
2202 #endif /* CONFIG_HAS_HW_NRF_CCM_HEADERMASK */
2203 #endif /* CONFIG_HAS_HW_NRF_CCM_HEADERMASK ||
2204 * CONFIG_SOC_COMPATIBLE_NRF54LX
2205 */
2206
2207 #if !defined(CONFIG_SOC_SERIES_NRF51X) && \
2208 !defined(CONFIG_SOC_NRF52832) && \
2209 !defined(CONFIG_SOC_COMPATIBLE_NRF54LX) && \
2210 (!defined(CONFIG_BT_CTLR_DATA_LENGTH_MAX) || \
2211 (CONFIG_BT_CTLR_DATA_LENGTH_MAX < ((HAL_RADIO_PDU_LEN_MAX) - 4U)))
2212 const uint8_t max_len = (NRF_RADIO->PCNF1 & RADIO_PCNF1_MAXLEN_Msk) >>
2213 RADIO_PCNF1_MAXLEN_Pos;
2214
2215 /* MAXPACKETSIZE value 0x001B (27) - 0x00FB (251) bytes */
2216 NRF_CCM->MAXPACKETSIZE = max_len - 4U;
2217 #endif
2218
2219 #if defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
2220 /* Configure the CCM key, nonce and pointers */
2221 NRF_CCM->KEY.VALUE[3] = sys_get_be32(&cnf->key[0]);
2222 NRF_CCM->KEY.VALUE[2] = sys_get_be32(&cnf->key[4]);
2223 NRF_CCM->KEY.VALUE[1] = sys_get_be32(&cnf->key[8]);
2224 NRF_CCM->KEY.VALUE[0] = sys_get_be32(&cnf->key[12]);
2225
2226 NRF_CCM->NONCE.VALUE[3] = ((uint8_t *)&cnf->counter)[0];
2227 NRF_CCM->NONCE.VALUE[2] = sys_get_be32(&((uint8_t *)&cnf->counter)[1]) |
2228 (cnf->direction << 7);
2229 NRF_CCM->NONCE.VALUE[1] = sys_get_be32(&cnf->iv[0]);
2230 NRF_CCM->NONCE.VALUE[0] = sys_get_be32(&cnf->iv[4]);
2231
2232 const uint8_t mlen = (NRF_RADIO->PCNF1 & RADIO_PCNF1_MAXLEN_Msk) >>
2233 RADIO_PCNF1_MAXLEN_Pos;
2234
2235 const uint8_t alen = sizeof(uint8_t);
2236
2237 ccm_job.in_alen = alen;
2238 ccm_job.in[0].ptr = &ccm_job.in_alen;
2239 ccm_job.in[0].length = sizeof(ccm_job.in_alen);
2240 ccm_job.in[0].attribute = CCM_JOB_PTR_ATTRIBUTE_ALEN;
2241
2242 ccm_job.in[1].ptr = (void *)((uint8_t *)_pkt_scratch + 1U);
2243 ccm_job.in[1].length = sizeof(uint8_t);
2244 ccm_job.in[1].attribute = CCM_JOB_PTR_ATTRIBUTE_MLEN;
2245
2246 ccm_job.in_mlen_msb = 0U;
2247 ccm_job.in[2].ptr = &ccm_job.in_mlen_msb;
2248 ccm_job.in[2].length = sizeof(ccm_job.in_mlen_msb);
2249 ccm_job.in[2].attribute = CCM_JOB_PTR_ATTRIBUTE_MLEN;
2250
2251 ccm_job.in[3].ptr = (void *)((uint8_t *)_pkt_scratch + 0U);
2252 ccm_job.in[3].length = sizeof(uint8_t);
2253 ccm_job.in[3].attribute = CCM_JOB_PTR_ATTRIBUTE_ADATA;
2254
2255 ccm_job.in[4].ptr = (void *)((uint8_t *)_pkt_scratch + 3U);
2256 ccm_job.in[4].length = mlen;
2257 ccm_job.in[4].attribute = CCM_JOB_PTR_ATTRIBUTE_MDATA;
2258
2259 ccm_job.in[5].ptr = NULL;
2260 ccm_job.in[5].length = 0U;
2261 ccm_job.in[5].attribute = 0U;
2262
2263 ccm_job.out[0].ptr = &ccm_job.out_alen;
2264 ccm_job.out[0].length = sizeof(ccm_job.out_alen);
2265 ccm_job.out[0].attribute = CCM_JOB_PTR_ATTRIBUTE_ALEN;
2266
2267 ccm_job.out[1].ptr = (void *)((uint8_t *)pkt + 1U);
2268 ccm_job.out[1].length = sizeof(uint8_t);
2269 ccm_job.out[1].attribute = CCM_JOB_PTR_ATTRIBUTE_MLEN;
2270
2271 ccm_job.out[2].ptr = &ccm_job.out_mlen_msb;
2272 ccm_job.out[2].length = sizeof(ccm_job.out_mlen_msb);
2273 ccm_job.out[2].attribute = CCM_JOB_PTR_ATTRIBUTE_MLEN;
2274
2275 ccm_job.out[3].ptr = (void *)((uint8_t *)pkt + 0U);
2276 ccm_job.out[3].length = sizeof(uint8_t);
2277 ccm_job.out[3].attribute = CCM_JOB_PTR_ATTRIBUTE_ADATA;
2278
2279 ccm_job.out[4].ptr = (void *)((uint8_t *)pkt + 3U);
2280 ccm_job.out[4].length = mlen - sizeof(uint32_t);
2281 ccm_job.out[4].attribute = CCM_JOB_PTR_ATTRIBUTE_MDATA;
2282
2283 ccm_job.out[5].ptr = NULL;
2284 ccm_job.out[5].length = 0U;
2285 ccm_job.out[5].attribute = 0U;
2286
2287 NRF_CCM->IN.PTR = (uint32_t)ccm_job.in;
2288 NRF_CCM->OUT.PTR = (uint32_t)ccm_job.out;
2289
2290 nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_END);
2291 nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ERROR);
2292
2293 #else /* !CONFIG_SOC_COMPATIBLE_NRF54LX */
2294 NRF_CCM->CNFPTR = (uint32_t)cnf;
2295 NRF_CCM->INPTR = (uint32_t)_pkt_scratch;
2296 NRF_CCM->OUTPTR = (uint32_t)pkt;
2297 NRF_CCM->SCRATCHPTR = (uint32_t)_ccm_scratch;
2298 NRF_CCM->SHORTS = 0;
2299
2300 nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ENDKSGEN);
2301 nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_END);
2302 nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ERROR);
2303
2304 nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_KSGEN);
2305 #endif /* !CONFIG_SOC_COMPATIBLE_NRF54LX */
2306
2307 return _pkt_scratch;
2308 }
2309
radio_ccm_rx_pkt_set(struct ccm * cnf,uint8_t phy,void * pkt)2310 void *radio_ccm_rx_pkt_set(struct ccm *cnf, uint8_t phy, void *pkt)
2311 {
2312 return radio_ccm_ext_rx_pkt_set(cnf, phy, RADIO_PKT_CONF_PDU_TYPE_DC, pkt);
2313 }
2314
radio_ccm_iso_rx_pkt_set(struct ccm * cnf,uint8_t phy,uint8_t pdu_type,void * pkt)2315 void *radio_ccm_iso_rx_pkt_set(struct ccm *cnf, uint8_t phy, uint8_t pdu_type, void *pkt)
2316 {
2317 return radio_ccm_ext_rx_pkt_set(cnf, phy, pdu_type, pkt);
2318 }
2319 #endif /* CONFIG_BT_CTLR_LE_ENC || CONFIG_BT_CTLR_SYNC_ISO */
2320
2321 #if defined(CONFIG_BT_CTLR_LE_ENC) || defined(CONFIG_BT_CTLR_ADV_ISO)
radio_ccm_ext_tx_pkt_set(struct ccm * cnf,uint8_t pdu_type,void * pkt)2322 static void *radio_ccm_ext_tx_pkt_set(struct ccm *cnf, uint8_t pdu_type, void *pkt)
2323 {
2324 uint32_t mode;
2325
2326 NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Disabled;
2327 NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Enabled;
2328
2329 mode = (CCM_MODE_MODE_Encryption << CCM_MODE_MODE_Pos) &
2330 CCM_MODE_MODE_Msk;
2331
2332 #if defined(CONFIG_SOC_COMPATIBLE_NRF52X) || \
2333 defined(CONFIG_SOC_COMPATIBLE_NRF53X)
2334 /* Enable CCM support for 8-bit length field PDUs. */
2335 mode |= (CCM_MODE_LENGTH_Extended << CCM_MODE_LENGTH_Pos) &
2336 CCM_MODE_LENGTH_Msk;
2337
2338 /* NOTE: use fastest data rate as tx data needs to be prepared before
2339 * radio Tx on any PHY.
2340 */
2341 mode |= (CCM_MODE_DATARATE_2Mbit << CCM_MODE_DATARATE_Pos) &
2342 CCM_MODE_DATARATE_Msk;
2343
2344 #elif defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
2345 /* Enable CCM Protocol Mode Bluetooth LE */
2346 mode |= (CCM_MODE_PROTOCOL_Ble << CCM_MODE_PROTOCOL_Pos) &
2347 CCM_MODE_PROTOCOL_Msk;
2348
2349 /* NOTE: use fastest data rate as tx data needs to be prepared before
2350 * radio Tx on any PHY.
2351 */
2352 mode |= (CCM_MODE_DATARATE_4Mbit << CCM_MODE_DATARATE_Pos) &
2353 CCM_MODE_DATARATE_Msk;
2354
2355 /* Enable CCM MAC Length 4 bytes */
2356 mode |= (CCM_MODE_MACLEN_M4 << CCM_MODE_MACLEN_Pos) &
2357 CCM_MODE_MACLEN_Msk;
2358 #endif
2359
2360 NRF_CCM->MODE = mode;
2361
2362 #if defined(CONFIG_HAS_HW_NRF_CCM_HEADERMASK) || \
2363 defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
2364 #if defined(CONFIG_HAS_HW_NRF_CCM_HEADERMASK)
2365 #define ADATAMASK HEADERMASK
2366 #endif /* CONFIG_HAS_HW_NRF_CCM_HEADERMASK */
2367 switch (pdu_type) {
2368 case RADIO_PKT_CONF_PDU_TYPE_BIS:
2369 NRF_CCM->ADATAMASK = 0xC3; /* mask CSSN and CSTF */
2370 break;
2371 case RADIO_PKT_CONF_PDU_TYPE_CIS:
2372 NRF_CCM->ADATAMASK = 0xA3; /* mask SN, NESN, CIE and NPI */
2373 break;
2374 default:
2375 /* Using default reset value of ADATAMASK */
2376 NRF_CCM->ADATAMASK = 0xE3; /* mask SN, NESN and MD */
2377 break;
2378 }
2379 #if defined(CONFIG_HAS_HW_NRF_CCM_HEADERMASK)
2380 #undef ADATAMASK
2381 #endif /* CONFIG_HAS_HW_NRF_CCM_HEADERMASK */
2382 #endif /* CONFIG_HAS_HW_NRF_CCM_HEADERMASK ||
2383 * CONFIG_SOC_COMPATIBLE_NRF54LX
2384 */
2385
2386 #if !defined(CONFIG_SOC_SERIES_NRF51X) && \
2387 !defined(CONFIG_SOC_NRF52832) && \
2388 !defined(CONFIG_SOC_COMPATIBLE_NRF54LX) && \
2389 (!defined(CONFIG_BT_CTLR_DATA_LENGTH_MAX) || \
2390 (CONFIG_BT_CTLR_DATA_LENGTH_MAX < ((HAL_RADIO_PDU_LEN_MAX) - 4U)))
2391 const uint8_t max_len = (NRF_RADIO->PCNF1 & RADIO_PCNF1_MAXLEN_Msk) >>
2392 RADIO_PCNF1_MAXLEN_Pos;
2393
2394 /* MAXPACKETSIZE value 0x001B (27) - 0x00FB (251) bytes */
2395 NRF_CCM->MAXPACKETSIZE = max_len - 4U;
2396 #endif
2397
2398 #if defined(CONFIG_SOC_COMPATIBLE_NRF54LX)
2399 /* Configure the CCM key, nonce and pointers */
2400 NRF_CCM->KEY.VALUE[3] = sys_get_be32(&cnf->key[0]);
2401 NRF_CCM->KEY.VALUE[2] = sys_get_be32(&cnf->key[4]);
2402 NRF_CCM->KEY.VALUE[1] = sys_get_be32(&cnf->key[8]);
2403 NRF_CCM->KEY.VALUE[0] = sys_get_be32(&cnf->key[12]);
2404
2405 NRF_CCM->NONCE.VALUE[3] = ((uint8_t *)&cnf->counter)[0];
2406 NRF_CCM->NONCE.VALUE[2] = sys_get_be32(&((uint8_t *)&cnf->counter)[1]) |
2407 (cnf->direction << 7);
2408 NRF_CCM->NONCE.VALUE[1] = sys_get_be32(&cnf->iv[0]);
2409 NRF_CCM->NONCE.VALUE[0] = sys_get_be32(&cnf->iv[4]);
2410
2411 const uint8_t alen = sizeof(uint8_t);
2412
2413 ccm_job.in_alen = alen;
2414 ccm_job.in[0].ptr = &ccm_job.in_alen;
2415 ccm_job.in[0].length = sizeof(ccm_job.in_alen);
2416 ccm_job.in[0].attribute = CCM_JOB_PTR_ATTRIBUTE_ALEN;
2417
2418 const uint8_t mlen = *((uint8_t *)pkt + 1U);
2419
2420 ccm_job.in_mlen = mlen;
2421 ccm_job.in[1].ptr = &ccm_job.in_mlen;
2422 ccm_job.in[1].length = sizeof(ccm_job.in_mlen);
2423 ccm_job.in[1].attribute = CCM_JOB_PTR_ATTRIBUTE_MLEN;
2424
2425 ccm_job.in[2].ptr = (void *)((uint8_t *)pkt + 0U);
2426 ccm_job.in[2].length = alen;
2427 ccm_job.in[2].attribute = CCM_JOB_PTR_ATTRIBUTE_ADATA;
2428
2429 ccm_job.in[3].ptr = (void *)((uint8_t *)pkt + 3U);
2430 ccm_job.in[3].length = mlen;
2431 ccm_job.in[3].attribute = CCM_JOB_PTR_ATTRIBUTE_MDATA;
2432
2433 ccm_job.in[4].ptr = NULL;
2434 ccm_job.in[4].length = 0U;
2435 ccm_job.in[4].attribute = 0U;
2436
2437 ccm_job.out[0].ptr = &ccm_job.out_alen;
2438 ccm_job.out[0].length = sizeof(ccm_job.out_alen);
2439 ccm_job.out[0].attribute = CCM_JOB_PTR_ATTRIBUTE_ALEN;
2440
2441 ccm_job.out[1].ptr = (void *)((uint8_t *)_pkt_scratch + 1U);
2442 ccm_job.out[1].length = sizeof(uint8_t);
2443 ccm_job.out[1].attribute = CCM_JOB_PTR_ATTRIBUTE_MLEN;
2444
2445 ccm_job.out[2].ptr = &ccm_job.out_mlen_msb;
2446 ccm_job.out[2].length = sizeof(ccm_job.out_mlen_msb);
2447 ccm_job.out[2].attribute = CCM_JOB_PTR_ATTRIBUTE_MLEN;
2448
2449 ccm_job.out[3].ptr = (void *)((uint8_t *)_pkt_scratch + 0U);
2450 ccm_job.out[3].length = sizeof(uint8_t);
2451 ccm_job.out[3].attribute = CCM_JOB_PTR_ATTRIBUTE_ADATA;
2452
2453 ccm_job.out[4].ptr = (void *)((uint8_t *)_pkt_scratch + 3U);
2454 ccm_job.out[4].length = mlen + sizeof(uint32_t);
2455 ccm_job.out[4].attribute = CCM_JOB_PTR_ATTRIBUTE_MDATA;
2456
2457 ccm_job.out[5].ptr = NULL;
2458 ccm_job.out[5].length = 0U;
2459 ccm_job.out[5].attribute = 0U;
2460
2461 NRF_CCM->IN.PTR = (uint32_t)ccm_job.in;
2462 NRF_CCM->OUT.PTR = (uint32_t)ccm_job.out;
2463
2464 nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_END);
2465 nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ERROR);
2466
2467 nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_START);
2468
2469 #else /* !CONFIG_SOC_COMPATIBLE_NRF54LX */
2470 NRF_CCM->CNFPTR = (uint32_t)cnf;
2471 NRF_CCM->INPTR = (uint32_t)pkt;
2472 NRF_CCM->OUTPTR = (uint32_t)_pkt_scratch;
2473 NRF_CCM->SCRATCHPTR = (uint32_t)_ccm_scratch;
2474 NRF_CCM->SHORTS = CCM_SHORTS_ENDKSGEN_CRYPT_Msk;
2475
2476 nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ENDKSGEN);
2477 nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_END);
2478 nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ERROR);
2479
2480 nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_KSGEN);
2481 #endif /* !CONFIG_SOC_COMPATIBLE_NRF54LX */
2482
2483 return _pkt_scratch;
2484 }
2485
radio_ccm_tx_pkt_set(struct ccm * cnf,void * pkt)2486 void *radio_ccm_tx_pkt_set(struct ccm *cnf, void *pkt)
2487 {
2488 return radio_ccm_ext_tx_pkt_set(cnf, RADIO_PKT_CONF_PDU_TYPE_DC, pkt);
2489 }
2490
radio_ccm_iso_tx_pkt_set(struct ccm * cnf,uint8_t pdu_type,void * pkt)2491 void *radio_ccm_iso_tx_pkt_set(struct ccm *cnf, uint8_t pdu_type, void *pkt)
2492 {
2493 return radio_ccm_ext_tx_pkt_set(cnf, pdu_type, pkt);
2494 }
2495 #endif /* CONFIG_BT_CTLR_LE_ENC || CONFIG_BT_CTLR_ADV_ISO */
2496
radio_ccm_is_done(void)2497 uint32_t radio_ccm_is_done(void)
2498 {
2499 nrf_ccm_int_enable(NRF_CCM, CCM_INTENSET_ENDCRYPT_Msk);
2500 while (NRF_CCM->EVENTS_ENDCRYPT == 0) {
2501 cpu_sleep();
2502 }
2503 nrf_ccm_int_disable(NRF_CCM, CCM_INTENCLR_ENDCRYPT_Msk);
2504 NVIC_ClearPendingIRQ(nrfx_get_irq_number(NRF_CCM));
2505
2506 return (NRF_CCM->EVENTS_ERROR == 0);
2507 }
2508
radio_ccm_mic_is_valid(void)2509 uint32_t radio_ccm_mic_is_valid(void)
2510 {
2511 return (NRF_CCM->MICSTATUS != 0);
2512 }
2513
2514 #if defined(CONFIG_BT_CTLR_PRIVACY)
2515 static uint8_t MALIGN(4) _aar_scratch[3];
2516
radio_ar_configure(uint32_t nirk,void * irk,uint8_t flags)2517 void radio_ar_configure(uint32_t nirk, void *irk, uint8_t flags)
2518 {
2519 uint32_t addrptr;
2520 uint8_t bcc;
2521 uint8_t phy;
2522
2523 /* Flags provide hint on how to setup AAR:
2524 * ....Xb - legacy PDU
2525 * ...X.b - extended PDU
2526 * XXX..b = RX PHY
2527 * 00000b = default case mapped to 00101b (legacy, 1M)
2528 *
2529 * If neither legacy not extended bit is set, legacy PDU is selected for
2530 * 1M PHY and extended PDU otherwise.
2531 */
2532
2533 phy = flags >> 2;
2534
2535 /* Check if extended PDU or non-1M and not legacy PDU */
2536 if (IS_ENABLED(CONFIG_BT_CTLR_ADV_EXT) &&
2537 ((flags & BIT(1)) || (!(flags & BIT(0)) && (phy > PHY_1M)))) {
2538 addrptr = NRF_RADIO->PACKETPTR + 1;
2539 bcc = 80;
2540 } else {
2541 addrptr = NRF_RADIO->PACKETPTR - 1;
2542 bcc = 64;
2543 }
2544
2545 /* For Coded PHY adjust for CI and TERM1 */
2546 if (IS_ENABLED(CONFIG_BT_CTLR_PHY_CODED) && (phy == PHY_CODED)) {
2547 bcc += 5;
2548 }
2549
2550 NRF_AAR->ENABLE = (AAR_ENABLE_ENABLE_Enabled << AAR_ENABLE_ENABLE_Pos) &
2551 AAR_ENABLE_ENABLE_Msk;
2552 NRF_AAR->NIRK = nirk;
2553 NRF_AAR->IRKPTR = (uint32_t)irk;
2554 NRF_AAR->ADDRPTR = addrptr;
2555 NRF_AAR->SCRATCHPTR = (uint32_t)&_aar_scratch[0];
2556
2557 nrf_aar_event_clear(NRF_AAR, NRF_AAR_EVENT_END);
2558 nrf_aar_event_clear(NRF_AAR, NRF_AAR_EVENT_RESOLVED);
2559 nrf_aar_event_clear(NRF_AAR, NRF_AAR_EVENT_NOTRESOLVED);
2560
2561 radio_bc_configure(bcc);
2562 radio_bc_status_reset();
2563
2564 hal_trigger_aar_ppi_config();
2565 hal_radio_nrf_ppi_channels_enable(BIT(HAL_TRIGGER_AAR_PPI));
2566 }
2567
radio_ar_match_get(void)2568 uint32_t radio_ar_match_get(void)
2569 {
2570 return NRF_AAR->STATUS;
2571 }
2572
radio_ar_status_reset(void)2573 void radio_ar_status_reset(void)
2574 {
2575 radio_bc_status_reset();
2576
2577 NRF_AAR->ENABLE = (AAR_ENABLE_ENABLE_Disabled << AAR_ENABLE_ENABLE_Pos) &
2578 AAR_ENABLE_ENABLE_Msk;
2579
2580 hal_radio_nrf_ppi_channels_disable(BIT(HAL_TRIGGER_AAR_PPI));
2581 }
2582
radio_ar_has_match(void)2583 uint32_t radio_ar_has_match(void)
2584 {
2585 if (!radio_bc_has_match()) {
2586 return 0U;
2587 }
2588
2589 nrf_aar_int_enable(NRF_AAR, AAR_INTENSET_END_Msk);
2590
2591 while (NRF_AAR->EVENTS_END == 0U) {
2592 cpu_sleep();
2593 }
2594
2595 nrf_aar_int_disable(NRF_AAR, AAR_INTENCLR_END_Msk);
2596
2597 NVIC_ClearPendingIRQ(nrfx_get_irq_number(NRF_AAR));
2598
2599 if (NRF_AAR->EVENTS_RESOLVED && !NRF_AAR->EVENTS_NOTRESOLVED) {
2600 return 1U;
2601 }
2602
2603 return 0U;
2604 }
2605
radio_ar_resolve(const uint8_t * addr)2606 uint8_t radio_ar_resolve(const uint8_t *addr)
2607 {
2608 uint8_t retval;
2609
2610 NRF_AAR->ENABLE = (AAR_ENABLE_ENABLE_Enabled << AAR_ENABLE_ENABLE_Pos) &
2611 AAR_ENABLE_ENABLE_Msk;
2612
2613 NRF_AAR->ADDRPTR = (uint32_t)addr - 3;
2614
2615 nrf_aar_event_clear(NRF_AAR, NRF_AAR_EVENT_END);
2616 nrf_aar_event_clear(NRF_AAR, NRF_AAR_EVENT_RESOLVED);
2617 nrf_aar_event_clear(NRF_AAR, NRF_AAR_EVENT_NOTRESOLVED);
2618
2619 NVIC_ClearPendingIRQ(nrfx_get_irq_number(NRF_AAR));
2620
2621 nrf_aar_int_enable(NRF_AAR, AAR_INTENSET_END_Msk);
2622
2623 nrf_aar_task_trigger(NRF_AAR, NRF_AAR_TASK_START);
2624
2625 while (NRF_AAR->EVENTS_END == 0) {
2626 cpu_sleep();
2627 }
2628
2629 nrf_aar_int_disable(NRF_AAR, AAR_INTENCLR_END_Msk);
2630
2631 NVIC_ClearPendingIRQ(nrfx_get_irq_number(NRF_AAR));
2632
2633 retval = (NRF_AAR->EVENTS_RESOLVED && !NRF_AAR->EVENTS_NOTRESOLVED) ?
2634 1U : 0U;
2635
2636 NRF_AAR->ENABLE = (AAR_ENABLE_ENABLE_Disabled << AAR_ENABLE_ENABLE_Pos) &
2637 AAR_ENABLE_ENABLE_Msk;
2638
2639 return retval;
2640
2641 }
2642 #endif /* CONFIG_BT_CTLR_PRIVACY */
2643 #endif /* CONFIG_BT_CTLR_LE_ENC || CONFIG_BT_CTLR_BROADCAST_ISO_ENC */
2644
2645 #if defined(CONFIG_BT_CTLR_DF_SUPPORT) && !defined(CONFIG_ZTEST)
2646 /* @brief Function configures CTE inline register to start sampling of CTE
2647 * according to information parsed from CTEInfo field of received PDU.
2648 *
2649 * @param[in] cte_info_in_s1 Informs where to expect CTEInfo field in PDU:
2650 * in S1 for data pdu, not in S1 for adv. PDU
2651 */
radio_df_cte_inline_set_enabled(bool cte_info_in_s1)2652 void radio_df_cte_inline_set_enabled(bool cte_info_in_s1)
2653 {
2654 const nrf_radio_cteinline_conf_t inline_conf = {
2655 .enable = true,
2656 /* Indicates whether CTEInfo is in S1 byte or not. */
2657 .info_in_s1 = cte_info_in_s1,
2658 /* Enable or disable switching and sampling when CRC is not OK. */
2659 #if defined(CONFIG_BT_CTLR_DF_SAMPLE_CTE_FOR_PDU_WITH_BAD_CRC)
2660 .err_handling = true,
2661 #else
2662 .err_handling = false,
2663 #endif /* CONFIG_BT_CTLR_DF_SAMPLE_CTE_FOR_PDU_WITH_BAD_CRC */
2664 /* Maximum range of CTE time. 20 * 8us according to BT spec.*/
2665 .time_range = NRF_RADIO_CTEINLINE_TIME_RANGE_20,
2666 /* Spacing between samples for 1us AoD or AoA is set to 2us. */
2667 .rx1us = NRF_RADIO_CTEINLINE_RX_MODE_2US,
2668 /* Spacing between samples for 2us AoD or AoA is set to 4us. */
2669 .rx2us = NRF_RADIO_CTEINLINE_RX_MODE_4US,
2670 /* S0 bit pattern to match all types of adv. PDUs or CP bit in conn PDU*/
2671 .s0_pattern = (cte_info_in_s1 ? DF_S0_MASK_CP_BIT_IN_DATA_CHANNEL_PDU :
2672 DF_S0_ALLOW_ALL_PER_ADV_PDU),
2673 /* S0 bit mask set to don't match any bit in SO octet or match CP bit in conn PDU */
2674 .s0_mask = (cte_info_in_s1 ? DF_S0_MASK_CP_BIT_IN_DATA_CHANNEL_PDU :
2675 DF_S0_ALLOW_ALL_PER_ADV_PDU)
2676 };
2677
2678 nrf_radio_cteinline_configure(NRF_RADIO, &inline_conf);
2679 }
2680 #endif /* CONFIG_BT_CTLR_DF_SUPPORT && !CONFIG_ZTEST */
2681