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