diff --git a/drivers/flash/Kconfig.nrf b/drivers/flash/Kconfig.nrf index 39800a0627e4..63e300ed9ff3 100644 --- a/drivers/flash/Kconfig.nrf +++ b/drivers/flash/Kconfig.nrf @@ -41,7 +41,7 @@ choice SOC_FLASH_NRF_RADIO_SYNC_CHOICE config SOC_FLASH_NRF_RADIO_SYNC_TICKER bool "Nordic nRFx flash driver synchronized with radio" - depends on BT_LL_SW_SPLIT + depends on BT_LL_SW_SPLIT && !SOC_SERIES_NRF54HX help Enable synchronization between flash memory driver and radio using Bluetooth LE LL controller ticker API. diff --git a/drivers/flash/Kconfig.nrf_rram b/drivers/flash/Kconfig.nrf_rram index d8a5abf64b2e..986686bd5eca 100644 --- a/drivers/flash/Kconfig.nrf_rram +++ b/drivers/flash/Kconfig.nrf_rram @@ -47,7 +47,7 @@ choice SOC_FLASH_NRF_RADIO_SYNC_CHOICE config SOC_FLASH_NRF_RADIO_SYNC_TICKER bool "Nordic nRFx flash driver synchronized with radio" - depends on BT_LL_SW_SPLIT + depends on BT_LL_SW_SPLIT && !SOC_SERIES_NRF54HX help Enable synchronization between flash memory driver and radio using Bluetooth LE LL controller ticker API. diff --git a/dts/vendor/nordic/nrf54h20.dtsi b/dts/vendor/nordic/nrf54h20.dtsi index 5c445b9d5c75..615e9b7a26b6 100644 --- a/dts/vendor/nordic/nrf54h20.dtsi +++ b/dts/vendor/nordic/nrf54h20.dtsi @@ -136,6 +136,7 @@ min-residency-us = <700>; exit-latency-us = <5>; }; + idle_cache_disabled: idle_cache_disabled { compatible = "zephyr,power-state"; power-state-name = "suspend-to-idle"; @@ -500,6 +501,7 @@ compatible = "nordic,bt-hci-sdc"; status = "disabled"; }; + bt_hci_controller: bt_hci_controller { compatible = "zephyr,bt-hci-ll-sw-split"; status = "disabled"; diff --git a/subsys/bluetooth/controller/Kconfig.ll_sw_split b/subsys/bluetooth/controller/Kconfig.ll_sw_split index 744727eb11f3..f74983470c91 100644 --- a/subsys/bluetooth/controller/Kconfig.ll_sw_split +++ b/subsys/bluetooth/controller/Kconfig.ll_sw_split @@ -1,6 +1,6 @@ # Zephyr Bluetooth Controller configuration options -# Copyright (c) 2016-2017 Nordic Semiconductor ASA +# Copyright (c) 2016-2025 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 if BT_LL_SW_SPLIT @@ -10,14 +10,15 @@ config BT_LLL_VENDOR_NORDIC depends on SOC_COMPATIBLE_NRF depends on !$(dt_nodelabel_enabled,timer0) depends on !$(dt_nodelabel_enabled,rtc0) - - select BT_CTLR_ENTROPY_SUPPORT - select ENTROPY_NRF5_RNG if BT_CTLR_ENTROPY && !SOC_COMPATIBLE_NRF54LX + select CLOCK_CONTROL + select ENTROPY_NRF5_RNG if BT_CTLR_ENTROPY && \ + !SOC_COMPATIBLE_NRF54LX && \ + !SOC_SERIES_NRF54HX select ENTROPY_NRF5_BIAS_CORRECTION if ENTROPY_NRF5_RNG select EXPERIMENTAL if !ENTROPY_HAS_DRIVER - select BT_HAS_HCI_VS select BT_HCI_VS_FATAL_ERROR_SUPPORT + select BT_CTLR_ENTROPY_SUPPORT select BT_CTLR_CRYPTO_SUPPORT select BT_CTLR_LE_ENC_SUPPORT if BT_CTLR_CRYPTO_SUPPORT && \ !BT_CTLR_DATA_LENGTH_CLEAR && \ @@ -30,6 +31,7 @@ config BT_LLL_VENDOR_NORDIC select BT_CTLR_DATA_LEN_UPDATE_SUPPORT if !BT_CTLR_LE_ENC_SUPPORT || \ HAS_HW_NRF_CCM_LFLEN_8BIT || \ SOC_COMPATIBLE_NRF54LX || \ + SOC_SERIES_NRF54HX || \ BT_CTLR_DATA_LENGTH_CLEAR select BT_CTLR_EXT_SCAN_FP_SUPPORT select BT_CTLR_PHY_2M_SUPPORT if HAS_HW_NRF_RADIO_BLE_2M || \ @@ -54,24 +56,21 @@ config BT_LLL_VENDOR_NORDIC select BT_CTLR_SYNC_TRANSFER_SENDER_SUPPORT select BT_CTLR_DTM_HCI_SUPPORT select BT_CTLR_CONN_RSSI_SUPPORT - select BT_CTLR_XTAL_ADVANCED_SUPPORT select BT_CTLR_SCHED_ADVANCED_SUPPORT select BT_CTLR_TIFS_HW_SUPPORT select BT_CTLR_ULL_LLL_PRIO_SUPPORT - - select BT_TICKER_REMAINDER_SUPPORT if !SOC_COMPATIBLE_NRF54LX + select BT_CTLR_ASSERT_OPTIMIZE_FOR_SIZE_SUPPORT if CPU_CORTEX_M select BT_TICKER_UPDATE if BT_BROADCASTER || BT_CONN || \ (BT_OBSERVER && BT_CTLR_ADV_EXT) - select BT_TICKER_START_REMAINDER if BT_TICKER_REMAINDER_SUPPORT && BT_CTLR_CENTRAL_ISO + select BT_TICKER_REMAINDER_SUPPORT if !BT_CTLR_NRF_GRTC + select BT_TICKER_START_REMAINDER if BT_TICKER_REMAINDER_SUPPORT && \ + BT_CTLR_CENTRAL_ISO select BT_TICKER_REMAINDER_GET if BT_TICKER_REMAINDER_SUPPORT && \ (BT_BROADCASTER && BT_CTLR_ADV_EXT) - select BT_TICKER_LAZY_GET if BT_CTLR_ADV_PERIODIC || BT_CTLR_CONN_ISO || BT_CTLR_SYNC_TRANSFER_SENDER - + select BT_TICKER_LAZY_GET if BT_CTLR_ADV_PERIODIC || BT_CTLR_CONN_ISO || \ + BT_CTLR_SYNC_TRANSFER_SENDER select BT_TICKER_PREFER_START_BEFORE_STOP if BT_TICKER_SLOT_AGNOSTIC - - select BT_CTLR_ASSERT_OPTIMIZE_FOR_SIZE_SUPPORT if CPU_CORTEX_M - default y help Use Nordic Lower Link Layer implementation. @@ -79,7 +78,6 @@ config BT_LLL_VENDOR_NORDIC config BT_LLL_VENDOR_OPENISA bool "Use OpenISA LLL" depends on SOC_OPENISA_RV32M1 - select BT_HAS_HCI_VS select BT_CTLR_ENTROPY_SUPPORT select BT_CTLR_CRYPTO_SUPPORT @@ -88,10 +86,8 @@ config BT_LLL_VENDOR_OPENISA select BT_CTLR_PRIVACY_SUPPORT if BT_CTLR_CRYPTO_SUPPORT select BT_CTLR_PHY_UPDATE_SUPPORT select BT_CTLR_EXT_REJ_IND_SUPPORT - select BT_TICKER_REMAINDER_SUPPORT select BT_TICKER_UPDATE if BT_BROADCASTER || BT_CONN - default y help Use OpenISA Lower Link Layer implementation. @@ -942,7 +938,7 @@ config BT_CTLR_RX_PDU_META config BT_CTLR_NRF_GRTC bool "Use nRF GRTC peripheral" - depends on SOC_COMPATIBLE_NRF54LX + depends on SOC_COMPATIBLE_NRF54LX || SOC_SERIES_NRF54HX select BT_TICKER_CNTR_FREE_RUNNING default y help @@ -974,7 +970,10 @@ config BT_CTLR_NRF_GRTC_AUTOEN_DEFAULT config BT_CTLR_RADIO_ENABLE_FAST bool "Use tTXEN/RXEN,FAST ramp-up" - depends on SOC_COMPATIBLE_NRF52X || SOC_COMPATIBLE_NRF53X || SOC_COMPATIBLE_NRF54LX + depends on SOC_COMPATIBLE_NRF52X || \ + SOC_COMPATIBLE_NRF53X || \ + SOC_COMPATIBLE_NRF54LX || \ + SOC_SERIES_NRF54HX select BT_CTLR_SW_SWITCH_SINGLE_TIMER if SOC_COMPATIBLE_NRF54LX default y help @@ -996,8 +995,10 @@ config BT_CTLR_TIFS_HW config BT_CTLR_SW_SWITCH_SINGLE_TIMER bool "Single TIMER tIFS Trx SW switching" - depends on (!BT_CTLR_TIFS_HW) && (SOC_COMPATIBLE_NRF52X || SOC_COMPATIBLE_NRF53X || \ - SOC_COMPATIBLE_NRF54LX) + depends on (!BT_CTLR_TIFS_HW) && (SOC_COMPATIBLE_NRF52X || \ + SOC_COMPATIBLE_NRF53X || \ + SOC_COMPATIBLE_NRF54LX || \ + SOC_SERIES_NRF54HX) help Implement the tIFS Trx SW switch with the same TIMER instance, as the one used for Bluetooth event timing. Requires diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/cntr.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/cntr.c index ba6487b53534..96d3e2ffac2e 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/cntr.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/cntr.c @@ -60,12 +60,18 @@ void cntr_init(void) * with ability to select/set IRQ group. * Shared interrupts is an option? It may add ISR latencies? */ +#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) NRF_GRTC->INTENSET1 = HAL_CNTR_GRTC_INTENSET_COMPARE_TICKER_Msk; if (IS_ENABLED(CONFIG_SOC_SERIES_BSIM_NRF54LX)) { extern void nhw_GRTC_regw_sideeffects_INTENSET(uint32_t inst, uint32_t n); nhw_GRTC_regw_sideeffects_INTENSET(0, 1); } +#elif defined(CONFIG_SOC_SERIES_NRF54HX) + NRF_GRTC->INTENSET6 = HAL_CNTR_GRTC_INTENSET_COMPARE_TICKER_Msk; +#else +#error "Unknown SoC." +#endif #if defined(CONFIG_BT_CTLR_NRF_GRTC_START) NRF_GRTC->MODE = ((GRTC_MODE_SYSCOUNTEREN_Enabled << diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ecb.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ecb.c index 38b70c491d7d..1ee3b8024818 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ecb.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/ecb.c @@ -22,6 +22,13 @@ #if defined(NRF54L_SERIES) #define NRF_ECB NRF_ECB00 #define ECB_IRQn ECB00_IRQn + +#elif defined(NRF54H_SERIES) +#define NRF_ECB NRF_ECB030 +#define ECB_IRQn ECB030_IRQn +#endif + +#if defined(NRF54L_SERIES) || defined(NRF54H_SERIES) #define ECB_INTENSET_ERRORECB_Msk ECB_INTENSET_ERROR_Msk #define ECB_INTENSET_ENDECB_Msk ECB_INTENSET_END_Msk #define TASKS_STARTECB TASKS_START @@ -49,7 +56,7 @@ struct ecb_param { uint8_t clear_text[16]; uint8_t cipher_text[16]; -#if defined(NRF54L_SERIES) +#if defined(NRF54L_SERIES) || defined(NRF54H_SERIES) struct ecb_job_ptr in[2]; struct ecb_job_ptr out[2]; #endif /* NRF54L_SERIES */ @@ -60,7 +67,7 @@ static void do_ecb(struct ecb_param *ep) do { nrf_ecb_task_trigger(NRF_ECB, NRF_ECB_TASK_STOPECB); -#if defined(NRF54L_SERIES) +#if defined(NRF54L_SERIES) || defined(NRF54H_SERIES) NRF_ECB->KEY.VALUE[3] = sys_get_be32(&ep->key[0]); NRF_ECB->KEY.VALUE[2] = sys_get_be32(&ep->key[4]); NRF_ECB->KEY.VALUE[1] = sys_get_be32(&ep->key[8]); @@ -153,7 +160,7 @@ void ecb_encrypt_nonblocking(struct ecb *e) } /* setup the encryption h/w */ -#if defined(NRF54L_SERIES) +#if defined(NRF54L_SERIES) || defined(NRF54H_SERIES) NRF_ECB->KEY.VALUE[3] = sys_get_be32(&e->in_key_be[0]); NRF_ECB->KEY.VALUE[2] = sys_get_be32(&e->in_key_be[4]); NRF_ECB->KEY.VALUE[1] = sys_get_be32(&e->in_key_be[8]); @@ -196,7 +203,7 @@ void ecb_encrypt_nonblocking(struct ecb *e) static void isr_ecb(const void *arg) { -#if defined(NRF54L_SERIES) +#if defined(NRF54L_SERIES) || defined(NRF54H_SERIES) struct ecb *e = (void *)((uint8_t *)NRF_ECB->ECBDATAPTR - sizeof(struct ecb)); #else /* !NRF54L_SERIES */ diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c index 7056f020bc28..ef1b416aa77c 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.c @@ -213,7 +213,7 @@ void radio_reset(void) hal_radio_sw_switch_ppi_group_setup(); #endif -#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) +#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) || defined(CONFIG_SOC_SERIES_NRF54HX) #if defined(CONFIG_BT_CTLR_TIFS_HW) NRF_RADIO->TIMING = (RADIO_TIMING_RU_Legacy << RADIO_TIMING_RU_Pos) & RADIO_TIMING_RU_Msk; @@ -221,7 +221,9 @@ void radio_reset(void) NRF_RADIO->TIMING = (RADIO_TIMING_RU_Fast << RADIO_TIMING_RU_Pos) & RADIO_TIMING_RU_Msk; #endif /* !CONFIG_BT_CTLR_TIFS_HW */ +#endif /* CONFIG_SOC_COMPATIBLE_NRF54LX || CONFIG_SOC_SERIES_NRF54HX */ +#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) #if defined(CONFIG_NRF_SYS_EVENT) (void)nrf_sys_event_request_global_constlat(); #else /* !CONFIG_NRF_SYS_EVENT */ @@ -293,7 +295,8 @@ void radio_phy_set(uint8_t phy, uint8_t flags) NRF_RADIO->MODE = (mode << RADIO_MODE_MODE_Pos) & RADIO_MODE_MODE_Msk; -#if !defined(CONFIG_SOC_SERIES_NRF51X) && !defined(CONFIG_SOC_COMPATIBLE_NRF54LX) +#if !defined(CONFIG_SOC_SERIES_NRF51X) && !defined(CONFIG_SOC_COMPATIBLE_NRF54LX) && \ + !defined(CONFIG_SOC_SERIES_NRF54HX) #if defined(CONFIG_BT_CTLR_RADIO_ENABLE_FAST) NRF_RADIO->MODECNF0 = ((RADIO_MODECNF0_DTX_Center << RADIO_MODECNF0_DTX_Pos) & @@ -311,7 +314,7 @@ void radio_phy_set(uint8_t phy, uint8_t flags) void radio_tx_power_set(int8_t power) { -#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) +#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) || defined(CONFIG_SOC_SERIES_NRF54HX) uint32_t value; value = hal_radio_tx_power_value(power); @@ -381,7 +384,7 @@ void radio_freq_chan_set(uint32_t chan) void radio_whiten_iv_set(uint32_t iv) { -#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) +#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) || defined(CONFIG_SOC_SERIES_NRF54HX) #if defined(RADIO_DATAWHITEIV_DATAWHITEIV_Msk) NRF_RADIO->DATAWHITEIV = HAL_RADIO_RESET_VALUE_DATAWHITE | iv; #else /* !RADIO_DATAWHITEIV_DATAWHITEIV_Msk */ @@ -428,7 +431,8 @@ void radio_pkt_configure(uint8_t bits_len, uint8_t max_len, uint8_t flags) #elif defined(CONFIG_SOC_COMPATIBLE_NRF52X) || \ defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET) || \ - defined(CONFIG_SOC_COMPATIBLE_NRF54LX) + defined(CONFIG_SOC_COMPATIBLE_NRF54LX) || \ + defined(CONFIG_SOC_SERIES_NRF54HX) extra = 0U; phy = RADIO_PKT_CONF_PHY_GET(flags); @@ -525,7 +529,8 @@ uint32_t radio_rx_chain_delay_get(uint8_t phy, uint8_t flags) void radio_rx_enable(void) { #if !defined(CONFIG_BT_CTLR_TIFS_HW) -#if defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX) +#if defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX) || \ + defined(CONFIG_SOC_SERIES_NRF54HX) /* NOTE: Timer clear DPPI configuration is needed only for nRF53 * because of calls to radio_disable() and * radio_switch_complete_and_disable() inside a radio event call @@ -547,7 +552,8 @@ void radio_rx_enable(void) void radio_tx_enable(void) { #if !defined(CONFIG_BT_CTLR_TIFS_HW) -#if defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX) +#if defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX) || \ + defined(CONFIG_SOC_SERIES_NRF54HX) /* NOTE: Timer clear DPPI configuration is needed only for nRF53 * because of calls to radio_disable() and * radio_switch_complete_and_disable() inside a radio event call @@ -939,7 +945,8 @@ void sw_switch(uint8_t dir_curr, uint8_t dir_next, uint8_t phy_curr, uint8_t fla * time-stamp. */ hal_radio_end_time_capture_ppi_config(); -#if !defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET) && !defined(CONFIG_SOC_COMPATIBLE_NRF54LX) +#if !defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET) && !defined(CONFIG_SOC_COMPATIBLE_NRF54LX) && \ + !defined(CONFIG_SOC_SERIES_NRF54HX) /* The function is not called for nRF5340 single timer configuration because * HAL_SW_SWITCH_TIMER_CLEAR_PPI is equal to HAL_RADIO_END_TIME_CAPTURE_PPI, * so channel is already enabled. @@ -1360,7 +1367,8 @@ void radio_tmr_rx_status_reset(void) void radio_tmr_tx_enable(void) { -#if defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX) +#if defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX) || \ + defined(CONFIG_SOC_SERIES_NRF54HX) #else /* !CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET && !CONFIG_SOC_COMPATIBLE_NRF54LX */ #if (HAL_RADIO_ENABLE_TX_ON_TICK_PPI == HAL_RADIO_ENABLE_RX_ON_TICK_PPI) hal_radio_enable_on_tick_ppi_config_and_enable(1U); @@ -1370,7 +1378,8 @@ void radio_tmr_tx_enable(void) void radio_tmr_rx_enable(void) { -#if defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX) +#if defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX) || \ + defined(CONFIG_SOC_SERIES_NRF54HX) #else /* !CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET && !CONFIG_SOC_COMPATIBLE_NRF54LX */ #if (HAL_RADIO_ENABLE_TX_ON_TICK_PPI == HAL_RADIO_ENABLE_RX_ON_TICK_PPI) hal_radio_enable_on_tick_ppi_config_and_enable(0U); @@ -1380,7 +1389,8 @@ void radio_tmr_rx_enable(void) void radio_tmr_tx_disable(void) { -#if defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX) +#if defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX) || \ + defined(CONFIG_SOC_SERIES_NRF54HX) nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_TXEN); #else /* !CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET && !CONFIG_SOC_COMPATIBLE_NRF54LX */ #endif /* !CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET && !CONFIG_SOC_COMPATIBLE_NRF54LX */ @@ -1388,7 +1398,8 @@ void radio_tmr_tx_disable(void) void radio_tmr_rx_disable(void) { -#if defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX) +#if defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX) || \ + defined(CONFIG_SOC_SERIES_NRF54HX) nrf_radio_subscribe_clear(NRF_RADIO, NRF_RADIO_TASK_RXEN); #else /* !CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET && !CONFIG_SOC_COMPATIBLE_NRF54LX */ #endif /* !CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET && !CONFIG_SOC_COMPATIBLE_NRF54LX */ @@ -1627,7 +1638,8 @@ uint32_t radio_tmr_start_tick(uint8_t trx, uint32_t ticks_start) #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) last_pdu_end_us_init(latency_us); #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ -#if defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX) +#if defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX) || \ + defined(CONFIG_SOC_SERIES_NRF54HX) /* NOTE: Timer clear DPPI configuration is needed only for nRF53 * because of calls to radio_disable() and * radio_switch_complete_and_disable() inside a radio event call @@ -1657,7 +1669,8 @@ uint32_t radio_tmr_start_us(uint8_t trx, uint32_t start_us) */ start_us -= last_pdu_end_us; #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ -#if defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX) +#if defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX) || \ + defined(CONFIG_SOC_SERIES_NRF54HX) /* NOTE: Timer clear DPPI configuration is needed only for nRF53 * because of calls to radio_disable() and * radio_switch_complete_and_disable() inside a radio event call @@ -1792,6 +1805,7 @@ void radio_tmr_stop(void) #endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ #endif /* !CONFIG_BT_CTLR_TIFS_HW */ +/* TODO: Check if this is needed for other SoCs like nRF54H20 */ #if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) #if defined(CONFIG_NRF_SYS_EVENT) (void)nrf_sys_event_release_global_constlat(); @@ -1876,9 +1890,12 @@ void radio_tmr_end_capture(void) * hal_sw_switch_timer_clear_ppi_config() and sw_switch(). There is no need to * configure the channel again in this function. */ -#if (!defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET) && !defined(CONFIG_SOC_COMPATIBLE_NRF54LX)) || \ +#if (!defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET) && \ + !defined(CONFIG_SOC_COMPATIBLE_NRF54LX) && \ + !defined(CONFIG_SOC_SERIES_NRF54HX)) || \ ((defined(CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET) || \ - defined(CONFIG_SOC_COMPATIBLE_NRF54LX)) && \ + defined(CONFIG_SOC_COMPATIBLE_NRF54LX) || \ + defined(CONFIG_SOC_SERIES_NRF54HX)) && \ !defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER)) hal_radio_end_time_capture_ppi_config(); hal_radio_nrf_ppi_channels_enable(BIT(HAL_RADIO_END_TIME_CAPTURE_PPI)); @@ -2073,7 +2090,7 @@ void radio_gpio_pa_lna_disable(void) #endif /* HAL_RADIO_GPIO_HAVE_PA_PIN || HAL_RADIO_GPIO_HAVE_LNA_PIN */ #if defined(CONFIG_BT_CTLR_LE_ENC) || defined(CONFIG_BT_CTLR_BROADCAST_ISO_ENC) -#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) +#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) || defined(CONFIG_SOC_SERIES_NRF54HX) struct ccm_job_ptr { void *ptr; struct { @@ -2115,7 +2132,7 @@ static void *radio_ccm_ext_rx_pkt_set(struct ccm *cnf, uint8_t phy, uint8_t pdu_ NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Enabled; /* Select the CCM decryption mode for the SoC */ -#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) +#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) || defined(CONFIG_SOC_SERIES_NRF54HX) /* NOTE: Use fast decryption as rx data is decrypt after payload is received, compared to * decrypting in parallel with radio reception of address in nRF51/nRF52/nRF53. */ @@ -2214,7 +2231,8 @@ static void *radio_ccm_ext_rx_pkt_set(struct ccm *cnf, uint8_t phy, uint8_t pdu_ NRF_CCM->MODE = mode; #if defined(CONFIG_HAS_HW_NRF_CCM_HEADERMASK) || \ - defined(CONFIG_SOC_COMPATIBLE_NRF54LX) + defined(CONFIG_SOC_COMPATIBLE_NRF54LX) || \ + defined(CONFIG_SOC_SERIES_NRF54HX) #if defined(CONFIG_HAS_HW_NRF_CCM_HEADERMASK) #define ADATAMASK HEADERMASK #endif /* CONFIG_HAS_HW_NRF_CCM_HEADERMASK */ @@ -2240,6 +2258,7 @@ static void *radio_ccm_ext_rx_pkt_set(struct ccm *cnf, uint8_t phy, uint8_t pdu_ #if !defined(CONFIG_SOC_SERIES_NRF51X) && \ !defined(CONFIG_SOC_NRF52832) && \ !defined(CONFIG_SOC_COMPATIBLE_NRF54LX) && \ + !defined(CONFIG_SOC_SERIES_NRF54HX) && \ (!defined(CONFIG_BT_CTLR_DATA_LENGTH_MAX) || \ (CONFIG_BT_CTLR_DATA_LENGTH_MAX < ((HAL_RADIO_PDU_LEN_MAX) - 4U))) const uint8_t max_len = (NRF_RADIO->PCNF1 & RADIO_PCNF1_MAXLEN_Msk) >> @@ -2249,7 +2268,7 @@ static void *radio_ccm_ext_rx_pkt_set(struct ccm *cnf, uint8_t phy, uint8_t pdu_ NRF_CCM->MAXPACKETSIZE = CLAMP((max_len - PDU_MIC_SIZE), 0x001B, 0x00FB); #endif -#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) +#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) || defined(CONFIG_SOC_SERIES_NRF54HX) /* Configure the CCM key, nonce and pointers */ NRF_CCM->KEY.VALUE[3] = sys_get_be32(&cnf->key[0]); NRF_CCM->KEY.VALUE[2] = sys_get_be32(&cnf->key[4]); @@ -2360,7 +2379,7 @@ static void *radio_ccm_ext_tx_pkt_set(struct ccm *cnf, uint8_t pdu_type, void *p NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Enabled; /* Select the CCM encryption mode for the SoC */ -#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) +#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) || defined(CONFIG_SOC_SERIES_NRF54HX) mode = (CCM_MODE_MODE_Encryption << CCM_MODE_MODE_Pos) & CCM_MODE_MODE_Msk; @@ -2403,7 +2422,8 @@ static void *radio_ccm_ext_tx_pkt_set(struct ccm *cnf, uint8_t pdu_type, void *p NRF_CCM->MODE = mode; #if defined(CONFIG_HAS_HW_NRF_CCM_HEADERMASK) || \ - defined(CONFIG_SOC_COMPATIBLE_NRF54LX) + defined(CONFIG_SOC_COMPATIBLE_NRF54LX) || \ + defined(CONFIG_SOC_SERIES_NRF54HX) #if defined(CONFIG_HAS_HW_NRF_CCM_HEADERMASK) #define ADATAMASK HEADERMASK #endif /* CONFIG_HAS_HW_NRF_CCM_HEADERMASK */ @@ -2429,6 +2449,7 @@ static void *radio_ccm_ext_tx_pkt_set(struct ccm *cnf, uint8_t pdu_type, void *p #if !defined(CONFIG_SOC_SERIES_NRF51X) && \ !defined(CONFIG_SOC_NRF52832) && \ !defined(CONFIG_SOC_COMPATIBLE_NRF54LX) && \ + !defined(CONFIG_SOC_SERIES_NRF54HX) && \ (!defined(CONFIG_BT_CTLR_DATA_LENGTH_MAX) || \ (CONFIG_BT_CTLR_DATA_LENGTH_MAX < ((HAL_RADIO_PDU_LEN_MAX) - 4U))) const uint8_t max_len = (NRF_RADIO->PCNF1 & RADIO_PCNF1_MAXLEN_Msk) >> @@ -2438,7 +2459,7 @@ static void *radio_ccm_ext_tx_pkt_set(struct ccm *cnf, uint8_t pdu_type, void *p NRF_CCM->MAXPACKETSIZE = CLAMP((max_len - PDU_MIC_SIZE), 0x001B, 0x00FB); #endif -#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) +#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) || defined(CONFIG_SOC_SERIES_NRF54HX) /* Configure the CCM key, nonce and pointers */ NRF_CCM->KEY.VALUE[3] = sys_get_be32(&cnf->key[0]); NRF_CCM->KEY.VALUE[2] = sys_get_be32(&cnf->key[4]); @@ -2562,7 +2583,7 @@ void radio_ccm_disable(void) #endif /* CONFIG_BT_CTLR_LE_ENC || CONFIG_BT_CTLR_BROADCAST_ISO_ENC */ #if defined(CONFIG_BT_CTLR_PRIVACY) -#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) +#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) || defined(CONFIG_SOC_SERIES_NRF54HX) struct aar_job_ptr { void *ptr; struct { @@ -2641,7 +2662,7 @@ void radio_ar_configure(uint32_t nirk, void *irk, uint8_t flags) NRF_AAR->ENABLE = (AAR_ENABLE_ENABLE_Enabled << AAR_ENABLE_ENABLE_Pos) & AAR_ENABLE_ENABLE_Msk; -#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) +#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) || defined(CONFIG_SOC_SERIES_NRF54HX) /* Input, Resolvable Address Hash offset in the legacy or extended advertising PDU. * Radio packet pointer offset by 3 compared to legacy AAR in nRF51/52/53 SoCs that took * Radio packet pointer value. @@ -2705,7 +2726,7 @@ void radio_ar_configure(uint32_t nirk, void *irk, uint8_t flags) uint32_t radio_ar_match_get(void) { -#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) +#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) || defined(CONFIG_SOC_SERIES_NRF54HX) return aar_job.status; #else /* !CONFIG_SOC_COMPATIBLE_NRF54LX */ return NRF_AAR->STATUS; @@ -2752,7 +2773,7 @@ uint8_t radio_ar_resolve(const uint8_t *addr) NRF_AAR->ENABLE = (AAR_ENABLE_ENABLE_Enabled << AAR_ENABLE_ENABLE_Pos) & AAR_ENABLE_ENABLE_Msk; -#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) +#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) || defined(CONFIG_SOC_SERIES_NRF54HX) /* Input, Resolvable Address Hash offset in the supplied address buffer */ aar_job.in[0].ptr = (void *)&addr[BDADDR_HASH_OFFSET]; diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h index 1b15f41c4080..a33cf71bac90 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5.h @@ -42,6 +42,10 @@ #elif defined(CONFIG_SOC_SERIES_NRF54LX) #include #include "radio_nrf54lx.h" +#elif defined(CONFIG_SOC_SERIES_NRF54HX) +#include +#include +#include "radio_nrf54hx.h" #elif defined(CONFIG_BOARD_NRF52_BSIM) #include "radio_sim_nrf52.h" #elif defined(CONFIG_BOARD_NRF5340BSIM_NRF5340_CPUNET) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf54hx.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf54hx.h new file mode 100644 index 000000000000..7c6436c8582c --- /dev/null +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf54hx.h @@ -0,0 +1,761 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#undef EVENT_TIMER_ID +#define EVENT_TIMER_ID 020 + +#undef EVENT_TIMER +#define EVENT_TIMER _CONCAT(NRF_TIMER, EVENT_TIMER_ID) + +#if !defined(CONFIG_BT_CTLR_TIFS_HW) +#undef SW_SWITCH_TIMER +#if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) +#define SW_SWITCH_TIMER EVENT_TIMER +#else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ +#define SW_SWITCH_TIMER NRF_TIMER021 +#endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ +#endif /* !CONFIG_BT_CTLR_TIFS_HW */ + +/* HAL abstraction of event timer prescaler value */ +#define HAL_EVENT_TIMER_PRESCALER_VALUE 5U + +/* NRF Radio HW timing constants + * - provided in US and NS (for higher granularity) + * - based on empirical measurements and sniffer logs + */ + +/* TXEN->TXIDLE + TXIDLE->TX (with fast Radio ramp-up mode) + * in microseconds for LE 1M PHY. + */ +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_1M_FAST_NS 40900 /*40.1 + 0.8 */ +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_1M_FAST_US \ + HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_1M_FAST_NS) + +/* TXEN->TXIDLE + TXIDLE->TX (with default Radio ramp-up mode) + * in microseconds for LE 1M PHY. + */ +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_1M_DEFAULT_NS 140900 /*140.1 + 0.8 */ +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_1M_DEFAULT_US \ + HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_1M_DEFAULT_NS) + +/* TXEN->TXIDLE + TXIDLE->TX (with default Radio ramp-up mode + * and no HW TIFS auto-switch) in microseconds for LE 1M PHY. + */ + /* 129.5 + 0.8 */ +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_1M_DEFAULT_NO_HW_TIFS_NS 130300 +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_1M_DEFAULT_NO_HW_TIFS_US \ + HAL_RADIO_NS2US_ROUND( \ + HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_1M_DEFAULT_NO_HW_TIFS_NS) + +/* TXEN->TXIDLE + TXIDLE->TX (with fast Radio ramp-up mode) + * in microseconds for LE 2M PHY. + */ +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_2M_FAST_NS 40000 /* 40.1 - 0.1 */ +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_2M_FAST_US \ + HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_2M_FAST_NS) + +/* TXEN->TXIDLE + TXIDLE->TX (with default Radio ramp-up mode) + * in microseconds for LE 2M PHY. + */ +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_2M_DEFAULT_NS 144900 /* 145 - 0.1 */ +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_2M_DEFAULT_US \ + HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_2M_DEFAULT_NS) + +/* TXEN->TXIDLE + TXIDLE->TX (with default Radio ramp-up mode and + * no HW TIFS auto-switch) in microseconds for LE 2M PHY. + */ +/* 129.5 - 0.1 */ +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_2M_DEFAULT_NO_HW_TIFS_NS 129400 +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_2M_DEFAULT_NO_HW_TIFS_US \ + HAL_RADIO_NS2US_ROUND( \ + HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_2M_DEFAULT_NO_HW_TIFS_NS) + +/* TXEN->TXIDLE + TXIDLE->TX (with fast Radio ramp-up mode) + * in microseconds for LE CODED PHY [S2]. + */ +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S2_FAST_NS 42300 /* 40.1 + 2.2 */ +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S2_FAST_US \ + HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S2_FAST_NS) + +/* TXEN->TXIDLE + TXIDLE->TX (with default Radio ramp-up mode) + * in microseconds for LE 2M PHY [S2]. + */ +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S2_DEFAULT_NS 132200 /* 130 + 2.2 */ +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S2_DEFAULT_US \ + HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S2_DEFAULT_NS) + +/* TXEN->TXIDLE + TXIDLE->TX (with default Radio ramp-up mode and + * no HW TIFS auto-switch) in microseconds for LE 2M PHY [S2]. + */ +/* 129.5 + 2.2 */ +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S2_DEFAULT_NO_HW_TIFS_NS 131700 +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S2_DEFAULT_NO_HW_TIFS_US \ + HAL_RADIO_NS2US_ROUND( \ + HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S2_DEFAULT_NO_HW_TIFS_NS) + +/* TXEN->TXIDLE + TXIDLE->TX (with fast Radio ramp-up mode) + * in microseconds for LE CODED PHY [S8]. + */ +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S8_FAST_NS 42300 /* 40.1 + 2.2 */ +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S8_FAST_US \ + HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S8_FAST_NS) +/* TXEN->TXIDLE + TXIDLE->TX (with default Radio ramp-up mode) + * in microseconds for LE 2M PHY [S8]. + */ +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S8_DEFAULT_NS 121800 /*119.6 + 2.2 */ +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S8_DEFAULT_US \ + HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S8_DEFAULT_NS) + +/* TXEN->TXIDLE + TXIDLE->TX (with default Radio ramp-up mode and + * no HW TIFS auto-switch) in microseconds for LE 2M PHY [S8]. + */ + /* 129.5 + 2.2 */ +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S8_DEFAULT_NO_HW_TIFS_NS 131700 +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S8_DEFAULT_NO_HW_TIFS_US \ + HAL_RADIO_NS2US_ROUND( \ + HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S8_DEFAULT_NO_HW_TIFS_NS) + +/* RXEN->RXIDLE + RXIDLE->RX (with fast Radio ramp-up mode) + * in microseconds for LE 1M PHY. + */ +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_1M_FAST_NS 40300 /* 40.1 + 0.2 */ +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_1M_FAST_US \ + HAL_RADIO_NS2US_CEIL(HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_1M_FAST_NS) + +/* RXEN->RXIDLE + RXIDLE->RX (with default Radio ramp-up mode) + * in microseconds for LE 1M PHY. + */ +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_1M_DEFAULT_NS 140300 /*140.1 + 0.2 */ +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_1M_DEFAULT_US \ + HAL_RADIO_NS2US_CEIL(HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_1M_DEFAULT_NS) + +/* RXEN->RXIDLE + RXIDLE->RX (with default Radio ramp-up mode and + * no HW TIFS auto-switch) in microseconds for LE 1M PHY. + */ +/* 129.5 + 0.2 */ +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_1M_DEFAULT_NO_HW_TIFS_NS 129700 +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_1M_DEFAULT_NO_HW_TIFS_US \ + HAL_RADIO_NS2US_CEIL( \ + HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_1M_DEFAULT_NO_HW_TIFS_NS) + +/* RXEN->RXIDLE + RXIDLE->RX (with fast Radio ramp-up mode) + * in microseconds for LE 2M PHY. + */ +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_2M_FAST_NS 40300 /* 40.1 + 0.2 */ +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_2M_FAST_US \ + HAL_RADIO_NS2US_CEIL(HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_2M_FAST_NS) + +/* RXEN->RXIDLE + RXIDLE->RX (with default Radio ramp-up mode) + * in microseconds for LE 2M PHY. + */ +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_2M_DEFAULT_NS 144800 /*144.6 + 0.2 */ +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_2M_DEFAULT_US \ + HAL_RADIO_NS2US_CEIL(HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_2M_DEFAULT_NS) + +/* RXEN->RXIDLE + RXIDLE->RX (with default Radio ramp-up mode and + * no HW TIFS auto-switch) in microseconds for LE 2M PHY. + */ +/* 129.5 + 0.2 */ +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_2M_DEFAULT_NO_HW_TIFS_NS 129700 +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_2M_DEFAULT_NO_HW_TIFS_US \ + HAL_RADIO_NS2US_CEIL( \ + HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_2M_DEFAULT_NO_HW_TIFS_NS) + +/* RXEN->RXIDLE + RXIDLE->RX (with fast Radio ramp-up mode) + * in microseconds for LE Coded PHY [S2]. + */ +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S2_FAST_NS 40300 /* 40.1 + 0.2 */ +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S2_FAST_US \ + HAL_RADIO_NS2US_CEIL(HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S2_FAST_NS) + +/* RXEN->RXIDLE + RXIDLE->RX (with default Radio ramp-up mode) + * in microseconds for LE Coded PHY [S2]. + */ +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S2_DEFAULT_NS 130200 /* 130 + 0.2 */ +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S2_DEFAULT_US \ + HAL_RADIO_NS2US_CEIL(HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S2_DEFAULT_NS) + +/* RXEN->RXIDLE + RXIDLE->RX (with default Radio ramp-up mode + * and no HW TIFS auto-switch) in microseconds for LE Coded PHY [S2]. + */ +/* 129.5 + 0.2 */ +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S2_DEFAULT_NO_HW_TIFS_NS 129700 +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S2_DEFAULT_NO_HW_TIFS_US \ + HAL_RADIO_NS2US_CEIL( \ + HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S2_DEFAULT_NO_HW_TIFS_NS) + +/* RXEN->RXIDLE + RXIDLE->RX (with fast Radio ramp-up mode) + * in microseconds for LE Coded PHY [S8]. + */ +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S8_FAST_NS 40300 /* 40.1 + 0.2 */ +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S8_FAST_US \ + HAL_RADIO_NS2US_CEIL(HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S8_FAST_NS) + +/* RXEN->RXIDLE + RXIDLE->RX (with default Radio ramp-up mode) + * in microseconds for LE Coded PHY [S8]. + */ +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S8_DEFAULT_NS 120200 /* 120.0 + 0.2 */ +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S8_DEFAULT_US \ + HAL_RADIO_NS2US_CEIL(HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S8_DEFAULT_NS) + +/* RXEN->RXIDLE + RXIDLE->RX (with default Radio ramp-up mode and + * no HW TIFS auto-switch) in microseconds for LE Coded PHY [S8]. + */ +/* 129.5 + 0.2 */ +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S8_DEFAULT_NO_HW_TIFS_NS 129700 +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S8_DEFAULT_NO_HW_TIFS_US \ + HAL_RADIO_NS2US_CEIL( \ + HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S8_DEFAULT_NO_HW_TIFS_NS) + +#define HAL_RADIO_NRF54HX_TX_CHAIN_DELAY_1M_US 1 /* ceil(0.6) */ +#define HAL_RADIO_NRF54HX_TX_CHAIN_DELAY_1M_NS 600 /* 0.6 */ +#define HAL_RADIO_NRF54HX_TX_CHAIN_DELAY_2M_US 1 /* ceil(0.6) */ +#define HAL_RADIO_NRF54HX_TX_CHAIN_DELAY_2M_NS 600 /* 0.6 */ +#define HAL_RADIO_NRF54HX_TX_CHAIN_DELAY_S2_US 1 /* ceil(0.6) */ +#define HAL_RADIO_NRF54HX_TX_CHAIN_DELAY_S2_NS 600 /* 0.6 */ +#define HAL_RADIO_NRF54HX_TX_CHAIN_DELAY_S8_US 1 /* ceil(0.6) */ +#define HAL_RADIO_NRF54HX_TX_CHAIN_DELAY_S8_NS 600 /* 0.6 */ + +#define HAL_RADIO_NRF54HX_RX_CHAIN_DELAY_1M_US 10 /* ceil(9.4) */ +#define HAL_RADIO_NRF54HX_RX_CHAIN_DELAY_1M_NS 9400 /* 9.4 */ +#define HAL_RADIO_NRF54HX_RX_CHAIN_DELAY_2M_US 5 /* ceil(5.0) */ +#define HAL_RADIO_NRF54HX_RX_CHAIN_DELAY_2M_NS 5000 /* 5.0 */ +#define HAL_RADIO_NRF54HX_RX_CHAIN_DELAY_S2_US 25 /* ceil(19.6) */ +#define HAL_RADIO_NRF54HX_RX_CHAIN_DELAY_S2_NS 24600 /* 19.6 */ +#define HAL_RADIO_NRF54HX_RX_CHAIN_DELAY_S8_US 30 /* ceil(29.6) */ +#define HAL_RADIO_NRF54HX_RX_CHAIN_DELAY_S8_NS 29600 /* 29.6 */ + +#if defined(CONFIG_BT_CTLR_RADIO_ENABLE_FAST) +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_1M_US \ + HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_1M_FAST_US +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_1M_NS \ + HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_1M_FAST_NS + +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_2M_US \ + HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_2M_FAST_US +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_2M_NS \ + HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_2M_FAST_NS + +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S2_US \ + HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S2_FAST_US +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S2_NS \ + HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S2_FAST_NS + +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S8_US \ + HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S8_FAST_US +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S8_NS \ + HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S8_FAST_NS + +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_1M_US \ + HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_1M_FAST_US +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_1M_NS \ + HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_1M_FAST_NS + +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_2M_US \ + HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_2M_FAST_US +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_2M_NS \ + HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_2M_FAST_NS + +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S2_US \ + HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S2_FAST_US +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S2_NS \ + HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S2_FAST_NS + +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S8_US \ + HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S8_FAST_US +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S8_NS \ + HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S8_FAST_NS + +#else /* !CONFIG_BT_CTLR_RADIO_ENABLE_FAST */ +#if defined(CONFIG_BT_CTLR_TIFS_HW) +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_1M_US \ + HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_1M_DEFAULT_US +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_1M_NS \ + HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_1M_DEFAULT_NS + +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_2M_US \ + HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_2M_DEFAULT_US +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_2M_NS \ + HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_2M_DEFAULT_NS + +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S2_US \ + HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S2_DEFAULT_US +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S2_NS \ + HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S2_DEFAULT_NS + +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S8_US \ + HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S8_DEFAULT_US +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S8_NS \ + HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S8_DEFAULT_NS + +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_1M_US \ + HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_1M_DEFAULT_US +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_1M_NS \ + HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_1M_DEFAULT_NS + +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_2M_US \ + HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_2M_DEFAULT_US +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_2M_NS \ + HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_2M_DEFAULT_NS + +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S2_US \ + HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S2_DEFAULT_US +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S2_NS \ + HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S2_DEFAULT_NS + +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S8_US \ + HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S8_DEFAULT_US +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S8_NS \ + HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S8_DEFAULT_NS + +#else /* !CONFIG_BT_CTLR_TIFS_HW */ +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_1M_US \ + HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_1M_DEFAULT_NO_HW_TIFS_US +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_1M_NS \ + HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_1M_DEFAULT_NO_HW_TIFS_NS + +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_2M_US \ + HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_2M_DEFAULT_NO_HW_TIFS_US +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_2M_NS \ + HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_2M_DEFAULT_NO_HW_TIFS_NS + +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S2_US \ + HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S2_DEFAULT_NO_HW_TIFS_US +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S2_NS \ + HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S2_DEFAULT_NO_HW_TIFS_NS + +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S8_US \ + HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S8_DEFAULT_NO_HW_TIFS_US +#define HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S8_NS \ + HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S8_DEFAULT_NO_HW_TIFS_NS + +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_1M_US \ + HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_1M_DEFAULT_NO_HW_TIFS_US +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_1M_NS \ + HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_1M_DEFAULT_NO_HW_TIFS_NS + +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_2M_US \ + HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_2M_DEFAULT_NO_HW_TIFS_US +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_2M_NS \ + HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_2M_DEFAULT_NO_HW_TIFS_NS + +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S2_US \ + HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S2_DEFAULT_NO_HW_TIFS_US +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S2_NS \ + HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S2_DEFAULT_NO_HW_TIFS_NS + +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S8_US \ + HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S8_DEFAULT_NO_HW_TIFS_US +#define HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S8_NS \ + HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S8_DEFAULT_NO_HW_TIFS_NS +#endif /* !CONFIG_BT_CTLR_TIFS_HW */ +#endif /* !CONFIG_BT_CTLR_RADIO_ENABLE_FAST */ + +/* HAL abstraction of Radio bitfields */ +#define HAL_NRF_RADIO_EVENT_END NRF_RADIO_EVENT_END +#define HAL_RADIO_EVENTS_END EVENTS_END +#define HAL_RADIO_PUBLISH_END PUBLISH_END +#define HAL_NRF_RADIO_EVENT_PHYEND NRF_RADIO_EVENT_PHYEND +#define HAL_RADIO_EVENTS_PHYEND EVENTS_PHYEND +#define HAL_RADIO_PUBLISH_PHYEND PUBLISH_PHYEND +#define HAL_RADIO_INTENSET_DISABLED_Msk RADIO_INTENSET00_DISABLED_Msk +#define HAL_RADIO_SHORTS_TRX_END_DISABLE_Msk RADIO_SHORTS_PHYEND_DISABLE_Msk +#define HAL_RADIO_SHORTS_TRX_PHYEND_DISABLE_Msk RADIO_SHORTS_PHYEND_DISABLE_Msk +#define HAL_RADIO_CLEARPATTERN_CLEARPATTERN_Clear (1UL) + +/* HAL abstraction of Radio IRQ number */ +#define HAL_RADIO_IRQn RADIO_0_IRQn + +/* SoC specific NRF_RADIO power-on reset value. Refer to Product Specification, + * RADIO Registers section for the documented reset values. + * + * NOTE: Only implementation used values defined here. + * In the future if MDK or nRFx header include these, use them instead. + */ +#define HAL_RADIO_RESET_VALUE_DFEMODE 0x00000000UL +#define HAL_RADIO_RESET_VALUE_CTEINLINECONF 0x00002800UL +#define HAL_RADIO_RESET_VALUE_DATAWHITE 0x00890040UL + +/* HAL abstraction of CCM h/w */ +#define NRF_CCM NRF_CCM030 +#define NRF_CCM_TASK_CRYPT NRF_CCM_TASK_START +#define EVENTS_ENDCRYPT EVENTS_END +#define INPTR IN.PTR +#define OUTPTR OUT.PTR +#define MICSTATUS MACSTATUS +#define CCM_INTENSET_ENDCRYPT_Msk CCM_INTENSET_END_Msk +#define CCM_INTENCLR_ENDCRYPT_Msk CCM_INTENCLR_END_Msk +#define CCM_MODE_DATARATE_125Kbps CCM_MODE_DATARATE_125Kbit +#define CCM_MODE_DATARATE_500Kbps CCM_MODE_DATARATE_500Kbit +#define CCM_RATEOVERRIDE_RATEOVERRIDE_500Kbps CCM_RATEOVERRIDE_RATEOVERRIDE_500Kbit + +/* HAL abstraction of AAR h/w */ +#define NRF_AAR NRF_AAR030 + +static inline void hal_radio_reset(void) +{ + /* TODO: Add any required setup for each radio event + */ + nrf_lrcconf_clock_always_run_force_set(NRF_LRCCONF000, 0, true); + nrf_lrcconf_task_trigger(NRF_LRCCONF000, NRF_LRCCONF_TASK_CLKSTART_0); +} + +static inline void hal_radio_stop(void) +{ + /* TODO: Add any required cleanup of actions taken in hal_radio_reset() + */ + nrf_lrcconf_clock_always_run_force_set(NRF_LRCCONF000, 0, false); + nrf_lrcconf_task_trigger(NRF_LRCCONF000, NRF_LRCCONF_TASK_CLKSTART_0); +} + +static inline void hal_radio_ram_prio_setup(void) +{ + /* TODO */ +} + +static inline uint32_t hal_radio_phy_mode_get(uint8_t phy, uint8_t flags) +{ + uint32_t mode; + + switch (phy) { + case BIT(0): + default: + mode = RADIO_MODE_MODE_Ble_1Mbit; + break; + + case BIT(1): + mode = RADIO_MODE_MODE_Ble_2Mbit; + break; + +#if defined(CONFIG_BT_CTLR_PHY_CODED) + case BIT(2): + if (flags & 0x01) { + mode = RADIO_MODE_MODE_Ble_LR125Kbit; + } else { + mode = RADIO_MODE_MODE_Ble_LR500Kbit; + } + break; +#endif /* CONFIG_BT_CTLR_PHY_CODED */ + } + + return mode; +} + +static inline int8_t hal_radio_tx_power_max_get(void) +{ + return 10; /* +10 dBm */ +} + +static inline int8_t hal_radio_tx_power_min_get(void) +{ + return -70; /* -70 dBm */ +} + +static inline int8_t hal_radio_tx_power_floor(int8_t tx_power_lvl) +{ + if (tx_power_lvl >= 10) { + return 10; + } + if (tx_power_lvl >= 9) { + return 9; + } + if (tx_power_lvl >= 8) { + return 8; + } + if (tx_power_lvl >= 7) { + return 7; + } + if (tx_power_lvl >= 6) { + return 6; + } + if (tx_power_lvl >= 5) { + return 5; + } + if (tx_power_lvl >= 4) { + return 4; + } + if (tx_power_lvl >= 3) { + return 3; + } + if (tx_power_lvl >= 2) { + return 2; + } + if (tx_power_lvl >= 1) { + return 1; + } + if (tx_power_lvl >= 0) { + return 0; + } + if (tx_power_lvl >= -1) { + return -1; + } + if (tx_power_lvl >= -2) { + return -2; + } + /* Step from -2 to -4 */ + if (tx_power_lvl >= -4) { + return -4; + } + /* Step from -4 to -8 */ + if (tx_power_lvl >= -8) { + return -8; + } + /* Step from -8 to -12 */ + if (tx_power_lvl >= -12) { + return -12; + } + /* Step from -12 to -16 */ + if (tx_power_lvl >= -16) { + return -16; + } + /* Step from -16 to -20 */ + if (tx_power_lvl >= -20) { + return -20; + } + /* Step from -20 to -30 */ + if (tx_power_lvl >= -30) { + return -30; + } + /* Step from -30 to -40 */ + if (tx_power_lvl >= -40) { + return -40; + } + /* Step from -40 to -70 */ + return -70; +} + +static inline uint32_t hal_radio_tx_power_value(int8_t tx_power_lvl) +{ + if (tx_power_lvl >= RADIO_TXPOWER_TXPOWER_Pos10dBm) { + return RADIO_TXPOWER_TXPOWER_Pos10dBm; + } + if (tx_power_lvl >= RADIO_TXPOWER_TXPOWER_Pos9dBm) { + return RADIO_TXPOWER_TXPOWER_Pos9dBm; + } + if (tx_power_lvl >= RADIO_TXPOWER_TXPOWER_Pos8dBm) { + return RADIO_TXPOWER_TXPOWER_Pos8dBm; + } + if (tx_power_lvl >= RADIO_TXPOWER_TXPOWER_Pos7dBm) { + return RADIO_TXPOWER_TXPOWER_Pos7dBm; + } + if (tx_power_lvl >= RADIO_TXPOWER_TXPOWER_Pos6dBm) { + return RADIO_TXPOWER_TXPOWER_Pos6dBm; + } + if (tx_power_lvl >= RADIO_TXPOWER_TXPOWER_Pos5dBm) { + return RADIO_TXPOWER_TXPOWER_Pos5dBm; + } + if (tx_power_lvl >= RADIO_TXPOWER_TXPOWER_Pos4dBm) { + return RADIO_TXPOWER_TXPOWER_Pos4dBm; + } + if (tx_power_lvl >= RADIO_TXPOWER_TXPOWER_Pos3dBm) { + return RADIO_TXPOWER_TXPOWER_Pos3dBm; + } + if (tx_power_lvl >= RADIO_TXPOWER_TXPOWER_Pos2dBm) { + return RADIO_TXPOWER_TXPOWER_Pos2dBm; + } + if (tx_power_lvl >= RADIO_TXPOWER_TXPOWER_Pos1dBm) { + return RADIO_TXPOWER_TXPOWER_Pos1dBm; + } + if (tx_power_lvl >= RADIO_TXPOWER_TXPOWER_0dBm) { + return RADIO_TXPOWER_TXPOWER_0dBm; + } + if (tx_power_lvl >= RADIO_TXPOWER_TXPOWER_Neg1dBm) { + return RADIO_TXPOWER_TXPOWER_Neg1dBm; + } + if (tx_power_lvl >= RADIO_TXPOWER_TXPOWER_Neg2dBm) { + return RADIO_TXPOWER_TXPOWER_Neg2dBm; + } + /* Step from -2 to -4 */ + if (tx_power_lvl >= RADIO_TXPOWER_TXPOWER_Neg4dBm) { + return RADIO_TXPOWER_TXPOWER_Neg4dBm; + } + /* Step from -4 to -8 */ + if (tx_power_lvl >= RADIO_TXPOWER_TXPOWER_Neg8dBm) { + return RADIO_TXPOWER_TXPOWER_Neg8dBm; + } + /* Step from -8 to -12 */ + if (tx_power_lvl >= RADIO_TXPOWER_TXPOWER_Neg12dBm) { + return RADIO_TXPOWER_TXPOWER_Neg12dBm; + } + /* Step from -12 to -16 */ + if (tx_power_lvl >= RADIO_TXPOWER_TXPOWER_Neg16dBm) { + return RADIO_TXPOWER_TXPOWER_Neg16dBm; + } + /* Step from -16 to -20 */ + if (tx_power_lvl >= RADIO_TXPOWER_TXPOWER_Neg20dBm) { + return RADIO_TXPOWER_TXPOWER_Neg20dBm; + } + /* Step from -20 to -30 */ + if (tx_power_lvl >= RADIO_TXPOWER_TXPOWER_Neg30dBm) { + return RADIO_TXPOWER_TXPOWER_Neg30dBm; + } + /* Step from -30 to -40 */ + if (tx_power_lvl >= RADIO_TXPOWER_TXPOWER_Neg40dBm) { + return RADIO_TXPOWER_TXPOWER_Neg40dBm; + } + /* Step from -40 to -70 */ + return RADIO_TXPOWER_TXPOWER_Neg70dBm; +} + +static inline uint32_t hal_radio_tx_ready_delay_us_get(uint8_t phy, uint8_t flags) +{ + switch (phy) { + default: + case BIT(0): + return HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_1M_US; + case BIT(1): + return HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_2M_US; + +#if defined(CONFIG_BT_CTLR_PHY_CODED) + case BIT(2): + if (flags & 0x01) { + return HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S8_US; + } else { + return HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S2_US; + } +#endif /* CONFIG_BT_CTLR_PHY_CODED */ + } +} + +static inline uint32_t hal_radio_rx_ready_delay_us_get(uint8_t phy, uint8_t flags) +{ + switch (phy) { + default: + case BIT(0): + return HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_1M_US; + case BIT(1): + return HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_2M_US; + +#if defined(CONFIG_BT_CTLR_PHY_CODED) + case BIT(2): + if (flags & 0x01) { + return HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S8_US; + } else { + return HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S2_US; + } +#endif /* CONFIG_BT_CTLR_PHY_CODED */ + } +} + +static inline uint32_t hal_radio_tx_chain_delay_us_get(uint8_t phy, uint8_t flags) +{ + switch (phy) { + default: + case BIT(0): + return HAL_RADIO_NRF54HX_TX_CHAIN_DELAY_1M_US; + case BIT(1): + return HAL_RADIO_NRF54HX_TX_CHAIN_DELAY_2M_US; + +#if defined(CONFIG_BT_CTLR_PHY_CODED) + case BIT(2): + if (flags & 0x01) { + return HAL_RADIO_NRF54HX_TX_CHAIN_DELAY_S8_US; + } else { + return HAL_RADIO_NRF54HX_TX_CHAIN_DELAY_S2_US; + } +#endif /* CONFIG_BT_CTLR_PHY_CODED */ + } +} + +static inline uint32_t hal_radio_rx_chain_delay_us_get(uint8_t phy, uint8_t flags) +{ + switch (phy) { + default: + case BIT(0): + return HAL_RADIO_NRF54HX_RX_CHAIN_DELAY_1M_US; + case BIT(1): + return HAL_RADIO_NRF54HX_RX_CHAIN_DELAY_2M_US; + +#if defined(CONFIG_BT_CTLR_PHY_CODED) + case BIT(2): + if (flags & 0x01) { + return HAL_RADIO_NRF54HX_RX_CHAIN_DELAY_S8_US; + } else { + return HAL_RADIO_NRF54HX_RX_CHAIN_DELAY_S2_US; + } +#endif /* CONFIG_BT_CTLR_PHY_CODED */ + } +} + +static inline uint32_t hal_radio_tx_ready_delay_ns_get(uint8_t phy, uint8_t flags) +{ + switch (phy) { + default: + case BIT(0): + return HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_1M_NS; + case BIT(1): + return HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_2M_NS; + +#if defined(CONFIG_BT_CTLR_PHY_CODED) + case BIT(2): + if (flags & 0x01) { + return HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S8_NS; + } else { + return HAL_RADIO_NRF54HX_TXEN_TXIDLE_TX_S2_NS; + } +#endif /* CONFIG_BT_CTLR_PHY_CODED */ + } +} + +static inline uint32_t hal_radio_rx_ready_delay_ns_get(uint8_t phy, uint8_t flags) +{ + switch (phy) { + default: + case BIT(0): + return HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_1M_NS; + case BIT(1): + return HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_2M_NS; + +#if defined(CONFIG_BT_CTLR_PHY_CODED) + case BIT(2): + if (flags & 0x01) { + return HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S8_NS; + } else { + return HAL_RADIO_NRF54HX_RXEN_RXIDLE_RX_S2_NS; + } +#endif /* CONFIG_BT_CTLR_PHY_CODED */ + } +} + +static inline uint32_t hal_radio_tx_chain_delay_ns_get(uint8_t phy, uint8_t flags) +{ + switch (phy) { + default: + case BIT(0): + return HAL_RADIO_NRF54HX_TX_CHAIN_DELAY_1M_NS; + case BIT(1): + return HAL_RADIO_NRF54HX_TX_CHAIN_DELAY_2M_NS; + +#if defined(CONFIG_BT_CTLR_PHY_CODED) + case BIT(2): + if (flags & 0x01) { + return HAL_RADIO_NRF54HX_TX_CHAIN_DELAY_S8_NS; + } else { + return HAL_RADIO_NRF54HX_TX_CHAIN_DELAY_S2_NS; + } +#endif /* CONFIG_BT_CTLR_PHY_CODED */ + } +} + +static inline uint32_t hal_radio_rx_chain_delay_ns_get(uint8_t phy, uint8_t flags) +{ + switch (phy) { + default: + case BIT(0): + return HAL_RADIO_NRF54HX_RX_CHAIN_DELAY_1M_NS; + case BIT(1): + return HAL_RADIO_NRF54HX_RX_CHAIN_DELAY_2M_NS; + +#if defined(CONFIG_BT_CTLR_PHY_CODED) + case BIT(2): + if (flags & 0x01) { + return HAL_RADIO_NRF54HX_RX_CHAIN_DELAY_S8_NS; + } else { + return HAL_RADIO_NRF54HX_RX_CHAIN_DELAY_S2_NS; + } +#endif /* CONFIG_BT_CTLR_PHY_CODED */ + } +} diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h index 1085f72f0b98..aa46838e9b3c 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi.h @@ -7,6 +7,8 @@ #if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) #define NRF_DPPIC NRF_DPPIC10 +#elif defined(CONFIG_SOC_SERIES_NRF54HX) +#define NRF_DPPIC NRF_DPPIC020 #endif /* CONFIG_SOC_COMPATIBLE_NRF54LX */ static inline void hal_radio_nrf_ppi_channels_enable(uint32_t mask) @@ -106,6 +108,7 @@ static inline void hal_event_timer_start_ppi_config(void) nrf_grtc_publish_set(NRF_GRTC, HAL_CNTR_GRTC_EVENT_COMPARE_RADIO, HAL_EVENT_TIMER_START_PPI); +#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) /* Setup PPIB receive publish */ nrf_ppib_publish_set(NRF_PPIB11, HAL_PPIB_RECEIVE_EVENT_TIMER_START_PPI, HAL_EVENT_TIMER_START_PPI); @@ -115,8 +118,26 @@ static inline void hal_event_timer_start_ppi_config(void) HAL_EVENT_TIMER_START_PPI); /* Enable same DPPI in Peripheral domain */ - nrf_dppi_channels_enable(NRF_DPPIC20, - BIT(HAL_EVENT_TIMER_START_PPI)); + nrf_dppi_channels_enable(NRF_DPPIC20, BIT(HAL_EVENT_TIMER_START_PPI)); + +#elif defined(CONFIG_SOC_SERIES_NRF54HX) + /* Setup IPCT receive publish in radio domain */ + nrf_ipct_publish_set(NRF_IPCT, HAL_IPCT_RECEIVE_EVENT_TIMER_START_PPI, + HAL_EVENT_TIMER_START_PPI); + + /* Setup IPCT send subscribe in main domain */ + nrf_ipct_subscribe_set(NRF_IPCT130, HAL_IPCT_SEND_EVENT_TIMER_START_PPI, + HAL_EVENT_TIMER_START_PPI); + + nrf_ipct_shorts_enable(NRF_IPCT, IPCT_SHORTS_RECEIVE0_FLUSH0_Msk); + + /* Enable same DPPI in main domain */ + nrf_dppi_channels_enable(NRF_DPPIC130, BIT(HAL_EVENT_TIMER_START_PPI)); + + /* Enable same DPPI in global domain */ + nrf_dppi_channels_enable(NRF_DPPIC132, BIT(HAL_EVENT_TIMER_START_PPI)); +#else +#endif #else /* !CONFIG_BT_CTLR_NRF_GRTC */ nrf_rtc_publish_set(NRF_RTC, NRF_RTC_EVENT_COMPARE_2, HAL_EVENT_TIMER_START_PPI); diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi_resources.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi_resources.h index 3a49b97e7b26..365fb2f11f9f 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi_resources.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_dppi_resources.h @@ -36,11 +36,15 @@ * Start event timer on RTC tick: * wire the RTC0 EVENTS_COMPARE[2] event to EVENT_TIMER TASKS_START task. */ -#define HAL_EVENT_TIMER_START_PPI 8 +#define HAL_EVENT_TIMER_START_PPI 0 #define HAL_PPIB_SEND_EVENT_TIMER_START_PPI \ _CONCAT(NRF_PPIB_TASK_SEND_, HAL_EVENT_TIMER_START_PPI) #define HAL_PPIB_RECEIVE_EVENT_TIMER_START_PPI \ _CONCAT(NRF_PPIB_EVENT_RECEIVE_, HAL_EVENT_TIMER_START_PPI) +#define HAL_IPCT_SEND_EVENT_TIMER_START_PPI \ + _CONCAT(NRF_IPCT_TASK_SEND_, HAL_EVENT_TIMER_START_PPI) +#define HAL_IPCT_RECEIVE_EVENT_TIMER_START_PPI \ + _CONCAT(NRF_IPCT_EVENT_RECEIVE_, HAL_EVENT_TIMER_START_PPI) /******************************************************************************* * Capture event timer on Radio ready: @@ -184,5 +188,9 @@ /* The 2 adjacent PPI groups used for implementing SW_SWITCH_TIMER-based * auto-switch for TIFS. 'index' must be 0 or 1. */ +#if defined(CONFIG_SOC_SERIES_NRF54HX) +#define SW_SWITCH_TIMER_TASK_GROUP_BASE 2 +#else /* !CONFIG_SOC_SERIES_NRF54HX */ #define SW_SWITCH_TIMER_TASK_GROUP_BASE 4 +#endif /* !CONFIG_SOC_SERIES_NRF54HX */ #endif /* !CONFIG_BT_CTLR_TIFS_HW */ diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/swi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/swi.h index 801479206461..d58db739795b 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/swi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/swi.h @@ -41,7 +41,7 @@ #error Unknown NRF5340 CPU. #endif /* !CONFIG_SOC_COMPATIBLE_NRF5340_CPUNET */ -/* nRF54 Series IRQ mapping */ +/* nRF54L Series IRQ mapping */ #elif defined(CONFIG_SOC_COMPATIBLE_NRF54LX) #define HAL_SWI_RADIO_IRQ SWI02_IRQn @@ -61,6 +61,25 @@ #define HAL_SWI_JOB_IRQ SWI03_IRQn #endif +/* nRF54H Series IRQ mapping */ +#elif defined(CONFIG_SOC_SERIES_NRF54HX) + +#define HAL_SWI_RADIO_IRQ SWI2_IRQn + +#if defined(CONFIG_BT_CTLR_NRF_GRTC) +#define HAL_SWI_WORKER_IRQ GRTC_2_IRQn +#define HAL_RTC_IRQn GRTC_2_IRQn +#else /* !CONFIG_BT_CTLR_NRF_GRTC */ +#define HAL_SWI_WORKER_IRQ RTC_IRQn +#define HAL_RTC_IRQn RTC_IRQn +#endif /* !CONFIG_BT_CTLR_NRF_GRTC */ + +#if !defined(CONFIG_BT_CTLR_LOW_LAT) && \ + (CONFIG_BT_CTLR_ULL_HIGH_PRIO == CONFIG_BT_CTLR_ULL_LOW_PRIO) +#define HAL_SWI_JOB_IRQ HAL_SWI_WORKER_IRQ +#else +#define HAL_SWI_JOB_IRQ SWI3_IRQn +#endif #endif static inline void hal_swi_init(void) diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hci/hci_vendor.c b/subsys/bluetooth/controller/ll_sw/nordic/hci/hci_vendor.c index a6f6a185d636..568bbef1cbfb 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hci/hci_vendor.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/hci/hci_vendor.c @@ -10,6 +10,13 @@ #include +#if defined(CONFIG_SOC_SERIES_NRF54HX) +#define DEVICEADDR BLE.ADDR +#define DEVICEADDRTYPE BLE.ADDRTYPE +#define IR BLE.IR +#define ER BLE.ER +#endif + uint8_t hci_vendor_read_static_addr(struct bt_hci_vs_static_addr addrs[], uint8_t size) { diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_clock.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_clock.c index af98d69b049e..f9d02c08d64f 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_clock.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_clock.c @@ -10,6 +10,8 @@ #include #include +#include "lll_clock.h" + #include "hal/debug.h" /* Clock setup timeouts are unlikely, below values are experimental */ @@ -17,14 +19,120 @@ #define HFCLOCK_TIMEOUT_MS 2 static uint16_t const sca_ppm_lut[] = {500, 250, 150, 100, 75, 50, 30, 20}; +static atomic_val_t hf_refcnt; + +#if defined(CONFIG_SOC_SERIES_NRF54HX) +#define CLOCK_CONTROL_NRF_K32SRC_ACCURACY 7U /* FIXME: */ +#define NOTIFY_TIMEOUT K_SECONDS(2) + +const static struct device *clock_dev_lf = DEVICE_DT_GET(DT_NODELABEL(lfclk)); +const static struct nrf_clock_spec clock_req_spec_lf = { + .frequency = 32768, + .accuracy = sca_ppm_lut[CLOCK_CONTROL_NRF_K32SRC_ACCURACY], + .precision = 0, /* 0 for low precision, 1 for high precision */ +}; +static struct onoff_client clock_cli_lf; + +int lll_clock_init(void) +{ + int err; + + sys_notify_init_spinwait(&clock_cli_lf.notify); + + err = nrf_clock_control_request(clock_dev_lf, &clock_req_spec_lf, &clock_cli_lf); + if (err) { + return err; + } + + return 0; +} + +int lll_clock_deinit(void) +{ + int err; + + err = nrf_clock_control_release(clock_dev_lf, &clock_req_spec_lf); + if (err) { + return err; + } + + return 0; +} + +int lll_clock_wait(void) +{ + return 0; +} + +#if !defined(CONFIG_BT_CTLR_ZLI) +const static struct device *clock_dev_hfxo = DEVICE_DT_GET(DT_NODELABEL(hfxo)); +const static struct nrf_clock_spec clock_req_spec_hfxo = { + .frequency = 0, /* Ignore or use default */ + .accuracy = 1, /* Use maximum accuracy */ + .precision = 1, /* 0 for low precision, 1 for high precision */ +}; +static struct onoff_client clock_cli_hfxo; +#endif + +int lll_hfclock_on(void) +{ + if (atomic_inc(&hf_refcnt) > 0) { + return 0; + } + +#if defined(CONFIG_BT_CTLR_ZLI) + nrf_clock_control_hfxo_request(); +#else + int err; + + sys_notify_init_spinwait(&clock_cli_hfxo.notify); + + err = nrf_clock_control_request(clock_dev_hfxo, &clock_req_spec_hfxo, &clock_cli_hfxo); + if (err) { + return err; + } +#endif + + return 0; +} + +int lll_hfclock_on_wait(void) +{ + /* TODO: */ + return 0; +} + +int lll_hfclock_off(void) +{ + if (atomic_get(&hf_refcnt) < 1) { + return -EALREADY; + } + + if (atomic_dec(&hf_refcnt) > 1) { + return 0; + } + +#if defined(CONFIG_BT_CTLR_ZLI) + nrf_clock_control_hfxo_release(); +#else + int err; + + err = nrf_clock_control_release(clock_dev_hfxo, &clock_req_spec_hfxo); + if (err) { + return err; + } +#endif + + return 0; +} + +#else /* !CONFIG_SOC_SERIES_NRF54HX */ struct lll_clock_state { struct onoff_client cli; struct k_sem sem; }; - static struct onoff_client lf_cli; -static atomic_val_t hf_refcnt; static void clock_ready(struct onoff_manager *mgr, struct onoff_client *cli, uint32_t state, int res) @@ -140,6 +248,7 @@ int lll_hfclock_off(void) return 0; } +#endif /* !CONFIG_SOC_SERIES_NRF54HX */ uint8_t lll_clock_sca_local_get(void) {