diff --git a/subsys/bluetooth/controller/Kconfig.ll_sw_split b/subsys/bluetooth/controller/Kconfig.ll_sw_split index ee422f1230e1..b4572c05d3bc 100644 --- a/subsys/bluetooth/controller/Kconfig.ll_sw_split +++ b/subsys/bluetooth/controller/Kconfig.ll_sw_split @@ -21,8 +21,7 @@ config BT_LLL_VENDOR_NORDIC select BT_CTLR_CRYPTO_SUPPORT select BT_CTLR_LE_ENC_SUPPORT if BT_CTLR_CRYPTO_SUPPORT && \ !BT_CTLR_DATA_LENGTH_CLEAR && \ - !BT_CTLR_PHY_2M_NRF && \ - !SOC_COMPATIBLE_NRF54LX + !BT_CTLR_PHY_2M_NRF select BT_CTLR_PRIVACY_SUPPORT if BT_CTLR_CRYPTO_SUPPORT && \ !SOC_SERIES_NRF51X && \ !SOC_COMPATIBLE_NRF54LX @@ -31,6 +30,7 @@ config BT_LLL_VENDOR_NORDIC select BT_CTLR_PER_INIT_FEAT_XCHG_SUPPORT select BT_CTLR_DATA_LEN_UPDATE_SUPPORT if !BT_CTLR_LE_ENC_SUPPORT || \ HAS_HW_NRF_CCM_LFLEN_8BIT || \ + SOC_COMPATIBLE_NRF54LX || \ 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 || \ @@ -43,7 +43,7 @@ config BT_LLL_VENDOR_NORDIC select BT_CTLR_SYNC_PERIODIC_SUPPORT select BT_CTLR_ADV_ISO_SUPPORT select BT_CTLR_SYNC_ISO_SUPPORT - select BT_CTLR_BROADCAST_ISO_ENC_SUPPORT if !SOC_COMPATIBLE_NRF54LX + select BT_CTLR_BROADCAST_ISO_ENC_SUPPORT select BT_CTLR_CENTRAL_ISO_SUPPORT select BT_CTLR_PERIPHERAL_ISO_SUPPORT select BT_CTLR_DF_SUPPORT if HAS_HW_NRF_RADIO_DFE diff --git a/subsys/bluetooth/controller/hci/hci.c b/subsys/bluetooth/controller/hci/hci.c index e553345f5adf..ba6609f7532b 100644 --- a/subsys/bluetooth/controller/hci/hci.c +++ b/subsys/bluetooth/controller/hci/hci.c @@ -8152,8 +8152,11 @@ static void le_big_complete(struct pdu_data *pdu_data, struct net_buf *buf) { struct bt_hci_evt_le_big_complete *sep; + uint32_t transport_latency_big; struct ll_adv_iso_set *adv_iso; + uint32_t iso_interval_us; struct lll_adv_iso *lll; + uint32_t big_sync_delay; size_t evt_size; adv_iso = node_rx->rx_ftr.param; @@ -8170,9 +8173,36 @@ static void le_big_complete(struct pdu_data *pdu_data, return; } - /* FIXME: Fill sync delay and latency */ - sys_put_le24(0, sep->sync_delay); - sys_put_le24(0, sep->latency); + /* BT Core v5.4 - Vol 6, Part B, Section 4.4.6.4: + * BIG_Sync_Delay = (Num_BIS – 1) × BIS_Spacing + (NSE – 1) × Sub_Interval + MPT. + * + * BT Core v5.4 - Vol 6, Part G, Section 3.2.1: (Framed) + * Transport_Latenct_BIG = BIG_Sync_Delay + PTO × (NSE / BN – IRC) * ISO_Interval + + * ISO_Interval + SDU_Interval + * + * BT Core v5.4 - Vol 6, Part G, Section 3.2.2: (Unframed) + * Transport_Latenct_BIG = BIG_Sync_Delay + (PTO × (NSE / BN – IRC) + 1) * ISO_Interval - + * SDU_Interval + */ + iso_interval_us = lll->iso_interval * ISO_INT_UNIT_US; + big_sync_delay = ull_iso_big_sync_delay(lll->num_bis, lll->bis_spacing, lll->nse, + lll->sub_interval, lll->phy, lll->max_pdu, + lll->enc); + sys_put_le24(big_sync_delay, sep->sync_delay); + + if (lll->framing) { + /* Framed */ + transport_latency_big = big_sync_delay + + lll->pto * (lll->nse / lll->bn - lll->irc) * + iso_interval_us + iso_interval_us + lll->sdu_interval; + } else { + /* Unframed */ + transport_latency_big = big_sync_delay + + (lll->pto * (lll->nse / lll->bn - lll->irc) + 1) * + iso_interval_us - lll->sdu_interval; + } + + sys_put_le24(transport_latency_big, sep->latency); sep->phy = find_lsb_set(lll->phy); sep->nse = lll->nse; @@ -8180,6 +8210,7 @@ static void le_big_complete(struct pdu_data *pdu_data, sep->pto = lll->pto; sep->irc = lll->irc; sep->max_pdu = sys_cpu_to_le16(lll->max_pdu); + sep->iso_interval = sys_cpu_to_le16(lll->iso_interval); sep->num_bis = lll->num_bis; /* Connection handle list of all BISes in the BIG */ diff --git a/subsys/bluetooth/controller/ll_sw/lll_conn.h b/subsys/bluetooth/controller/ll_sw/lll_conn.h index 19a7820ed949..bcaaa4d2d2e6 100644 --- a/subsys/bluetooth/controller/ll_sw/lll_conn.h +++ b/subsys/bluetooth/controller/ll_sw/lll_conn.h @@ -86,10 +86,14 @@ struct lll_conn { #if defined(CONFIG_BT_PERIPHERAL) struct { - uint8_t initiated:1; - uint8_t cancelled:1; - uint8_t forced:1; - uint8_t latency_enabled:1; + uint8_t initiated:1; + uint8_t cancelled:1; + uint8_t forced:1; + uint8_t latency_enabled:1; + +#if defined(CONFIG_BT_CTLR_PHY) + uint8_t phy_rx_event:3; +#endif /* CONFIG_BT_CTLR_PHY */ uint32_t window_widening_periodic_us; uint32_t window_widening_max_us; diff --git a/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h b/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h index 31e2f70fcd61..676c574155e4 100644 --- a/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h +++ b/subsys/bluetooth/controller/ll_sw/lll_conn_iso.h @@ -45,7 +45,8 @@ struct lll_conn_iso_stream { struct lll_conn_iso_stream_rxtx tx; /* TX parameters */ /* Event and payload counters */ - uint64_t event_count:39; /* cisEventCount */ + uint64_t event_count_prepare:39; /* cisEventCount in overlapping CIG prepare */ + uint64_t event_count:39; /* cisEventCount in current CIG event */ /* Acknowledgment and flow control */ uint8_t sn:1; /* Sequence number */ 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 d9ecba277aae..fab5618a4d81 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 @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -404,7 +405,7 @@ void radio_aa_set(const uint8_t *aa) NRF_RADIO->RXADDRESSES = ((RADIO_RXADDRESSES_ADDR0_Enabled) << RADIO_RXADDRESSES_ADDR0_Pos); NRF_RADIO->PREFIX0 = aa[3]; - NRF_RADIO->BASE0 = (((uint32_t) aa[2]) << 24) | (aa[1] << 16) | (aa[0] << 8); + NRF_RADIO->BASE0 = sys_get_le24(aa) << 8; } void radio_pkt_configure(uint8_t bits_len, uint8_t max_len, uint8_t flags) @@ -611,11 +612,18 @@ uint32_t radio_is_address(void) } #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) +static uint32_t last_pdu_end_latency_us; static uint32_t last_pdu_end_us; +static void last_pdu_end_us_init(uint32_t latency_us) +{ + last_pdu_end_latency_us = latency_us; + last_pdu_end_us = 0U; +} + uint32_t radio_is_done(void) { - if (NRF_RADIO->NRF_RADIO_TRX_END_EVENT != 0) { + if (NRF_RADIO->HAL_RADIO_TRX_EVENTS_END != 0) { /* On packet END event increment last packet end time value. * Note: this depends on the function being called exactly once * in the ISR function. @@ -630,7 +638,7 @@ uint32_t radio_is_done(void) #else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ uint32_t radio_is_done(void) { - return (NRF_RADIO->NRF_RADIO_TRX_END_EVENT != 0); + return (NRF_RADIO->HAL_RADIO_TRX_EVENTS_END != 0); } #endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ @@ -1388,7 +1396,11 @@ void radio_tmr_tifs_set(uint32_t tifs) uint32_t radio_tmr_start(uint8_t trx, uint32_t ticks_start, uint32_t remainder) { + uint32_t remainder_us; + + /* Convert jitter to positive offset remainder in microseconds */ hal_ticker_remove_jitter(&ticks_start, &remainder); + remainder_us = remainder; #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) /* When using single timer for software tIFS switching, ensure that @@ -1401,18 +1413,18 @@ uint32_t radio_tmr_start(uint8_t trx, uint32_t ticks_start, uint32_t remainder) uint32_t latency_ticks; uint32_t latency_us; - latency_us = MAX(remainder, HAL_RADIO_ISR_LATENCY_MAX_US) - remainder; + latency_us = MAX(remainder_us, HAL_RADIO_ISR_LATENCY_MAX_US) - remainder_us; latency_ticks = HAL_TICKER_US_TO_TICKS(latency_us); ticks_start -= latency_ticks; - remainder += latency_us; -#endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ + remainder_us += latency_us; +#endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ nrf_timer_task_trigger(EVENT_TIMER, NRF_TIMER_TASK_CLEAR); EVENT_TIMER->MODE = 0; EVENT_TIMER->PRESCALER = HAL_EVENT_TIMER_PRESCALER_VALUE; EVENT_TIMER->BITMODE = 2; /* 24 - bit */ - nrf_timer_cc_set(EVENT_TIMER, HAL_EVENT_TIMER_TRX_CC_OFFSET, remainder); + nrf_timer_cc_set(EVENT_TIMER, HAL_EVENT_TIMER_TRX_CC_OFFSET, remainder_us); #if defined(CONFIG_BT_CTLR_NRF_GRTC) uint32_t cntr_l, cntr_h, cntr_h_overflow, stale; @@ -1479,7 +1491,7 @@ uint32_t radio_tmr_start(uint8_t trx, uint32_t ticks_start, uint32_t remainder) #if !defined(CONFIG_BT_CTLR_TIFS_HW) #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) - last_pdu_end_us = 0U; + last_pdu_end_us_init(latency_us); #else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ nrf_timer_task_trigger(SW_SWITCH_TIMER, NRF_TIMER_TASK_CLEAR); @@ -1506,7 +1518,7 @@ uint32_t radio_tmr_start(uint8_t trx, uint32_t ticks_start, uint32_t remainder) #endif /* CONFIG_BT_CTLR_PHY_CODED && CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */ #endif /* !CONFIG_BT_CTLR_TIFS_HW */ - return remainder; + return remainder_us; } uint32_t radio_tmr_start_tick(uint8_t trx, uint32_t ticks_start) @@ -1514,7 +1526,7 @@ uint32_t radio_tmr_start_tick(uint8_t trx, uint32_t ticks_start) uint32_t remainder_us; /* Setup compare event with min. 1 us offset */ - remainder_us = 1; + remainder_us = 1U; #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) /* When using single timer for software tIFS switching, ensure that @@ -1531,7 +1543,7 @@ uint32_t radio_tmr_start_tick(uint8_t trx, uint32_t ticks_start) latency_ticks = HAL_TICKER_US_TO_TICKS(latency_us); ticks_start -= latency_ticks; remainder_us += latency_us; -#endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ +#endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ nrf_timer_task_trigger(EVENT_TIMER, NRF_TIMER_TASK_STOP); nrf_timer_task_trigger(EVENT_TIMER, NRF_TIMER_TASK_CLEAR); @@ -1603,7 +1615,7 @@ uint32_t radio_tmr_start_tick(uint8_t trx, uint32_t ticks_start) #if !defined(CONFIG_BT_CTLR_TIFS_HW) #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) - last_pdu_end_us = 0U; + last_pdu_end_us_init(latency_us); #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ #if defined(CONFIG_SOC_COMPATIBLE_NRF53X) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX) /* NOTE: Timer clear DPPI configuration is needed only for nRF53 @@ -1630,7 +1642,10 @@ uint32_t radio_tmr_start_us(uint8_t trx, uint32_t start_us) #if !defined(CONFIG_BT_CTLR_TIFS_HW) #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) - last_pdu_end_us = 0U; + /* As timer is reset on every radio end, remove the accumulated + * last_pdu_end_us in the given start_us. + */ + start_us -= last_pdu_end_us; #endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ #if defined(CONFIG_SOC_COMPATIBLE_NRF53X) || defined(CONFIG_SOC_COMPATIBLE_NRF54LX) /* NOTE: Timer clear DPPI configuration is needed only for nRF53 @@ -1672,7 +1687,7 @@ uint32_t radio_tmr_start_us(uint8_t trx, uint32_t start_us) latency_us = MAX(actual_us, HAL_RADIO_ISR_LATENCY_MAX_US) - actual_us; actual_us += latency_us; -#endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ +#endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ nrf_timer_event_clear(EVENT_TIMER, HAL_EVENT_TIMER_TRX_EVENT); nrf_timer_cc_set(EVENT_TIMER, HAL_EVENT_TIMER_TRX_CC_OFFSET, actual_us); @@ -1684,6 +1699,10 @@ uint32_t radio_tmr_start_us(uint8_t trx, uint32_t start_us) } while ((now_us > start_us) && (EVENT_TIMER->EVENTS_COMPARE[HAL_EVENT_TIMER_TRX_CC_OFFSET] == 0U)); +#if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) + actual_us += last_pdu_end_us; +#endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ + return actual_us; } @@ -1697,9 +1716,26 @@ uint32_t radio_tmr_start_now(uint8_t trx) nrf_timer_task_trigger(EVENT_TIMER, HAL_EVENT_TIMER_SAMPLE_TASK); start_us = EVENT_TIMER->CC[HAL_EVENT_TIMER_SAMPLE_CC_OFFSET]; +#if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) + /* As timer is reset on every radio end, add the accumulated + * last_pdu_end_us to the captured current time. + */ + start_us += last_pdu_end_us; +#endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ + /* Setup radio start at current time */ start_us = radio_tmr_start_us(trx, start_us); +#if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) + /* Remove the single timer start latency used to mitigate use of too + * small compare register value. Thus, start_us returned be always + * the value corresponding to the captured radio ready timestamp. + * This is used in the calculation of aux_offset in subsequent + * ADV_EXT_IND PDUs. + */ + start_us -= last_pdu_end_latency_us; +#endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ + return start_us; } @@ -1721,18 +1757,29 @@ uint32_t radio_tmr_start_get(void) return start_ticks; } +uint32_t radio_tmr_start_latency_get(void) +{ +#if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) + return last_pdu_end_latency_us; +#else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ + return 0U; +#endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ +} + void radio_tmr_stop(void) { nrf_timer_task_trigger(EVENT_TIMER, NRF_TIMER_TASK_STOP); #if defined(TIMER_TASKS_SHUTDOWN_TASKS_SHUTDOWN_Msk) nrf_timer_task_trigger(EVENT_TIMER, NRF_TIMER_TASK_SHUTDOWN); -#endif +#endif /* TIMER_TASKS_SHUTDOWN_TASKS_SHUTDOWN_Msk */ #if !defined(CONFIG_BT_CTLR_TIFS_HW) +#if !defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) nrf_timer_task_trigger(SW_SWITCH_TIMER, NRF_TIMER_TASK_STOP); #if defined(TIMER_TASKS_SHUTDOWN_TASKS_SHUTDOWN_Msk) nrf_timer_task_trigger(SW_SWITCH_TIMER, NRF_TIMER_TASK_SHUTDOWN); -#endif +#endif /* TIMER_TASKS_SHUTDOWN_TASKS_SHUTDOWN_Msk */ +#endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ #endif /* !CONFIG_BT_CTLR_TIFS_HW */ #if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) @@ -1740,9 +1787,9 @@ void radio_tmr_stop(void) #endif /* CONFIG_SOC_COMPATIBLE_NRF54LX */ } -void radio_tmr_hcto_configure(uint32_t hcto) +void radio_tmr_hcto_configure(uint32_t hcto_us) { - nrf_timer_cc_set(EVENT_TIMER, HAL_EVENT_TIMER_HCTO_CC_OFFSET, hcto); + nrf_timer_cc_set(EVENT_TIMER, HAL_EVENT_TIMER_HCTO_CC_OFFSET, hcto_us); hal_radio_recv_timeout_cancel_ppi_config(); hal_radio_disable_on_hcto_ppi_config(); @@ -1751,6 +1798,18 @@ void radio_tmr_hcto_configure(uint32_t hcto) BIT(HAL_RADIO_DISABLE_ON_HCTO_PPI)); } +void radio_tmr_hcto_configure_abs(uint32_t hcto_from_start_us) +{ +#if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) + /* As timer is reset on every radio end, remove the accumulated + * last_pdu_end_us in the given hcto_us. + */ + hcto_from_start_us -= last_pdu_end_us; +#endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ + + radio_tmr_hcto_configure(hcto_from_start_us); +} + void radio_tmr_aa_capture(void) { hal_radio_ready_time_capture_ppi_config(); @@ -1825,7 +1884,11 @@ uint32_t radio_tmr_end_get(void) uint32_t radio_tmr_tifs_base_get(void) { +#if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) + return 0U; +#else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ return radio_tmr_end_get(); +#endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ } #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) @@ -1995,7 +2058,33 @@ 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) +struct ccm_job_ptr { + void *ptr; + struct { + uint32_t length:24; + uint32_t attribute:8; + } __packed; +} __packed; + +#define CCM_JOB_PTR_ATTRIBUTE_ALEN 11U +#define CCM_JOB_PTR_ATTRIBUTE_MLEN 12U +#define CCM_JOB_PTR_ATTRIBUTE_ADATA 13U +#define CCM_JOB_PTR_ATTRIBUTE_MDATA 14U + +static struct { + uint16_t in_alen; + uint16_t in_mlen; + uint8_t in_mlen_msb; + uint8_t out_mlen_msb; + uint16_t out_alen; + struct ccm_job_ptr in[6]; + struct ccm_job_ptr out[6]; +} ccm_job; + +#else /* !CONFIG_SOC_COMPATIBLE_NRF54LX */ static uint8_t MALIGN(4) _ccm_scratch[(HAL_RADIO_PDU_LEN_MAX - 4) + 16]; +#endif /* !CONFIG_SOC_COMPATIBLE_NRF54LX */ #if defined(CONFIG_BT_CTLR_LE_ENC) || defined(CONFIG_BT_CTLR_SYNC_ISO) static void *radio_ccm_ext_rx_pkt_set(struct ccm *cnf, uint8_t phy, uint8_t pdu_type, void *pkt) @@ -2004,21 +2093,34 @@ static void *radio_ccm_ext_rx_pkt_set(struct ccm *cnf, uint8_t phy, uint8_t pdu_ NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Disabled; NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Enabled; + mode = (CCM_MODE_MODE_Decryption << CCM_MODE_MODE_Pos) & CCM_MODE_MODE_Msk; -#if !defined(CONFIG_SOC_SERIES_NRF51X) +#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) + /* Enable CCM Protocol Mode BLE */ + mode |= (CCM_MODE_PROTOCOL_Ble << CCM_MODE_PROTOCOL_Pos) & + CCM_MODE_PROTOCOL_Msk; + + /* Enable CCM MAC Length 4 bytes */ + mode |= (CCM_MODE_MACLEN_M4 << CCM_MODE_MACLEN_Pos) & + CCM_MODE_MACLEN_Msk; + +#elif !defined(CONFIG_SOC_SERIES_NRF51X) /* Enable CCM support for 8-bit length field PDUs. */ mode |= (CCM_MODE_LENGTH_Extended << CCM_MODE_LENGTH_Pos) & CCM_MODE_LENGTH_Msk; +#endif /* !CONFIG_SOC_SERIES_NRF51X */ /* Select CCM data rate based on current PHY in use. */ switch (phy) { default: case PHY_1M: +#if !defined(CONFIG_SOC_SERIES_NRF51X) mode |= (CCM_MODE_DATARATE_1Mbit << CCM_MODE_DATARATE_Pos) & CCM_MODE_DATARATE_Msk; +#endif /* !CONFIG_SOC_SERIES_NRF51X */ if (false) { @@ -2041,9 +2143,11 @@ static void *radio_ccm_ext_rx_pkt_set(struct ccm *cnf, uint8_t phy, uint8_t pdu_ break; case PHY_2M: +#if !defined(CONFIG_SOC_SERIES_NRF51X) mode |= (CCM_MODE_DATARATE_2Mbit << CCM_MODE_DATARATE_Pos) & CCM_MODE_DATARATE_Msk; +#endif /* !CONFIG_SOC_SERIES_NRF51X */ hal_trigger_crypt_ppi_config(); hal_radio_nrf_ppi_channels_enable(BIT(HAL_TRIGGER_CRYPT_PPI)); @@ -2074,47 +2178,131 @@ static void *radio_ccm_ext_rx_pkt_set(struct ccm *cnf, uint8_t phy, uint8_t pdu_ #endif /* CONFIG_BT_CTLR_PHY_CODED */ } -#if !defined(CONFIG_SOC_NRF52832) && \ - (!defined(CONFIG_BT_CTLR_DATA_LENGTH_MAX) || \ - (CONFIG_BT_CTLR_DATA_LENGTH_MAX < ((HAL_RADIO_PDU_LEN_MAX) - 4U))) - uint8_t max_len = (NRF_RADIO->PCNF1 & RADIO_PCNF1_MAXLEN_Msk) >> - RADIO_PCNF1_MAXLEN_Pos; - - /* MAXPACKETSIZE value 0x001B (27) - 0x00FB (251) bytes */ - NRF_CCM->MAXPACKETSIZE = max_len - 4U; -#endif + NRF_CCM->MODE = mode; +#if defined(CONFIG_HAS_HW_NRF_CCM_HEADERMASK) || \ + defined(CONFIG_SOC_COMPATIBLE_NRF54LX) #if defined(CONFIG_HAS_HW_NRF_CCM_HEADERMASK) +#define ADATAMASK HEADERMASK +#endif /* CONFIG_HAS_HW_NRF_CCM_HEADERMASK */ switch (pdu_type) { case RADIO_PKT_CONF_PDU_TYPE_BIS: - NRF_CCM->HEADERMASK = 0xC3; /* mask CSSN and CSTF */ + NRF_CCM->ADATAMASK = 0xC3; /* mask CSSN and CSTF */ break; case RADIO_PKT_CONF_PDU_TYPE_CIS: - NRF_CCM->HEADERMASK = 0xA3; /* mask SN, NESN, CIE and NPI */ + NRF_CCM->ADATAMASK = 0xA3; /* mask SN, NESN, CIE and NPI */ break; default: - /* Using default reset value of HEADERMASK */ - NRF_CCM->HEADERMASK = 0xE3; /* mask SN, NESN and MD */ + /* Using default reset value of ADATAMASK */ + NRF_CCM->ADATAMASK = 0xE3; /* mask SN, NESN and MD */ break; } +#if defined(CONFIG_HAS_HW_NRF_CCM_HEADERMASK) +#undef ADATAMASK #endif /* CONFIG_HAS_HW_NRF_CCM_HEADERMASK */ +#endif /* CONFIG_HAS_HW_NRF_CCM_HEADERMASK || + * CONFIG_SOC_COMPATIBLE_NRF54LX + */ -#else /* CONFIG_SOC_SERIES_NRF51X */ - hal_trigger_crypt_ppi_config(); - hal_radio_nrf_ppi_channels_enable(BIT(HAL_TRIGGER_CRYPT_PPI)); -#endif /* CONFIG_SOC_SERIES_NRF51X */ +#if !defined(CONFIG_SOC_SERIES_NRF51X) && \ + !defined(CONFIG_SOC_NRF52832) && \ + !defined(CONFIG_SOC_COMPATIBLE_NRF54LX) && \ + (!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) >> + RADIO_PCNF1_MAXLEN_Pos; - NRF_CCM->MODE = mode; + /* MAXPACKETSIZE value 0x001B (27) - 0x00FB (251) bytes */ + NRF_CCM->MAXPACKETSIZE = max_len - 4U; +#endif + +#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) + /* 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]); + NRF_CCM->KEY.VALUE[1] = sys_get_be32(&cnf->key[8]); + NRF_CCM->KEY.VALUE[0] = sys_get_be32(&cnf->key[12]); + + NRF_CCM->NONCE.VALUE[3] = ((uint8_t *)&cnf->counter)[0]; + NRF_CCM->NONCE.VALUE[2] = sys_get_be32(&((uint8_t *)&cnf->counter)[1]) | + (cnf->direction << 7); + NRF_CCM->NONCE.VALUE[1] = sys_get_be32(&cnf->iv[0]); + NRF_CCM->NONCE.VALUE[0] = sys_get_be32(&cnf->iv[4]); + + const uint8_t mlen = (NRF_RADIO->PCNF1 & RADIO_PCNF1_MAXLEN_Msk) >> + RADIO_PCNF1_MAXLEN_Pos; + + const uint8_t alen = sizeof(uint8_t); + + ccm_job.in_alen = alen; + ccm_job.in[0].ptr = &ccm_job.in_alen; + ccm_job.in[0].length = sizeof(ccm_job.in_alen); + ccm_job.in[0].attribute = CCM_JOB_PTR_ATTRIBUTE_ALEN; + + ccm_job.in[1].ptr = (void *)((uint8_t *)_pkt_scratch + 1U); + ccm_job.in[1].length = sizeof(uint8_t); + ccm_job.in[1].attribute = CCM_JOB_PTR_ATTRIBUTE_MLEN; + + ccm_job.in_mlen_msb = 0U; + ccm_job.in[2].ptr = &ccm_job.in_mlen_msb; + ccm_job.in[2].length = sizeof(ccm_job.in_mlen_msb); + ccm_job.in[2].attribute = CCM_JOB_PTR_ATTRIBUTE_MLEN; + + ccm_job.in[3].ptr = (void *)((uint8_t *)_pkt_scratch + 0U); + ccm_job.in[3].length = sizeof(uint8_t); + ccm_job.in[3].attribute = CCM_JOB_PTR_ATTRIBUTE_ADATA; + + ccm_job.in[4].ptr = (void *)((uint8_t *)_pkt_scratch + 3U); + ccm_job.in[4].length = mlen; + ccm_job.in[4].attribute = CCM_JOB_PTR_ATTRIBUTE_MDATA; + + ccm_job.in[5].ptr = NULL; + ccm_job.in[5].length = 0U; + ccm_job.in[5].attribute = 0U; + + ccm_job.out[0].ptr = &ccm_job.out_alen; + ccm_job.out[0].length = sizeof(ccm_job.out_alen); + ccm_job.out[0].attribute = CCM_JOB_PTR_ATTRIBUTE_ALEN; + + ccm_job.out[1].ptr = (void *)((uint8_t *)pkt + 1U); + ccm_job.out[1].length = sizeof(uint8_t); + ccm_job.out[1].attribute = CCM_JOB_PTR_ATTRIBUTE_MLEN; + + ccm_job.out[2].ptr = &ccm_job.out_mlen_msb; + ccm_job.out[2].length = sizeof(ccm_job.out_mlen_msb); + ccm_job.out[2].attribute = CCM_JOB_PTR_ATTRIBUTE_MLEN; + + ccm_job.out[3].ptr = (void *)((uint8_t *)pkt + 0U); + ccm_job.out[3].length = sizeof(uint8_t); + ccm_job.out[3].attribute = CCM_JOB_PTR_ATTRIBUTE_ADATA; + + ccm_job.out[4].ptr = (void *)((uint8_t *)pkt + 3U); + ccm_job.out[4].length = mlen - sizeof(uint32_t); + ccm_job.out[4].attribute = CCM_JOB_PTR_ATTRIBUTE_MDATA; + + ccm_job.out[5].ptr = NULL; + ccm_job.out[5].length = 0U; + ccm_job.out[5].attribute = 0U; + + NRF_CCM->IN.PTR = (uint32_t)ccm_job.in; + NRF_CCM->OUT.PTR = (uint32_t)ccm_job.out; + + nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_END); + nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ERROR); + +#else /* !CONFIG_SOC_COMPATIBLE_NRF54LX */ NRF_CCM->CNFPTR = (uint32_t)cnf; NRF_CCM->INPTR = (uint32_t)_pkt_scratch; NRF_CCM->OUTPTR = (uint32_t)pkt; NRF_CCM->SCRATCHPTR = (uint32_t)_ccm_scratch; NRF_CCM->SHORTS = 0; + nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ENDKSGEN); nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_END); nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ERROR); nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_KSGEN); +#endif /* !CONFIG_SOC_COMPATIBLE_NRF54LX */ return _pkt_scratch; } @@ -2137,11 +2325,12 @@ static void *radio_ccm_ext_tx_pkt_set(struct ccm *cnf, uint8_t pdu_type, void *p NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Disabled; NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Enabled; + mode = (CCM_MODE_MODE_Encryption << CCM_MODE_MODE_Pos) & CCM_MODE_MODE_Msk; + #if defined(CONFIG_SOC_COMPATIBLE_NRF52X) || \ - defined(CONFIG_SOC_COMPATIBLE_NRF53X) || \ - defined(CONFIG_SOC_COMPATIBLE_NRF54LX) + defined(CONFIG_SOC_COMPATIBLE_NRF53X) /* Enable CCM support for 8-bit length field PDUs. */ mode |= (CCM_MODE_LENGTH_Extended << CCM_MODE_LENGTH_Pos) & CCM_MODE_LENGTH_Msk; @@ -2151,45 +2340,145 @@ static void *radio_ccm_ext_tx_pkt_set(struct ccm *cnf, uint8_t pdu_type, void *p */ mode |= (CCM_MODE_DATARATE_2Mbit << CCM_MODE_DATARATE_Pos) & CCM_MODE_DATARATE_Msk; -#endif -#if !defined(CONFIG_SOC_SERIES_NRF51X) && \ - !defined(CONFIG_SOC_NRF52832) && \ - (!defined(CONFIG_BT_CTLR_DATA_LENGTH_MAX) || \ - (CONFIG_BT_CTLR_DATA_LENGTH_MAX < ((HAL_RADIO_PDU_LEN_MAX) - 4))) - uint8_t max_len = (NRF_RADIO->PCNF1 & RADIO_PCNF1_MAXLEN_Msk) >> - RADIO_PCNF1_MAXLEN_Pos; +#elif defined(CONFIG_SOC_COMPATIBLE_NRF54LX) + /* Enable CCM Protocol Mode BLE */ + mode |= (CCM_MODE_PROTOCOL_Ble << CCM_MODE_PROTOCOL_Pos) & + CCM_MODE_PROTOCOL_Msk; - /* MAXPACKETSIZE value 0x001B (27) - 0x00FB (251) bytes */ - NRF_CCM->MAXPACKETSIZE = max_len - 4U; + /* NOTE: use fastest data rate as tx data needs to be prepared before + * radio Tx on any PHY. + */ + mode |= (CCM_MODE_DATARATE_4Mbit << CCM_MODE_DATARATE_Pos) & + CCM_MODE_DATARATE_Msk; + + /* Enable CCM MAC Length 4 bytes */ + mode |= (CCM_MODE_MACLEN_M4 << CCM_MODE_MACLEN_Pos) & + CCM_MODE_MACLEN_Msk; #endif + NRF_CCM->MODE = mode; + +#if defined(CONFIG_HAS_HW_NRF_CCM_HEADERMASK) || \ + defined(CONFIG_SOC_COMPATIBLE_NRF54LX) #if defined(CONFIG_HAS_HW_NRF_CCM_HEADERMASK) +#define ADATAMASK HEADERMASK +#endif /* CONFIG_HAS_HW_NRF_CCM_HEADERMASK */ switch (pdu_type) { case RADIO_PKT_CONF_PDU_TYPE_BIS: - NRF_CCM->HEADERMASK = 0xC3; /* mask CSSN and CSTF */ + NRF_CCM->ADATAMASK = 0xC3; /* mask CSSN and CSTF */ break; case RADIO_PKT_CONF_PDU_TYPE_CIS: - NRF_CCM->HEADERMASK = 0xA3; /* mask SN, NESN, CIE and NPI */ + NRF_CCM->ADATAMASK = 0xA3; /* mask SN, NESN, CIE and NPI */ break; default: - /* Using default reset value of HEADERMASK */ - NRF_CCM->HEADERMASK = 0xE3; /* mask SN, NESN and MD */ + /* Using default reset value of ADATAMASK */ + NRF_CCM->ADATAMASK = 0xE3; /* mask SN, NESN and MD */ break; } +#if defined(CONFIG_HAS_HW_NRF_CCM_HEADERMASK) +#undef ADATAMASK #endif /* CONFIG_HAS_HW_NRF_CCM_HEADERMASK */ +#endif /* CONFIG_HAS_HW_NRF_CCM_HEADERMASK || + * CONFIG_SOC_COMPATIBLE_NRF54LX + */ - NRF_CCM->MODE = mode; +#if !defined(CONFIG_SOC_SERIES_NRF51X) && \ + !defined(CONFIG_SOC_NRF52832) && \ + !defined(CONFIG_SOC_COMPATIBLE_NRF54LX) && \ + (!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) >> + RADIO_PCNF1_MAXLEN_Pos; + + /* MAXPACKETSIZE value 0x001B (27) - 0x00FB (251) bytes */ + NRF_CCM->MAXPACKETSIZE = max_len - 4U; +#endif + +#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) + /* 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]); + NRF_CCM->KEY.VALUE[1] = sys_get_be32(&cnf->key[8]); + NRF_CCM->KEY.VALUE[0] = sys_get_be32(&cnf->key[12]); + + NRF_CCM->NONCE.VALUE[3] = ((uint8_t *)&cnf->counter)[0]; + NRF_CCM->NONCE.VALUE[2] = sys_get_be32(&((uint8_t *)&cnf->counter)[1]) | + (cnf->direction << 7); + NRF_CCM->NONCE.VALUE[1] = sys_get_be32(&cnf->iv[0]); + NRF_CCM->NONCE.VALUE[0] = sys_get_be32(&cnf->iv[4]); + + const uint8_t alen = sizeof(uint8_t); + + ccm_job.in_alen = alen; + ccm_job.in[0].ptr = &ccm_job.in_alen; + ccm_job.in[0].length = sizeof(ccm_job.in_alen); + ccm_job.in[0].attribute = CCM_JOB_PTR_ATTRIBUTE_ALEN; + + const uint8_t mlen = *((uint8_t *)pkt + 1U); + + ccm_job.in_mlen = mlen; + ccm_job.in[1].ptr = &ccm_job.in_mlen; + ccm_job.in[1].length = sizeof(ccm_job.in_mlen); + ccm_job.in[1].attribute = CCM_JOB_PTR_ATTRIBUTE_MLEN; + + ccm_job.in[2].ptr = (void *)((uint8_t *)pkt + 0U); + ccm_job.in[2].length = alen; + ccm_job.in[2].attribute = CCM_JOB_PTR_ATTRIBUTE_ADATA; + + ccm_job.in[3].ptr = (void *)((uint8_t *)pkt + 3U); + ccm_job.in[3].length = mlen; + ccm_job.in[3].attribute = CCM_JOB_PTR_ATTRIBUTE_MDATA; + + ccm_job.in[4].ptr = NULL; + ccm_job.in[4].length = 0U; + ccm_job.in[4].attribute = 0U; + + ccm_job.out[0].ptr = &ccm_job.out_alen; + ccm_job.out[0].length = sizeof(ccm_job.out_alen); + ccm_job.out[0].attribute = CCM_JOB_PTR_ATTRIBUTE_ALEN; + + ccm_job.out[1].ptr = (void *)((uint8_t *)_pkt_scratch + 1U); + ccm_job.out[1].length = sizeof(uint8_t); + ccm_job.out[1].attribute = CCM_JOB_PTR_ATTRIBUTE_MLEN; + + ccm_job.out[2].ptr = &ccm_job.out_mlen_msb; + ccm_job.out[2].length = sizeof(ccm_job.out_mlen_msb); + ccm_job.out[2].attribute = CCM_JOB_PTR_ATTRIBUTE_MLEN; + + ccm_job.out[3].ptr = (void *)((uint8_t *)_pkt_scratch + 0U); + ccm_job.out[3].length = sizeof(uint8_t); + ccm_job.out[3].attribute = CCM_JOB_PTR_ATTRIBUTE_ADATA; + + ccm_job.out[4].ptr = (void *)((uint8_t *)_pkt_scratch + 3U); + ccm_job.out[4].length = mlen + sizeof(uint32_t); + ccm_job.out[4].attribute = CCM_JOB_PTR_ATTRIBUTE_MDATA; + + ccm_job.out[5].ptr = NULL; + ccm_job.out[5].length = 0U; + ccm_job.out[5].attribute = 0U; + + NRF_CCM->IN.PTR = (uint32_t)ccm_job.in; + NRF_CCM->OUT.PTR = (uint32_t)ccm_job.out; + + nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_END); + nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ERROR); + + nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_START); + +#else /* !CONFIG_SOC_COMPATIBLE_NRF54LX */ NRF_CCM->CNFPTR = (uint32_t)cnf; NRF_CCM->INPTR = (uint32_t)pkt; NRF_CCM->OUTPTR = (uint32_t)_pkt_scratch; NRF_CCM->SCRATCHPTR = (uint32_t)_ccm_scratch; NRF_CCM->SHORTS = CCM_SHORTS_ENDKSGEN_CRYPT_Msk; + nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ENDKSGEN); nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_END); nrf_ccm_event_clear(NRF_CCM, NRF_CCM_EVENT_ERROR); nrf_ccm_task_trigger(NRF_CCM, NRF_CCM_TASK_KSGEN); +#endif /* !CONFIG_SOC_COMPATIBLE_NRF54LX */ return _pkt_scratch; } diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h index bc5d1605302c..ae334df9af58 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio.h @@ -146,8 +146,10 @@ uint32_t radio_tmr_start_tick(uint8_t trx, uint32_t ticks_start); uint32_t radio_tmr_start_us(uint8_t trx, uint32_t us); uint32_t radio_tmr_start_now(uint8_t trx); uint32_t radio_tmr_start_get(void); +uint32_t radio_tmr_start_latency_get(void); void radio_tmr_stop(void); -void radio_tmr_hcto_configure(uint32_t hcto); +void radio_tmr_hcto_configure(uint32_t hcto_us); +void radio_tmr_hcto_configure_abs(uint32_t hcto_from_start_us); void radio_tmr_aa_capture(void); uint32_t radio_tmr_aa_get(void); void radio_tmr_aa_save(uint32_t aa); 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 327888e4dfec..07c40bd566ae 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 @@ -20,11 +20,7 @@ #define HAL_RADIO_NS2US_ROUND(ns) ((ns + 500)/1000) /* SoC specific defines */ -#if defined(CONFIG_BOARD_NRF52_BSIM) -#include "radio_sim_nrf52.h" -#elif defined(CONFIG_BOARD_NRF5340BSIM_NRF5340_CPUNET) -#include "radio_sim_nrf5340.h" -#elif defined(CONFIG_SOC_SERIES_NRF51X) +#if defined(CONFIG_SOC_SERIES_NRF51X) #include "radio_nrf51.h" #elif defined(CONFIG_SOC_NRF52805) #include "radio_nrf52805.h" @@ -43,9 +39,16 @@ #elif defined(CONFIG_SOC_NRF5340_CPUNET) #include #include "radio_nrf5340.h" -#elif defined(CONFIG_SOC_COMPATIBLE_NRF54LX) +#elif defined(CONFIG_SOC_SERIES_NRF54LX) #include "radio_nrf54lx.h" -#else /* !CONFIG_SOC_COMPATIBLE_NRF54LX */ +#elif defined(CONFIG_BOARD_NRF52_BSIM) +#include "radio_sim_nrf52.h" +#elif defined(CONFIG_BOARD_NRF5340BSIM_NRF5340_CPUNET) +#include +#include "radio_sim_nrf5340.h" +#elif defined(CONFIG_BOARD_NRF54L15BSIM_NRF54L15_CPUAPP) +#include "radio_sim_nrf54l.h" +#else #error "Unsupported SoC." #endif diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf51.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf51.h index 4ccb6f2e3099..faad07f4cbc8 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf51.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf51.h @@ -24,9 +24,10 @@ #define HAL_RADIO_NRF51_RX_CHAIN_DELAY_NS 3000 /* 3.0 */ /* HAL abstraction of Radio bitfields */ -#define HAL_RADIO_INTENSET_DISABLED_Msk RADIO_INTENSET_DISABLED_Msk -#define HAL_RADIO_SHORTS_TRX_END_DISABLE_Msk RADIO_SHORTS_END_DISABLE_Msk -#define HAL_RADIO_SHORTS_TRX_PHYEND_DISABLE_Msk RADIO_SHORTS_PHYEND_DISABLE_Msk +#define HAL_NRF_RADIO_EVENT_END NRF_RADIO_EVENT_END +#define HAL_RADIO_EVENTS_END EVENTS_END +#define HAL_RADIO_INTENSET_DISABLED_Msk RADIO_INTENSET_DISABLED_Msk +#define HAL_RADIO_SHORTS_TRX_END_DISABLE_Msk RADIO_SHORTS_END_DISABLE_Msk /* HAL abstraction of Radio IRQ number */ #define HAL_RADIO_IRQn RADIO_IRQn diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52805.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52805.h index ad4e1377d39c..ee96c07a5fc3 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52805.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52805.h @@ -186,9 +186,10 @@ #endif /* !CONFIG_BT_CTLR_RADIO_ENABLE_FAST */ /* HAL abstraction of Radio bitfields */ -#define HAL_RADIO_INTENSET_DISABLED_Msk RADIO_INTENSET_DISABLED_Msk -#define HAL_RADIO_SHORTS_TRX_END_DISABLE_Msk RADIO_SHORTS_END_DISABLE_Msk -#define HAL_RADIO_SHORTS_TRX_PHYEND_DISABLE_Msk RADIO_SHORTS_PHYEND_DISABLE_Msk +#define HAL_NRF_RADIO_EVENT_END NRF_RADIO_EVENT_END +#define HAL_RADIO_EVENTS_END EVENTS_END +#define HAL_RADIO_INTENSET_DISABLED_Msk RADIO_INTENSET_DISABLED_Msk +#define HAL_RADIO_SHORTS_TRX_END_DISABLE_Msk RADIO_SHORTS_END_DISABLE_Msk /* HAL abstraction of Radio IRQ number */ #define HAL_RADIO_IRQn RADIO_IRQn diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52810.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52810.h index b672f74cf9ae..7b22249ec928 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52810.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52810.h @@ -188,9 +188,10 @@ #endif /* !CONFIG_BT_CTLR_RADIO_ENABLE_FAST */ /* HAL abstraction of Radio bitfields */ -#define HAL_RADIO_INTENSET_DISABLED_Msk RADIO_INTENSET_DISABLED_Msk -#define HAL_RADIO_SHORTS_TRX_END_DISABLE_Msk RADIO_SHORTS_END_DISABLE_Msk -#define HAL_RADIO_SHORTS_TRX_PHYEND_DISABLE_Msk RADIO_SHORTS_PHYEND_DISABLE_Msk +#define HAL_NRF_RADIO_EVENT_END NRF_RADIO_EVENT_END +#define HAL_RADIO_EVENTS_END EVENTS_END +#define HAL_RADIO_INTENSET_DISABLED_Msk RADIO_INTENSET_DISABLED_Msk +#define HAL_RADIO_SHORTS_TRX_END_DISABLE_Msk RADIO_SHORTS_END_DISABLE_Msk /* HAL abstraction of Radio IRQ number */ #define HAL_RADIO_IRQn RADIO_IRQn diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52811.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52811.h index 9204ed3ac3ee..5caa59470b63 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52811.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52811.h @@ -343,6 +343,10 @@ #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_NRF_RADIO_EVENT_PHYEND NRF_RADIO_EVENT_PHYEND +#define HAL_RADIO_EVENTS_PHYEND EVENTS_PHYEND #define HAL_RADIO_INTENSET_DISABLED_Msk RADIO_INTENSET_DISABLED_Msk #define HAL_RADIO_SHORTS_TRX_END_DISABLE_Msk RADIO_SHORTS_END_DISABLE_Msk #define HAL_RADIO_SHORTS_TRX_PHYEND_DISABLE_Msk RADIO_SHORTS_PHYEND_DISABLE_Msk diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52820.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52820.h index c0be42698ad0..ab15f62f6857 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52820.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52820.h @@ -343,6 +343,10 @@ #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_NRF_RADIO_EVENT_PHYEND NRF_RADIO_EVENT_PHYEND +#define HAL_RADIO_EVENTS_PHYEND EVENTS_PHYEND #define HAL_RADIO_INTENSET_DISABLED_Msk RADIO_INTENSET_DISABLED_Msk #define HAL_RADIO_SHORTS_TRX_END_DISABLE_Msk RADIO_SHORTS_END_DISABLE_Msk #define HAL_RADIO_SHORTS_TRX_PHYEND_DISABLE_Msk RADIO_SHORTS_PHYEND_DISABLE_Msk diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52832.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52832.h index 398c92b5064d..10e942cca1e9 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52832.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52832.h @@ -189,9 +189,10 @@ #endif /* !CONFIG_BT_CTLR_RADIO_ENABLE_FAST */ /* HAL abstraction of Radio bitfields */ -#define HAL_RADIO_INTENSET_DISABLED_Msk RADIO_INTENSET_DISABLED_Msk -#define HAL_RADIO_SHORTS_TRX_END_DISABLE_Msk RADIO_SHORTS_END_DISABLE_Msk -#define HAL_RADIO_SHORTS_TRX_PHYEND_DISABLE_Msk RADIO_SHORTS_PHYEND_DISABLE_Msk +#define HAL_NRF_RADIO_EVENT_END NRF_RADIO_EVENT_END +#define HAL_RADIO_EVENTS_END EVENTS_END +#define HAL_RADIO_INTENSET_DISABLED_Msk RADIO_INTENSET_DISABLED_Msk +#define HAL_RADIO_SHORTS_TRX_END_DISABLE_Msk RADIO_SHORTS_END_DISABLE_Msk /* HAL abstraction of Radio IRQ number */ #define HAL_RADIO_IRQn RADIO_IRQn diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52833.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52833.h index 169f5c93714d..e8c55fc89524 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52833.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52833.h @@ -343,6 +343,10 @@ #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_NRF_RADIO_EVENT_PHYEND NRF_RADIO_EVENT_PHYEND +#define HAL_RADIO_EVENTS_PHYEND EVENTS_PHYEND #define HAL_RADIO_INTENSET_DISABLED_Msk RADIO_INTENSET_DISABLED_Msk #define HAL_RADIO_SHORTS_TRX_END_DISABLE_Msk RADIO_SHORTS_END_DISABLE_Msk #define HAL_RADIO_SHORTS_TRX_PHYEND_DISABLE_Msk RADIO_SHORTS_PHYEND_DISABLE_Msk diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52840.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52840.h index 07c9a7d6130b..80ab0f9e2410 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52840.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf52840.h @@ -346,9 +346,10 @@ #endif /* !CONFIG_BT_CTLR_RADIO_ENABLE_FAST */ /* HAL abstraction of Radio bitfields */ -#define HAL_RADIO_INTENSET_DISABLED_Msk RADIO_INTENSET_DISABLED_Msk -#define HAL_RADIO_SHORTS_TRX_END_DISABLE_Msk RADIO_SHORTS_END_DISABLE_Msk -#define HAL_RADIO_SHORTS_TRX_PHYEND_DISABLE_Msk RADIO_SHORTS_PHYEND_DISABLE_Msk +#define HAL_NRF_RADIO_EVENT_END NRF_RADIO_EVENT_END +#define HAL_RADIO_EVENTS_END EVENTS_END +#define HAL_RADIO_INTENSET_DISABLED_Msk RADIO_INTENSET_DISABLED_Msk +#define HAL_RADIO_SHORTS_TRX_END_DISABLE_Msk RADIO_SHORTS_END_DISABLE_Msk /* HAL abstraction of Radio IRQ number */ #define HAL_RADIO_IRQn RADIO_IRQn diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5340.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5340.h index f8b7635e7d14..a9638b62634c 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5340.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5340.h @@ -365,6 +365,12 @@ #endif /* 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_INTENSET_DISABLED_Msk #define HAL_RADIO_SHORTS_TRX_END_DISABLE_Msk RADIO_SHORTS_END_DISABLE_Msk #define HAL_RADIO_SHORTS_TRX_PHYEND_DISABLE_Msk RADIO_SHORTS_PHYEND_DISABLE_Msk diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf54lx.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf54lx.h index bc0cc2993c56..047e3ea24878 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf54lx.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf54lx.h @@ -361,6 +361,12 @@ #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 @@ -379,6 +385,19 @@ #define HAL_RADIO_RESET_VALUE_CTEINLINECONF 0x00002800UL #define HAL_RADIO_RESET_VALUE_DATAWHITE 0x00890040UL +/* HAL abstraction of CCM h/w */ +#define NRF_CCM NRF_CCM00 +#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 + static inline void hal_radio_reset(void) { /* TODO: Add any required setup for each radio event 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 1ddf9af1ccfb..06aea328eaf4 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 @@ -26,7 +26,7 @@ static inline void hal_radio_nrf_ppi_channels_disable(uint32_t mask) static inline void hal_radio_enable_on_tick_ppi_config_and_enable(uint8_t trx) { if (trx) { - nrf_timer_publish_set(EVENT_TIMER, NRF_TIMER_EVENT_COMPARE0, + nrf_timer_publish_set(EVENT_TIMER, HAL_EVENT_TIMER_TRX_EVENT, HAL_RADIO_ENABLE_TX_ON_TICK_PPI); nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_TXEN, HAL_RADIO_ENABLE_TX_ON_TICK_PPI); @@ -40,7 +40,7 @@ static inline void hal_radio_enable_on_tick_ppi_config_and_enable(uint8_t trx) nrf_dppi_channels_enable(NRF_DPPIC, BIT(HAL_RADIO_ENABLE_TX_ON_TICK_PPI)); } else { - nrf_timer_publish_set(EVENT_TIMER, NRF_TIMER_EVENT_COMPARE0, + nrf_timer_publish_set(EVENT_TIMER, HAL_EVENT_TIMER_TRX_EVENT, HAL_RADIO_ENABLE_RX_ON_TICK_PPI); nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_RXEN, HAL_RADIO_ENABLE_RX_ON_TICK_PPI); @@ -63,10 +63,10 @@ static inline void hal_radio_enable_on_tick_ppi_config_and_enable(uint8_t trx) */ static inline void hal_radio_recv_timeout_cancel_ppi_config(void) { - nrf_radio_publish_set(NRF_RADIO, - NRF_RADIO_EVENT_ADDRESS, HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI); - nrf_timer_subscribe_set(EVENT_TIMER, - NRF_TIMER_TASK_CAPTURE1, HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI); + nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_ADDRESS, + HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI); + nrf_timer_subscribe_set(EVENT_TIMER, HAL_EVENT_TIMER_ADDRESS_TASK, + HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI); } /******************************************************************************* @@ -76,10 +76,10 @@ static inline void hal_radio_recv_timeout_cancel_ppi_config(void) */ static inline void hal_radio_disable_on_hcto_ppi_config(void) { - nrf_timer_publish_set(EVENT_TIMER, - NRF_TIMER_EVENT_COMPARE1, HAL_RADIO_DISABLE_ON_HCTO_PPI); - nrf_radio_subscribe_set(NRF_RADIO, - NRF_RADIO_TASK_DISABLE, HAL_RADIO_DISABLE_ON_HCTO_PPI); + nrf_timer_publish_set(EVENT_TIMER, HAL_EVENT_TIMER_HCTO_EVENT, + HAL_RADIO_DISABLE_ON_HCTO_PPI); + nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_DISABLE, + HAL_RADIO_DISABLE_ON_HCTO_PPI); } /******************************************************************************* @@ -89,9 +89,9 @@ static inline void hal_radio_disable_on_hcto_ppi_config(void) */ static inline void hal_radio_end_time_capture_ppi_config(void) { - nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_END, HAL_RADIO_END_TIME_CAPTURE_PPI); - nrf_timer_subscribe_set(EVENT_TIMER, - NRF_TIMER_TASK_CAPTURE2, HAL_RADIO_END_TIME_CAPTURE_PPI); + nrf_radio_publish_set(NRF_RADIO, HAL_NRF_RADIO_EVENT_END, HAL_RADIO_END_TIME_CAPTURE_PPI); + nrf_timer_subscribe_set(EVENT_TIMER, HAL_EVENT_TIMER_TRX_END_TASK, + HAL_RADIO_END_TIME_CAPTURE_PPI); } /******************************************************************************* @@ -105,7 +105,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); - /* Enable same DPPI in Global domain */ + /* Enable same DPPI in Peripheral domain */ nrf_dppi_channels_enable(NRF_DPPIC20, BIT(HAL_EVENT_TIMER_START_PPI)); @@ -131,10 +131,10 @@ static inline void hal_event_timer_start_ppi_config(void) */ static inline void hal_radio_ready_time_capture_ppi_config(void) { - nrf_radio_publish_set(NRF_RADIO, - NRF_RADIO_EVENT_READY, HAL_RADIO_READY_TIME_CAPTURE_PPI); - nrf_timer_subscribe_set(EVENT_TIMER, - NRF_TIMER_TASK_CAPTURE0, HAL_RADIO_READY_TIME_CAPTURE_PPI); + nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_READY, + HAL_RADIO_READY_TIME_CAPTURE_PPI); + nrf_timer_subscribe_set(EVENT_TIMER, HAL_EVENT_TIMER_READY_TASK, + HAL_RADIO_READY_TIME_CAPTURE_PPI); } #if defined(CONFIG_BT_CTLR_LE_ENC) || defined(CONFIG_BT_CTLR_BROADCAST_ISO_ENC) @@ -147,9 +147,23 @@ static inline void hal_radio_ready_time_capture_ppi_config(void) */ static inline void hal_trigger_crypt_ppi_config(void) { - nrf_radio_publish_set(NRF_RADIO, - NRF_RADIO_EVENT_ADDRESS, HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI); - nrf_ccm_subscribe_set(NRF_CCM, NRF_CCM_TASK_START, HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI); + nrf_ccm_subscribe_set(NRF_CCM, NRF_CCM_TASK_START, HAL_TRIGGER_CRYPT_PPI); + +#if !defined(CONFIG_SOC_COMPATIBLE_NRF54LX) + nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_ADDRESS, HAL_TRIGGER_CRYPT_PPI); + +#else /* !CONFIG_SOC_COMPATIBLE_NRF54LX */ + nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_PAYLOAD, HAL_TRIGGER_CRYPT_PPI); + + /* Enable same DPPI in MCU domain */ + nrf_dppi_channels_enable(NRF_DPPIC00, BIT(HAL_TRIGGER_CRYPT_PPI)); + + /* Setup PPIB send subscribe */ + nrf_ppib_subscribe_set(NRF_PPIB10, HAL_PPIB_SEND_TRIGGER_CRYPT_PPI, HAL_TRIGGER_CRYPT_PPI); + + /* Setup PPIB receive publish */ + nrf_ppib_publish_set(NRF_PPIB00, HAL_PPIB_RECEIVE_TRIGGER_CRYPT_PPI, HAL_TRIGGER_CRYPT_PPI); +#endif /* !CONFIG_SOC_COMPATIBLE_NRF54LX */ } /******************************************************************************* @@ -160,6 +174,7 @@ static inline void hal_trigger_crypt_ppi_disable(void) nrf_ccm_subscribe_clear(NRF_CCM, NRF_CCM_TASK_START); } +#if defined(CONFIG_BT_CTLR_PRIVACY) /******************************************************************************* * Trigger automatic address resolution on Bit counter match: * wire the RADIO EVENTS_BCMATCH event to the AAR TASKS_START task. @@ -169,6 +184,7 @@ static inline void hal_trigger_aar_ppi_config(void) nrf_radio_publish_set(NRF_RADIO, NRF_RADIO_EVENT_BCMATCH, HAL_TRIGGER_AAR_PPI); nrf_aar_subscribe_set(NRF_AAR, NRF_AAR_TASK_START, HAL_TRIGGER_AAR_PPI); } +#endif /* CONFIG_BT_CTLR_PRIVACY */ /* When hardware does not support Coded PHY we still allow the Controller * implementation to accept Coded PHY flags, but the Controller will use 1M @@ -215,16 +231,14 @@ static inline void hal_trigger_crypt_by_bcmatch_ppi_config(void) /******************************************************************************/ #if !defined(CONFIG_BT_CTLR_TIFS_HW) -#if !defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) -#define NRF_RADIO_PUBLISH_PDU_END_EVT PUBLISH_PHYEND -/* Wrappenr for EVENTS_END event name used by nRFX API */ -#define NRFX_RADIO_TXRX_END_EVENT NRF_RADIO_EVENT_PHYEND -#else /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ -#define NRF_RADIO_PUBLISH_PDU_END_EVT PUBLISH_END -#define NRFX_RADIO_TXRX_END_EVENT NRF_RADIO_EVENT_END -#endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ - /* DPPI setup used for SW-based auto-switching during TIFS. */ +#if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) +#define HAL_NRF_RADIO_TIFS_DPPI_EVENT_END HAL_NRF_RADIO_EVENT_END +#define HAL_RADIO_TIFS_DPPI_PUBLISH_END HAL_RADIO_PUBLISH_END +#else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ +#define HAL_NRF_RADIO_TIFS_DPPI_EVENT_END HAL_NRF_RADIO_EVENT_PHYEND +#define HAL_RADIO_TIFS_DPPI_PUBLISH_END HAL_RADIO_PUBLISH_PHYEND +#endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ /* Clear SW-switch timer on packet end: * wire the RADIO EVENTS_END event to SW_SWITCH_TIMER TASKS_CLEAR task. @@ -236,7 +250,8 @@ static inline void hal_trigger_crypt_by_bcmatch_ppi_config(void) */ static inline void hal_sw_switch_timer_clear_ppi_config(void) { - nrf_radio_publish_set(NRF_RADIO, NRFX_RADIO_TXRX_END_EVENT, HAL_SW_SWITCH_TIMER_CLEAR_PPI); + nrf_radio_publish_set(NRF_RADIO, HAL_NRF_RADIO_TIFS_DPPI_EVENT_END, + HAL_SW_SWITCH_TIMER_CLEAR_PPI); nrf_timer_subscribe_set(SW_SWITCH_TIMER, NRF_TIMER_TASK_CLEAR, HAL_SW_SWITCH_TIMER_CLEAR_PPI); @@ -305,7 +320,8 @@ static inline void hal_sw_switch_timer_clear_ppi_config(void) * Note: we do not need an additional PPI, since we have already set up * a PPI to publish RADIO END event. */ -#define HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_EVT (NRF_RADIO->NRF_RADIO_PUBLISH_PDU_END_EVT) +#define HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_REGISTER_EVT \ + (NRF_RADIO->HAL_RADIO_TIFS_DPPI_PUBLISH_END) #define HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_EVT \ (((HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI << \ RADIO_PUBLISH_END_CHIDX_Pos) \ @@ -432,7 +448,7 @@ static inline void hal_radio_b2b_txen_on_sw_switch(uint8_t compare_reg_index, HAL_SW_SWITCH_RADIO_ENABLE_PPI_REGISTER_EVT(compare_reg_index) = HAL_SW_SWITCH_RADIO_ENABLE_PPI_EVT(radio_enable_ppi); - uint8_t prev_ppi_idx = (compare_reg_index + 0x01) & 0x01; + uint8_t prev_ppi_idx = (compare_reg_index + 0x01 - SW_SWITCH_TIMER_EVTS_COMP_BASE) & 0x01; radio_enable_ppi = HAL_SW_SWITCH_RADIO_ENABLE_PPI(prev_ppi_idx); nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_TXEN, radio_enable_ppi); @@ -464,7 +480,7 @@ static inline void hal_radio_b2b_rxen_on_sw_switch(uint8_t compare_reg_index, HAL_SW_SWITCH_RADIO_ENABLE_PPI_REGISTER_EVT(compare_reg_index) = HAL_SW_SWITCH_RADIO_ENABLE_PPI_EVT(radio_enable_ppi); - uint8_t prev_ppi_idx = (compare_reg_index + 0x01) & 0x01; + uint8_t prev_ppi_idx = (compare_reg_index + 0x01 - SW_SWITCH_TIMER_EVTS_COMP_BASE) & 0x01; radio_enable_ppi = HAL_SW_SWITCH_RADIO_ENABLE_PPI(prev_ppi_idx); nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_RXEN, radio_enable_ppi); @@ -492,7 +508,7 @@ static inline void hal_radio_sw_switch_b2b_tx_disable(uint8_t compare_reg_index) { hal_radio_sw_switch_disable(); - uint8_t prev_ppi_idx = (compare_reg_index + 0x01) & 0x01; + uint8_t prev_ppi_idx = (compare_reg_index + 0x01 - SW_SWITCH_TIMER_EVTS_COMP_BASE) & 0x01; uint8_t radio_enable_ppi = HAL_SW_SWITCH_RADIO_ENABLE_PPI(prev_ppi_idx); nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_TXEN, radio_enable_ppi); @@ -502,7 +518,7 @@ static inline void hal_radio_sw_switch_b2b_rx_disable(uint8_t compare_reg_index) { hal_radio_sw_switch_disable(); - uint8_t prev_ppi_idx = (compare_reg_index + 0x01) & 0x01; + uint8_t prev_ppi_idx = (compare_reg_index + 0x01 - SW_SWITCH_TIMER_EVTS_COMP_BASE) & 0x01; uint8_t radio_enable_ppi = HAL_SW_SWITCH_RADIO_ENABLE_PPI(prev_ppi_idx); nrf_radio_subscribe_set(NRF_RADIO, NRF_RADIO_TASK_RXEN, radio_enable_ppi); @@ -543,7 +559,7 @@ static inline void hal_radio_sw_switch_coded_tx_config_set(uint8_t ppi_en, HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI_REGISTER_EVT = HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI_EVT; nrf_timer_subscribe_set(SW_SWITCH_TIMER, - nrf_timer_capture_task_get(cc_s2), + nrf_timer_capture_task_get(SW_SWITCH_TIMER_EVTS_COMP(group_index)), HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI); nrf_dppi_channels_enable(NRF_DPPIC, 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 8bb3fc1c9f0b..5433d0d3eec3 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 @@ -8,35 +8,35 @@ * Enable Radio on Event Timer tick: * wire the EVENT_TIMER EVENTS_COMPARE[0] event to RADIO TASKS_TXEN/RXEN task. */ -#define HAL_RADIO_ENABLE_TX_ON_TICK_PPI 6 -#define HAL_RADIO_ENABLE_RX_ON_TICK_PPI 6 +#define HAL_RADIO_ENABLE_TX_ON_TICK_PPI 9 +#define HAL_RADIO_ENABLE_RX_ON_TICK_PPI 9 /******************************************************************************* * Capture event timer on Address reception: * wire the RADIO EVENTS_ADDRESS event to the * EVENT_TIMER TASKS_CAPTURE[
] task. */ -#define HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI 9 +#define HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI 11 /******************************************************************************* * Disable Radio on HCTO: * wire the EVENT_TIMER EVENTS_COMPARE[] event * to the RADIO TASKS_DISABLE task. */ -#define HAL_RADIO_DISABLE_ON_HCTO_PPI 10 +#define HAL_RADIO_DISABLE_ON_HCTO_PPI 12 /******************************************************************************* * Capture event timer on Radio end: * wire the RADIO EVENTS_END event to the * EVENT_TIMER TASKS_CAPTURE[] task. */ -#define HAL_RADIO_END_TIME_CAPTURE_PPI 11 +#define HAL_RADIO_END_TIME_CAPTURE_PPI 13 /******************************************************************************* * 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 7 +#define HAL_EVENT_TIMER_START_PPI 8 #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 \ @@ -47,7 +47,7 @@ * wire the RADIO EVENTS_READY event to the * EVENT_TIMER TASKS_CAPTURE[] task. */ -#define HAL_RADIO_READY_TIME_CAPTURE_PPI 8 +#define HAL_RADIO_READY_TIME_CAPTURE_PPI 10 /******************************************************************************* * Trigger encryption task upon address reception: @@ -55,34 +55,44 @@ * * Note: we do not need an additional PPI, since we have already set up * a PPI to publish RADIO ADDRESS event. + * Note: For nRF54L, CCM is started on RADIO PAYLOAD, hence need an explicit + * PPI channel. */ +#if defined(CONFIG_SOC_COMPATIBLE_NRF54LX) +#define HAL_TRIGGER_CRYPT_PPI 7 +#else /* CONFIG_SOC_COMPATIBLE_NRF54LX */ #define HAL_TRIGGER_CRYPT_PPI HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI +#endif /* CONFIG_SOC_COMPATIBLE_NRF54LX */ +#define HAL_PPIB_SEND_TRIGGER_CRYPT_PPI \ + _CONCAT(NRF_PPIB_TASK_SEND_, HAL_TRIGGER_CRYPT_PPI) +#define HAL_PPIB_RECEIVE_TRIGGER_CRYPT_PPI \ + _CONCAT(NRF_PPIB_EVENT_RECEIVE_, HAL_TRIGGER_CRYPT_PPI) /******************************************************************************* * Trigger automatic address resolution on Bit counter match: * wire the RADIO EVENTS_BCMATCH event to the AAR TASKS_START task. */ -#define HAL_TRIGGER_AAR_PPI 12 +#define HAL_TRIGGER_AAR_PPI 6 #if defined(CONFIG_BT_CTLR_PHY_CODED) && \ defined(CONFIG_HAS_HW_NRF_RADIO_BLE_CODED) /******************************************************************************* * Trigger Radio Rate override upon Rateboost event. */ -#define HAL_TRIGGER_RATEOVERRIDE_PPI 13 +#define HAL_TRIGGER_RATEOVERRIDE_PPI 3 #endif /* CONFIG_BT_CTLR_PHY_CODED && CONFIG_HAS_HW_NRF_RADIO_BLE_CODED */ #if defined(HAL_RADIO_GPIO_HAVE_PA_PIN) || defined(HAL_RADIO_GPIO_HAVE_LNA_PIN) /******************************************************************************/ -#define HAL_ENABLE_PALNA_PPI 5 +#define HAL_ENABLE_PALNA_PPI 2 #if defined(HAL_RADIO_FEM_IS_NRF21540) -#define HAL_DISABLE_PALNA_PPI 4 +#define HAL_DISABLE_PALNA_PPI 0 #else #define HAL_DISABLE_PALNA_PPI HAL_ENABLE_PALNA_PPI #endif -#define HAL_ENABLE_FEM_PPI 3 +#define HAL_ENABLE_FEM_PPI 1 #define HAL_DISABLE_FEM_PPI HAL_DISABLE_PALNA_PPI #endif /* HAL_RADIO_GPIO_HAVE_PA_PIN || HAL_RADIO_GPIO_HAVE_LNA_PIN */ @@ -94,16 +104,16 @@ /* Clear SW-switch timer on packet end: * wire the RADIO EVENTS_END event to SW_SWITCH_TIMER TASKS_CLEAR task. * - * Note: In case of HW TIFS support or single timer configuration we do not need - * an additional PPI, since we have already set up a PPI to publish RADIO END - * event. In other case separate PPI is used because packet end is marked by - * PHYEND event while last bit or CRC is marked by END event. + * Note: In case of single timer configuration we do not need an additional PPI, + * since we have already set up a PPI to publish RADIO END event. In other case + * separate PPI is used because packet end is marked by PHYEND event while last + * bit or CRC is marked by END event. */ -#if !defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) -#define HAL_SW_SWITCH_TIMER_CLEAR_PPI 24 -#else /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ +#if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) #define HAL_SW_SWITCH_TIMER_CLEAR_PPI HAL_RADIO_END_TIME_CAPTURE_PPI -#endif /* CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ +#else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ +#define HAL_SW_SWITCH_TIMER_CLEAR_PPI 24 +#endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ /* Wire a SW SWITCH TIMER EVENTS_COMPARE[] event * to a PPI GROUP TASK DISABLE task (PPI group with index ). @@ -162,11 +172,11 @@ * when direction finding RX and PHY is set to PHY1M. Due to that it can be shared with Radio Rate * override. */ -#define HAL_TRIGGER_CRYPT_DELAY_PPI 13 +#define HAL_TRIGGER_CRYPT_DELAY_PPI 3 #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RX */ /* The 2 adjacent PPI groups used for implementing SW_SWITCH_TIMER-based * auto-switch for TIFS. 'index' must be 0 or 1. */ -#define SW_SWITCH_TIMER_TASK_GROUP_BASE 0 +#define SW_SWITCH_TIMER_TASK_GROUP_BASE 4 #endif /* !CONFIG_BT_CTLR_TIFS_HW */ diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h index 8185036fbc3b..05445e1fb48b 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_ppi.h @@ -63,7 +63,7 @@ static inline void hal_radio_enable_on_tick_ppi_config_and_enable(uint8_t trx) if (trx) { nrf_ppi_channel_endpoint_setup(NRF_PPI, HAL_RADIO_ENABLE_TX_ON_TICK_PPI, - (uint32_t)&(EVENT_TIMER->EVENTS_COMPARE[0]), + (uint32_t)&(EVENT_TIMER->EVENTS_COMPARE[HAL_EVENT_TIMER_TRX_CC_OFFSET]), (uint32_t)&(NRF_RADIO->TASKS_TXEN)); #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) @@ -80,7 +80,7 @@ static inline void hal_radio_enable_on_tick_ppi_config_and_enable(uint8_t trx) } else { nrf_ppi_channel_endpoint_setup(NRF_PPI, HAL_RADIO_ENABLE_RX_ON_TICK_PPI, - (uint32_t)&(EVENT_TIMER->EVENTS_COMPARE[0]), + (uint32_t)&(EVENT_TIMER->EVENTS_COMPARE[HAL_EVENT_TIMER_TRX_CC_OFFSET]), (uint32_t)&(NRF_RADIO->TASKS_RXEN)); #if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) @@ -122,7 +122,7 @@ static inline void hal_radio_recv_timeout_cancel_ppi_config(void) NRF_PPI, HAL_RADIO_RECV_TIMEOUT_CANCEL_PPI, (uint32_t)&(NRF_RADIO->EVENTS_ADDRESS), - (uint32_t)&(EVENT_TIMER->TASKS_CAPTURE[1])); + (uint32_t)&(EVENT_TIMER->TASKS_CAPTURE[HAL_EVENT_TIMER_HCTO_CC_OFFSET])); } #endif /* (EVENT_TIMER_ID == 0) */ @@ -149,7 +149,7 @@ static inline void hal_radio_disable_on_hcto_ppi_config(void) nrf_ppi_channel_endpoint_setup( NRF_PPI, HAL_RADIO_DISABLE_ON_HCTO_PPI, - (uint32_t)&(EVENT_TIMER->EVENTS_COMPARE[1]), + (uint32_t)&(EVENT_TIMER->EVENTS_COMPARE[HAL_EVENT_TIMER_HCTO_CC_OFFSET]), (uint32_t)&(NRF_RADIO->TASKS_DISABLE)); } @@ -177,8 +177,8 @@ static inline void hal_radio_end_time_capture_ppi_config(void) nrf_ppi_channel_endpoint_setup( NRF_PPI, HAL_RADIO_END_TIME_CAPTURE_PPI, - (uint32_t)&(NRF_RADIO->NRF_RADIO_TRX_END_EVENT), - (uint32_t)&(EVENT_TIMER->TASKS_CAPTURE[2])); + (uint32_t)&(NRF_RADIO->HAL_RADIO_TRX_EVENTS_END), + (uint32_t)&(EVENT_TIMER->TASKS_CAPTURE[HAL_EVENT_TIMER_TRX_END_CC_OFFSET])); } #endif /* (EVENT_TIMER_ID == 0) */ @@ -207,7 +207,7 @@ static inline void hal_radio_ready_time_capture_ppi_config(void) NRF_PPI, HAL_RADIO_READY_TIME_CAPTURE_PPI, (uint32_t)&(NRF_RADIO->EVENTS_READY), - (uint32_t)&(EVENT_TIMER->TASKS_CAPTURE[0])); + (uint32_t)&(EVENT_TIMER->TASKS_CAPTURE[HAL_EVENT_TIMER_TRX_CC_OFFSET])); } /******************************************************************************* @@ -303,7 +303,7 @@ static inline void hal_sw_switch_timer_clear_ppi_config(void) nrf_ppi_channel_endpoint_setup( NRF_PPI, HAL_SW_SWITCH_TIMER_CLEAR_PPI, - (uint32_t)&(NRF_RADIO->NRF_RADIO_TRX_END_EVENT), + (uint32_t)&(NRF_RADIO->HAL_RADIO_TRX_EVENTS_END), (uint32_t)&(SW_SWITCH_TIMER->TASKS_CLEAR)); } @@ -364,7 +364,7 @@ static inline void hal_sw_switch_timer_clear_ppi_config(void) * 'index' must be 0 or 1. */ #define HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_EVT \ - ((uint32_t)&(NRF_RADIO->NRF_RADIO_TRX_END_EVENT)) + ((uint32_t)&(NRF_RADIO->HAL_RADIO_TRX_EVENTS_END)) #define HAL_SW_SWITCH_GROUP_TASK_ENABLE_PPI_TASK(index) \ ((uint32_t)&(NRF_PPI->TASKS_CHG[SW_SWITCH_TIMER_TASK_GROUP(index)].EN)) @@ -517,7 +517,8 @@ static inline void hal_radio_sw_switch_coded_tx_config_set(uint8_t ppi_en, nrf_ppi_event_endpoint_setup(NRF_PPI, HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI, HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI_EVT); nrf_ppi_task_endpoint_setup(NRF_PPI, HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI, - HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI_TASK(cc_s2)); + HAL_SW_SWITCH_TIMER_S8_DISABLE_PPI_TASK( + SW_SWITCH_TIMER_EVTS_COMP(group_index))); nrf_ppi_channels_enable( NRF_PPI, diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_resources.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_resources.h index 618e1535839e..8bd540bbfa65 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_resources.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_resources.h @@ -18,7 +18,7 @@ * or reception of a PDU on air. In case of regular PDU it is generated when last bit of CRC is * received or transmitted. */ -#define NRF_RADIO_TRX_END_EVENT EVENTS_END +#define HAL_RADIO_TRX_EVENTS_END HAL_RADIO_EVENTS_END /* Wrapper for RADIO_SHORTS mask connecting EVENTS_END to EVENTS_DISABLE. * This is a default shortcut used to automatically disable Radio after end of PDU. @@ -27,9 +27,14 @@ #define HAL_EVENT_TIMER_TRX_CC_OFFSET 0 #define HAL_EVENT_TIMER_TRX_EVENT NRF_TIMER_EVENT_COMPARE0 +#define HAL_EVENT_TIMER_READY_TASK NRF_TIMER_TASK_CAPTURE0 #define HAL_EVENT_TIMER_HCTO_CC_OFFSET 1 +#define HAL_EVENT_TIMER_HCTO_EVENT NRF_TIMER_EVENT_COMPARE1 +#define HAL_EVENT_TIMER_ADDRESS_TASK NRF_TIMER_TASK_CAPTURE1 + #define HAL_EVENT_TIMER_TRX_END_CC_OFFSET 2 +#define HAL_EVENT_TIMER_TRX_END_TASK NRF_TIMER_TASK_CAPTURE2 #define HAL_EVENT_TIMER_DEFERRED_TRX_CC_OFFSET 2 #define HAL_EVENT_TIMER_DEFERRED_TX_EVENT NRF_TIMER_EVENT_COMPARE2 @@ -50,18 +55,27 @@ /* Radio ISR Latency to be considered with single timer used so that the PPI/ * DPPI is disabled in time when the timer is cleared on radio end, so that * the timer compare should not trigger TXEN/RXEN immediately on radio end. + * This value will be used as minimum turnaround time in setting up Rx to Tx + * using radio_tmr_start_us under single timer use. + * The value of 80 us is used considering 150 us TIFS minus the maximum rx + * chain delay ~30 us, and minus the radio ramp up delay ~40 us. */ -#define HAL_RADIO_ISR_LATENCY_MAX_US 150U +#define HAL_RADIO_ISR_LATENCY_MAX_US 80U + +#if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RX) +/* Delay of CCM TASKS_CRYPT start in number of bits for Radio Bit counter */ +#define CCM_TASKS_CRYPT_DELAY_BITS 3 +#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RX */ #if defined(CONFIG_BT_CTLR_PHY_CODED) -#define SW_SWITCH_TIMER_EVTS_COMP_BASE 3 -#define SW_SWITCH_TIMER_EVTS_COMP_S2_BASE 5 +#define SW_SWITCH_TIMER_EVTS_COMP_BASE 4 +#define SW_SWITCH_TIMER_EVTS_COMP_S2_BASE 6 /* Wrapper for EVENTS_END event generated by Radio peripheral at the very end of the transmission * or reception of a PDU on air. In case of regular PDU it is generated when last bit of CRC is * received or transmitted. */ -#define NRF_RADIO_TRX_END_EVENT EVENTS_END +#define HAL_RADIO_TRX_EVENTS_END HAL_RADIO_EVENTS_END /* Wrapper for RADIO_SHORTS mask connecting EVENTS_END to EVENTS_DISABLE. * This is a default shortcut used to automatically disable Radio after end of PDU. @@ -70,15 +84,20 @@ #define HAL_EVENT_TIMER_TRX_CC_OFFSET 0 #define HAL_EVENT_TIMER_TRX_EVENT NRF_TIMER_EVENT_COMPARE0 +#define HAL_EVENT_TIMER_READY_TASK NRF_TIMER_TASK_CAPTURE0 #define HAL_EVENT_TIMER_HCTO_CC_OFFSET 1 +#define HAL_EVENT_TIMER_HCTO_EVENT NRF_TIMER_EVENT_COMPARE1 +#define HAL_EVENT_TIMER_ADDRESS_TASK NRF_TIMER_TASK_CAPTURE1 + #define HAL_EVENT_TIMER_TRX_END_CC_OFFSET 2 +#define HAL_EVENT_TIMER_TRX_END_TASK NRF_TIMER_TASK_CAPTURE2 #define HAL_EVENT_TIMER_DEFERRED_TRX_CC_OFFSET 2 #define HAL_EVENT_TIMER_DEFERRED_TX_EVENT NRF_TIMER_EVENT_COMPARE2 -#define HAL_EVENT_TIMER_SAMPLE_CC_OFFSET 2 -#define HAL_EVENT_TIMER_SAMPLE_TASK NRF_TIMER_TASK_CAPTURE2 +#define HAL_EVENT_TIMER_SAMPLE_CC_OFFSET 3 +#define HAL_EVENT_TIMER_SAMPLE_TASK NRF_TIMER_TASK_CAPTURE3 #define HAL_EVENT_TIMER_PA_LNA_CC_OFFSET 2 #define HAL_EVENT_TIMER_PA_LNA_PDN_CC_OFFSET 3 @@ -90,7 +109,7 @@ * or reception of a PDU on air. In case of regular PDU it is generated when last bit of CRC is * received or transmitted. */ -#define NRF_RADIO_TRX_END_EVENT EVENTS_END +#define HAL_RADIO_TRX_EVENTS_END HAL_RADIO_EVENTS_END /* Wrapper for RADIO_SHORTS mask connecting EVENTS_END to EVENTS_DISABLE. * This is a default shortcut used to automatically disable Radio after end of PDU. @@ -99,9 +118,14 @@ #define HAL_EVENT_TIMER_TRX_CC_OFFSET 0 #define HAL_EVENT_TIMER_TRX_EVENT NRF_TIMER_EVENT_COMPARE0 +#define HAL_EVENT_TIMER_READY_TASK NRF_TIMER_TASK_CAPTURE0 #define HAL_EVENT_TIMER_HCTO_CC_OFFSET 1 +#define HAL_EVENT_TIMER_HCTO_EVENT NRF_TIMER_EVENT_COMPARE1 +#define HAL_EVENT_TIMER_ADDRESS_TASK NRF_TIMER_TASK_CAPTURE1 + #define HAL_EVENT_TIMER_TRX_END_CC_OFFSET 2 +#define HAL_EVENT_TIMER_TRX_END_TASK NRF_TIMER_TASK_CAPTURE2 #define HAL_EVENT_TIMER_DEFERRED_TRX_CC_OFFSET 2 #define HAL_EVENT_TIMER_DEFERRED_TX_EVENT NRF_TIMER_EVENT_COMPARE2 @@ -149,7 +173,7 @@ * including CTE EVENTS_PHYEND event is generated at very end of a PDU. In case there is no CTE in * a PDU the EVENTS_PHYEND event is generated in the same instant as EVENTS_END event. */ -#define NRF_RADIO_TRX_END_EVENT EVENTS_PHYEND +#define HAL_RADIO_TRX_EVENTS_END HAL_RADIO_EVENTS_PHYEND /* Wrapper for RADIO_SHORTS mask connecting EVENTS_PHYEND to EVENTS_DISABLE. * This is a mask for SOC that has Direction Finding Extension in a Radio peripheral. @@ -162,15 +186,17 @@ /* Delay of EVENTS_PHYEND event on receive PDU without CTE included when CTEINLINE is enabled */ #define RADIO_EVENTS_PHYEND_DELAY_US 16 +#if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RX) /* Delay of CCM TASKS_CRYPT start in number of bits for Radio Bit counter */ #define CCM_TASKS_CRYPT_DELAY_BITS 3 +#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_RX */ #else /* !CONFIG_BT_CTLR_DF */ /* Wrapper for EVENTS_END event generated by Radio peripheral at the very end of the transmission * or reception of a PDU on air. In case of regular PDU it is generated when last bit of CRC is * received or transmitted. */ -#define NRF_RADIO_TRX_END_EVENT EVENTS_END +#define HAL_RADIO_TRX_EVENTS_END HAL_RADIO_EVENTS_END /* Wrapper for RADIO_SHORTS mask connecting EVENTS_END to EVENTS_DISABLE. * This is a default shortcut used to automatically disable Radio after end of PDU. @@ -180,9 +206,14 @@ #define HAL_EVENT_TIMER_TRX_CC_OFFSET 0 #define HAL_EVENT_TIMER_TRX_EVENT NRF_TIMER_EVENT_COMPARE0 +#define HAL_EVENT_TIMER_READY_TASK NRF_TIMER_TASK_CAPTURE0 #define HAL_EVENT_TIMER_HCTO_CC_OFFSET 1 +#define HAL_EVENT_TIMER_HCTO_EVENT NRF_TIMER_EVENT_COMPARE1 +#define HAL_EVENT_TIMER_ADDRESS_TASK NRF_TIMER_TASK_CAPTURE1 + #define HAL_EVENT_TIMER_TRX_END_CC_OFFSET 2 +#define HAL_EVENT_TIMER_TRX_END_TASK NRF_TIMER_TASK_CAPTURE2 #define HAL_EVENT_TIMER_DEFERRED_TRX_CC_OFFSET 2 #define HAL_EVENT_TIMER_DEFERRED_TX_EVENT NRF_TIMER_EVENT_COMPARE2 diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf52.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf52.h index 8e4838ef10ed..099f073f30c3 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf52.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf52.h @@ -6,12 +6,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -/* - * This header needs lots of types and macros, instead of relaying on - * good inclusion order let's pull them through soc.h - */ -#include - /* Use the NRF_RTC instance for coarse radio event scheduling */ #define NRF_RTC NRF_RTC0 @@ -156,10 +150,9 @@ */ #define HAL_RADIO_NRF52833_RXEN_RXIDLE_RX_2M_DEFAULT_NO_HW_TIFS_NS 129000 #define HAL_RADIO_NRF52833_RXEN_RXIDLE_RX_2M_DEFAULT_NO_HW_TIFS_US \ - HAL_RADIO_NS2US_CEIL(\ + HAL_RADIO_NS2US_CEIL( \ HAL_RADIO_NRF52833_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]. */ @@ -352,13 +345,27 @@ #endif /* !CONFIG_BT_CTLR_RADIO_ENABLE_FAST */ /* HAL abstraction of Radio bitfields */ -#define HAL_RADIO_INTENSET_DISABLED_Msk RADIO_INTENSET_DISABLED_Msk -#define HAL_RADIO_SHORTS_TRX_END_DISABLE_Msk RADIO_SHORTS_END_DISABLE_Msk -#define HAL_RADIO_SHORTS_TRX_PHYEND_DISABLE_Msk RADIO_SHORTS_PHYEND_DISABLE_Msk +#define HAL_NRF_RADIO_EVENT_END NRF_RADIO_EVENT_END +#define HAL_RADIO_EVENTS_END EVENTS_END +#define HAL_NRF_RADIO_EVENT_PHYEND NRF_RADIO_EVENT_PHYEND +#define HAL_RADIO_EVENTS_PHYEND EVENTS_PHYEND +#define HAL_RADIO_INTENSET_DISABLED_Msk RADIO_INTENSET_DISABLED_Msk +#define HAL_RADIO_SHORTS_TRX_END_DISABLE_Msk RADIO_SHORTS_END_DISABLE_Msk +#define HAL_RADIO_SHORTS_TRX_PHYEND_DISABLE_Msk RADIO_SHORTS_PHYEND_DISABLE_Msk +#define HAL_RADIO_CLEARPATTERN_CLEARPATTERN_Clear RADIO_CLEARPATTERN_CLEARPATTERN_Clear /* HAL abstraction of Radio IRQ number */ #define HAL_RADIO_IRQn RADIO_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 + static inline void hal_radio_reset(void) { } diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf5340.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf5340.h index 6e115926c41c..ff31a6693cfe 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf5340.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf5340.h @@ -5,9 +5,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include -#include - /* Use the NRF_RTC instance for coarse radio event scheduling */ #define NRF_RTC NRF_RTC0 @@ -366,9 +363,16 @@ #endif /* HAL abstraction of Radio bitfields */ -#define HAL_RADIO_INTENSET_DISABLED_Msk RADIO_INTENSET_DISABLED_Msk -#define HAL_RADIO_SHORTS_TRX_END_DISABLE_Msk RADIO_SHORTS_END_DISABLE_Msk -#define HAL_RADIO_SHORTS_TRX_PHYEND_DISABLE_Msk RADIO_SHORTS_PHYEND_DISABLE_Msk +#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_INTENSET_DISABLED_Msk +#define HAL_RADIO_SHORTS_TRX_END_DISABLE_Msk RADIO_SHORTS_END_DISABLE_Msk +#define HAL_RADIO_SHORTS_TRX_PHYEND_DISABLE_Msk RADIO_SHORTS_PHYEND_DISABLE_Msk +#define HAL_RADIO_CLEARPATTERN_CLEARPATTERN_Clear RADIO_CLEARPATTERN_CLEARPATTERN_Clear /* HAL abstraction of Radio IRQ number */ #define HAL_RADIO_IRQn RADIO_IRQn diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf54l.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf54l.h new file mode 100644 index 000000000000..047e3ea24878 --- /dev/null +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_sim_nrf54l.h @@ -0,0 +1,832 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Use the NRF_RTC instance for coarse radio event scheduling */ +#if !defined(CONFIG_BT_CTLR_NRF_GRTC) +#define NRF_RTC NRF_RTC10 +#endif /* !CONFIG_BT_CTLR_NRF_GRTC */ + +#undef EVENT_TIMER_ID +#define EVENT_TIMER_ID 10 + +#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 */ +/* TODO: Using NRF_TIMER from another domain needs DPPIC and PPIB setup */ +#error "SW tIFS switching using dedicated second timer not supported yet." +#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_NRF54LX_TXEN_TXIDLE_TX_1M_FAST_NS 40900 /*40.1 + 0.8*/ +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_1M_FAST_US \ + HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF54LX_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_NRF54LX_TXEN_TXIDLE_TX_1M_DEFAULT_NS 140900 /*140.1 + 0.8*/ +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_1M_DEFAULT_US \ + HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF54LX_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_NRF54LX_TXEN_TXIDLE_TX_1M_DEFAULT_NO_HW_TIFS_NS 130300 +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_1M_DEFAULT_NO_HW_TIFS_US \ + HAL_RADIO_NS2US_ROUND( \ + HAL_RADIO_NRF54LX_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_NRF54LX_TXEN_TXIDLE_TX_2M_FAST_NS 40000 /* 40.1 - 0.1 */ +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_2M_FAST_US \ + HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF54LX_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_NRF54LX_TXEN_TXIDLE_TX_2M_DEFAULT_NS 144900 /* 145 - 0.1 */ +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_2M_DEFAULT_US \ + HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF54LX_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_NRF54LX_TXEN_TXIDLE_TX_2M_DEFAULT_NO_HW_TIFS_NS 129400 +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_2M_DEFAULT_NO_HW_TIFS_US \ + HAL_RADIO_NS2US_ROUND( \ + HAL_RADIO_NRF54LX_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_NRF54LX_TXEN_TXIDLE_TX_S2_FAST_NS 42300 /* 40.1 + 2.2 */ +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S2_FAST_US \ + HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF54LX_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_NRF54LX_TXEN_TXIDLE_TX_S2_DEFAULT_NS 132200 /* 130 + 2.2 */ +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S2_DEFAULT_US \ + HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF54LX_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_NRF54LX_TXEN_TXIDLE_TX_S2_DEFAULT_NO_HW_TIFS_NS 131700 +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S2_DEFAULT_NO_HW_TIFS_US \ + HAL_RADIO_NS2US_ROUND( \ + HAL_RADIO_NRF54LX_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_NRF54LX_TXEN_TXIDLE_TX_S8_FAST_NS 42300 /* 40.1 + 2.2 */ +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S8_FAST_US \ + HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF54LX_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_NRF54LX_TXEN_TXIDLE_TX_S8_DEFAULT_NS 121800 /*119.6 + 2.2*/ +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S8_DEFAULT_US \ + HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF54LX_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_NRF54LX_TXEN_TXIDLE_TX_S8_DEFAULT_NO_HW_TIFS_NS 131700 +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S8_DEFAULT_NO_HW_TIFS_US \ + HAL_RADIO_NS2US_ROUND( \ + HAL_RADIO_NRF54LX_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_NRF54LX_RXEN_RXIDLE_RX_1M_FAST_NS 40300 /* 40.1 + 0.2 */ +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_1M_FAST_US \ + HAL_RADIO_NS2US_CEIL(HAL_RADIO_NRF54LX_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_NRF54LX_RXEN_RXIDLE_RX_1M_DEFAULT_NS 140300 /*140.1 + 0.2*/ +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_1M_DEFAULT_US \ + HAL_RADIO_NS2US_CEIL(HAL_RADIO_NRF54LX_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_NRF54LX_RXEN_RXIDLE_RX_1M_DEFAULT_NO_HW_TIFS_NS 129700 +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_1M_DEFAULT_NO_HW_TIFS_US \ + HAL_RADIO_NS2US_CEIL( \ + HAL_RADIO_NRF54LX_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_NRF54LX_RXEN_RXIDLE_RX_2M_FAST_NS 40300 /* 40.1 + 0.2 */ +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_2M_FAST_US \ + HAL_RADIO_NS2US_CEIL(HAL_RADIO_NRF54LX_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_NRF54LX_RXEN_RXIDLE_RX_2M_DEFAULT_NS 144800 /*144.6 + 0.2*/ +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_2M_DEFAULT_US \ + HAL_RADIO_NS2US_CEIL(HAL_RADIO_NRF54LX_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_NRF54LX_RXEN_RXIDLE_RX_2M_DEFAULT_NO_HW_TIFS_NS 129700 +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_2M_DEFAULT_NO_HW_TIFS_US \ + HAL_RADIO_NS2US_CEIL( \ + HAL_RADIO_NRF54LX_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_NRF54LX_RXEN_RXIDLE_RX_S2_FAST_NS 40300 /* 40.1 + 0.2 */ +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S2_FAST_US \ + HAL_RADIO_NS2US_CEIL(HAL_RADIO_NRF54LX_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_NRF54LX_RXEN_RXIDLE_RX_S2_DEFAULT_NS 130200 /* 130 + 0.2 */ +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S2_DEFAULT_US \ + HAL_RADIO_NS2US_CEIL(HAL_RADIO_NRF54LX_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_NRF54LX_RXEN_RXIDLE_RX_S2_DEFAULT_NO_HW_TIFS_NS 129700 +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S2_DEFAULT_NO_HW_TIFS_US \ + HAL_RADIO_NS2US_CEIL( \ + HAL_RADIO_NRF54LX_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_NRF54LX_RXEN_RXIDLE_RX_S8_FAST_NS 40300 /* 40.1 + 0.2 */ +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S8_FAST_US \ + HAL_RADIO_NS2US_CEIL(HAL_RADIO_NRF54LX_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_NRF54LX_RXEN_RXIDLE_RX_S8_DEFAULT_NS 120200 /* 120.0 + 0.2 */ +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S8_DEFAULT_US \ + HAL_RADIO_NS2US_CEIL(HAL_RADIO_NRF54LX_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_NRF54LX_RXEN_RXIDLE_RX_S8_DEFAULT_NO_HW_TIFS_NS 129700 +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S8_DEFAULT_NO_HW_TIFS_US \ + HAL_RADIO_NS2US_CEIL( \ + HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S8_DEFAULT_NO_HW_TIFS_NS) + +#define HAL_RADIO_NRF54LX_TX_CHAIN_DELAY_1M_US 1 /* ceil(0.6) */ +#define HAL_RADIO_NRF54LX_TX_CHAIN_DELAY_1M_NS 600 /* 0.6 */ +#define HAL_RADIO_NRF54LX_TX_CHAIN_DELAY_2M_US 1 /* ceil(0.6) */ +#define HAL_RADIO_NRF54LX_TX_CHAIN_DELAY_2M_NS 600 /* 0.6 */ +#define HAL_RADIO_NRF54LX_TX_CHAIN_DELAY_S2_US 1 /* ceil(0.6) */ +#define HAL_RADIO_NRF54LX_TX_CHAIN_DELAY_S2_NS 600 /* 0.6 */ +#define HAL_RADIO_NRF54LX_TX_CHAIN_DELAY_S8_US 1 /* ceil(0.6) */ +#define HAL_RADIO_NRF54LX_TX_CHAIN_DELAY_S8_NS 600 /* 0.6 */ + +#define HAL_RADIO_NRF54LX_RX_CHAIN_DELAY_1M_US 10 /* ceil(9.4) */ +#define HAL_RADIO_NRF54LX_RX_CHAIN_DELAY_1M_NS 9400 /* 9.4 */ +#define HAL_RADIO_NRF54LX_RX_CHAIN_DELAY_2M_US 5 /* ceil(5.0) */ +#define HAL_RADIO_NRF54LX_RX_CHAIN_DELAY_2M_NS 5000 /* 5.0 */ +#define HAL_RADIO_NRF54LX_RX_CHAIN_DELAY_S2_US 25 /* ceil(19.6) */ +#define HAL_RADIO_NRF54LX_RX_CHAIN_DELAY_S2_NS 24600 /* 19.6 */ +#define HAL_RADIO_NRF54LX_RX_CHAIN_DELAY_S8_US 30 /* ceil(29.6) */ +#define HAL_RADIO_NRF54LX_RX_CHAIN_DELAY_S8_NS 29600 /* 29.6 */ + +#if defined(CONFIG_BT_CTLR_RADIO_ENABLE_FAST) +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_1M_US \ + HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_1M_FAST_US +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_1M_NS \ + HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_1M_FAST_NS + +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_2M_US \ + HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_2M_FAST_US +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_2M_NS \ + HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_2M_FAST_NS + +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S2_US \ + HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S2_FAST_US +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S2_NS \ + HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S2_FAST_NS + +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S8_US \ + HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S8_FAST_US +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S8_NS \ + HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S8_FAST_NS + +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_1M_US \ + HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_1M_FAST_US +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_1M_NS \ + HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_1M_FAST_NS + +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_2M_US \ + HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_2M_FAST_US +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_2M_NS \ + HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_2M_FAST_NS + +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S2_US \ + HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S2_FAST_US +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S2_NS \ + HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S2_FAST_NS + +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S8_US \ + HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S8_FAST_US +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S8_NS \ + HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S8_FAST_NS + +#else /* !CONFIG_BT_CTLR_RADIO_ENABLE_FAST */ +#if defined(CONFIG_BT_CTLR_TIFS_HW) +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_1M_US \ + HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_1M_DEFAULT_US +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_1M_NS \ + HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_1M_DEFAULT_NS + +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_2M_US \ + HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_2M_DEFAULT_US +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_2M_NS \ + HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_2M_DEFAULT_NS + +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S2_US \ + HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S2_DEFAULT_US +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S2_NS \ + HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S2_DEFAULT_NS + +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S8_US \ + HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S8_DEFAULT_US +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S8_NS \ + HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S8_DEFAULT_NS + +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_1M_US \ + HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_1M_DEFAULT_US +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_1M_NS \ + HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_1M_DEFAULT_NS + +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_2M_US \ + HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_2M_DEFAULT_US +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_2M_NS \ + HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_2M_DEFAULT_NS + +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S2_US \ + HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S2_DEFAULT_US +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S2_NS \ + HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S2_DEFAULT_NS + +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S8_US \ + HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S8_DEFAULT_US +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S8_NS \ + HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S8_DEFAULT_NS + +#else /* !CONFIG_BT_CTLR_TIFS_HW */ +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_1M_US \ + HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_1M_DEFAULT_NO_HW_TIFS_US +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_1M_NS \ + HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_1M_DEFAULT_NO_HW_TIFS_NS + +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_2M_US \ + HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_2M_DEFAULT_NO_HW_TIFS_US +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_2M_NS \ + HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_2M_DEFAULT_NO_HW_TIFS_NS + +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S2_US \ + HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S2_DEFAULT_NO_HW_TIFS_US +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S2_NS \ + HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S2_DEFAULT_NO_HW_TIFS_NS + +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S8_US \ + HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S8_DEFAULT_NO_HW_TIFS_US +#define HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S8_NS \ + HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S8_DEFAULT_NO_HW_TIFS_NS + +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_1M_US \ + HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_1M_DEFAULT_NO_HW_TIFS_US +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_1M_NS \ + HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_1M_DEFAULT_NO_HW_TIFS_NS + +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_2M_US \ + HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_2M_DEFAULT_NO_HW_TIFS_US +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_2M_NS \ + HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_2M_DEFAULT_NO_HW_TIFS_NS + +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S2_US \ + HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S2_DEFAULT_NO_HW_TIFS_US +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S2_NS \ + HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S2_DEFAULT_NO_HW_TIFS_NS + +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S8_US \ + HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S8_DEFAULT_NO_HW_TIFS_US +#define HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S8_NS \ + HAL_RADIO_NRF54LX_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_CCM00 +#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 + +static inline void hal_radio_reset(void) +{ + /* TODO: Add any required setup for each radio event + */ +} + +static inline void hal_radio_stop(void) +{ + /* TODO: Add any required cleanup of actions taken in hal_radio_reset() + */ +} + +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 8; /* +8 dBm */ +} + +static inline int8_t hal_radio_tx_power_min_get(void) +{ + return -46; /* -46 dBm */ +} + +static inline int8_t hal_radio_tx_power_floor(int8_t tx_power_lvl) +{ + 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; + } + + if (tx_power_lvl >= -3) { + return -3; + } + + if (tx_power_lvl >= -4) { + return -4; + } + + if (tx_power_lvl >= -5) { + return -5; + } + + if (tx_power_lvl >= -6) { + return -6; + } + + if (tx_power_lvl >= -7) { + return -7; + } + + if (tx_power_lvl >= -8) { + return -8; + } + + if (tx_power_lvl >= -9) { + return -9; + } + + if (tx_power_lvl >= -10) { + return -10; + } + + if (tx_power_lvl >= -12) { + return -12; + } + + if (tx_power_lvl >= -14) { + return -14; + } + + if (tx_power_lvl >= -16) { + return -16; + } + + if (tx_power_lvl >= -20) { + return -20; + } + + if (tx_power_lvl >= -26) { + return -26; + } + + if (tx_power_lvl >= -40) { + return -40; + } + + return -46; +} + +static inline uint32_t hal_radio_tx_power_value(int8_t tx_power_lvl) +{ + if (tx_power_lvl >= 8) { + return RADIO_TXPOWER_TXPOWER_Pos8dBm; + } + + if (tx_power_lvl >= 7) { + return RADIO_TXPOWER_TXPOWER_Pos7dBm; + } + + if (tx_power_lvl >= 6) { + return RADIO_TXPOWER_TXPOWER_Pos6dBm; + } + + if (tx_power_lvl >= 5) { + return RADIO_TXPOWER_TXPOWER_Pos5dBm; + } + + if (tx_power_lvl >= 4) { + return RADIO_TXPOWER_TXPOWER_Pos4dBm; + } + + if (tx_power_lvl >= 3) { + return RADIO_TXPOWER_TXPOWER_Pos3dBm; + } + + if (tx_power_lvl >= 2) { + return RADIO_TXPOWER_TXPOWER_Pos2dBm; + } + + if (tx_power_lvl >= 1) { + return RADIO_TXPOWER_TXPOWER_Pos1dBm; + } + + if (tx_power_lvl >= 0) { + return RADIO_TXPOWER_TXPOWER_0dBm; + } + + if (tx_power_lvl >= -1) { + return RADIO_TXPOWER_TXPOWER_Neg1dBm; + } + + if (tx_power_lvl >= -2) { + return RADIO_TXPOWER_TXPOWER_Neg2dBm; + } + + if (tx_power_lvl >= -3) { + return RADIO_TXPOWER_TXPOWER_Neg3dBm; + } + + if (tx_power_lvl >= -4) { + return RADIO_TXPOWER_TXPOWER_Neg4dBm; + } + + if (tx_power_lvl >= -5) { + return RADIO_TXPOWER_TXPOWER_Neg5dBm; + } + + if (tx_power_lvl >= -6) { + return RADIO_TXPOWER_TXPOWER_Neg6dBm; + } + + if (tx_power_lvl >= -7) { + return RADIO_TXPOWER_TXPOWER_Neg7dBm; + } + + if (tx_power_lvl >= -8) { + return RADIO_TXPOWER_TXPOWER_Neg8dBm; + } + + if (tx_power_lvl >= -9) { + return RADIO_TXPOWER_TXPOWER_Neg9dBm; + } + + if (tx_power_lvl >= -10) { + return RADIO_TXPOWER_TXPOWER_Neg10dBm; + } + + if (tx_power_lvl >= -12) { + return RADIO_TXPOWER_TXPOWER_Neg12dBm; + } + + if (tx_power_lvl >= -14) { + return RADIO_TXPOWER_TXPOWER_Neg14dBm; + } + + if (tx_power_lvl >= -16) { + return RADIO_TXPOWER_TXPOWER_Neg16dBm; + } + + if (tx_power_lvl >= -20) { + return RADIO_TXPOWER_TXPOWER_Neg20dBm; + } + +#if defined(RADIO_TXPOWER_TXPOWER_Neg26dBm) + if (tx_power_lvl >= -26) { + return RADIO_TXPOWER_TXPOWER_Neg26dBm; + } +#endif + +#if defined(RADIO_TXPOWER_TXPOWER_Neg28dBm) + if (tx_power_lvl >= -28) { + return RADIO_TXPOWER_TXPOWER_Neg28dBm; + } +#endif + + if (tx_power_lvl >= -40) { + return RADIO_TXPOWER_TXPOWER_Neg40dBm; + } + + return RADIO_TXPOWER_TXPOWER_Neg46dBm; +} + +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_NRF54LX_TXEN_TXIDLE_TX_1M_US; + case BIT(1): + return HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_2M_US; + +#if defined(CONFIG_BT_CTLR_PHY_CODED) + case BIT(2): + if (flags & 0x01) { + return HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S8_US; + } else { + return HAL_RADIO_NRF54LX_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_NRF54LX_RXEN_RXIDLE_RX_1M_US; + case BIT(1): + return HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_2M_US; + +#if defined(CONFIG_BT_CTLR_PHY_CODED) + case BIT(2): + if (flags & 0x01) { + return HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S8_US; + } else { + return HAL_RADIO_NRF54LX_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_NRF54LX_TX_CHAIN_DELAY_1M_US; + case BIT(1): + return HAL_RADIO_NRF54LX_TX_CHAIN_DELAY_2M_US; + +#if defined(CONFIG_BT_CTLR_PHY_CODED) + case BIT(2): + if (flags & 0x01) { + return HAL_RADIO_NRF54LX_TX_CHAIN_DELAY_S8_US; + } else { + return HAL_RADIO_NRF54LX_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_NRF54LX_RX_CHAIN_DELAY_1M_US; + case BIT(1): + return HAL_RADIO_NRF54LX_RX_CHAIN_DELAY_2M_US; + +#if defined(CONFIG_BT_CTLR_PHY_CODED) + case BIT(2): + if (flags & 0x01) { + return HAL_RADIO_NRF54LX_RX_CHAIN_DELAY_S8_US; + } else { + return HAL_RADIO_NRF54LX_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_NRF54LX_TXEN_TXIDLE_TX_1M_NS; + case BIT(1): + return HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_2M_NS; + +#if defined(CONFIG_BT_CTLR_PHY_CODED) + case BIT(2): + if (flags & 0x01) { + return HAL_RADIO_NRF54LX_TXEN_TXIDLE_TX_S8_NS; + } else { + return HAL_RADIO_NRF54LX_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_NRF54LX_RXEN_RXIDLE_RX_1M_NS; + case BIT(1): + return HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_2M_NS; + +#if defined(CONFIG_BT_CTLR_PHY_CODED) + case BIT(2): + if (flags & 0x01) { + return HAL_RADIO_NRF54LX_RXEN_RXIDLE_RX_S8_NS; + } else { + return HAL_RADIO_NRF54LX_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_NRF54LX_TX_CHAIN_DELAY_1M_NS; + case BIT(1): + return HAL_RADIO_NRF54LX_TX_CHAIN_DELAY_2M_NS; + +#if defined(CONFIG_BT_CTLR_PHY_CODED) + case BIT(2): + if (flags & 0x01) { + return HAL_RADIO_NRF54LX_TX_CHAIN_DELAY_S8_NS; + } else { + return HAL_RADIO_NRF54LX_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_NRF54LX_RX_CHAIN_DELAY_1M_NS; + case BIT(1): + return HAL_RADIO_NRF54LX_RX_CHAIN_DELAY_2M_NS; + +#if defined(CONFIG_BT_CTLR_PHY_CODED) + case BIT(2): + if (flags & 0x01) { + return HAL_RADIO_NRF54LX_RX_CHAIN_DELAY_S8_NS; + } else { + return HAL_RADIO_NRF54LX_RX_CHAIN_DELAY_S2_NS; + } +#endif /* CONFIG_BT_CTLR_PHY_CODED */ + } +} diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv.c index a4b6d0dd3ad6..8334f35ebf8d 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv.c @@ -1303,6 +1303,11 @@ static void isr_done(void *param) { struct lll_adv *lll; + /* Call to ensure packet/event timer accumulates the elapsed time + * under single timer use. + */ + (void)radio_is_tx_done(); + /* Clear radio status and events */ lll_isr_status_reset(); diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_iso.c index a31b68b3ad13..91ca0b1d0c63 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_adv_iso.c @@ -625,10 +625,35 @@ static void isr_tx_common(void *param, /* Get ISO data PDU, not control subevent */ if (!pdu) { - uint8_t payload_index; + uint16_t payload_index; + + if (lll->ptc_curr) { + /* FIXME: Do not remember why ptc is 4 bits, it should be 5 bits as ptc is a + * running buffer offset related to nse. + * Fix ptc and ptc_curr definitions, until then there is an assertion + * check when ptc is calculated in ptc_calc function. + */ + uint8_t ptx_idx = lll->ptc_curr - 1U; /* max. nse 5 bits */ + uint8_t ptx_payload_idx; + uint16_t ptx_group_mult; + uint8_t ptx_group_idx; + + /* Calculate group index and multiplier for deriving + * pre-transmission payload index. + */ + ptx_group_idx = ptx_idx / lll->bn; /* 5 bits */ + ptx_payload_idx = ptx_idx - ptx_group_idx * lll->bn; /* 8 bits */ + ptx_group_mult = (ptx_group_idx + 1U) * lll->pto; /* 9 bits */ + payload_index = ptx_payload_idx + ptx_group_mult * lll->bn; /* 13 bits */ + + /* FIXME: memq_peek_n function does not support indices > UINT8_MAX, + * add assertion check to honor this limitation. + */ + LL_ASSERT(payload_index <= UINT8_MAX); + } else { + payload_index = lll->bn_curr - 1U; /* 3 bits */ + } - payload_index = (lll->bn_curr - 1U) + - (lll->ptc_curr * lll->pto); payload_count = lll->payload_count + payload_index - lll->bn; #if !TEST_WITH_DUMMY_PDU @@ -654,6 +679,10 @@ static void isr_tx_common(void *param, (tx->payload_count < payload_count)); } if (!link || (tx->payload_count != payload_count)) { + /* FIXME: Do not transmit on air an empty PDU if this is a Pre-Transmission + * subevent, instead use radio_tmr_start_us() to schedule next valid + * subevent. + */ pdu = radio_pkt_empty_get(); pdu->ll_id = lll->framing ? PDU_BIS_LLID_FRAMED : PDU_BIS_LLID_START_CONTINUE; diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c index 4b4a76a3dec2..526403e92d99 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_central_iso.c @@ -92,23 +92,12 @@ int lll_central_iso_reset(void) void lll_central_iso_prepare(void *param) { - struct lll_conn_iso_group *cig_lll; - struct lll_prepare_param *p; - uint16_t elapsed; int err; /* Initiate HF clock start up */ err = lll_hfclock_on(); LL_ASSERT(err >= 0); - /* Instants elapsed */ - p = param; - elapsed = p->lazy + 1U; - - /* Save the (latency + 1) for use in event and/or supervision timeout */ - cig_lll = p->param; - cig_lll->latency_prepare += elapsed; - /* Invoke common pipeline handling of prepare */ err = lll_prepare(lll_is_abort_cb, abort_cb, prepare_cb, 0U, param); LL_ASSERT(!err || err == -EINPROGRESS); @@ -135,7 +124,6 @@ static int prepare_cb(struct lll_prepare_param *p) struct ull_hdr *ull; uint32_t remainder; uint32_t start_us; - uint16_t lazy; uint32_t ret; uint8_t phy; int err = 0; @@ -162,6 +150,9 @@ static int prepare_cb(struct lll_prepare_param *p) /* Get reference to ACL context */ conn_lll = ull_conn_lll_get(cis_lll->acl_handle); + /* Pick the event_count calculated in the ULL prepare */ + cis_lll->event_count = cis_lll->event_count_prepare; + /* Event counter value, 0-15 bit of cisEventCounter */ event_counter = cis_lll->event_count; @@ -173,9 +164,9 @@ static int prepare_cb(struct lll_prepare_param *p) &data_chan_prn_s, &data_chan_remap_idx); - /* Store the current event latency */ - cig_lll->latency_event = cig_lll->latency_prepare; - lazy = cig_lll->latency_prepare - 1U; + /* Calculate the current event latency */ + cig_lll->lazy_prepare = p->lazy; + cig_lll->latency_event = cig_lll->latency_prepare + cig_lll->lazy_prepare; /* Reset accumulated latencies */ cig_lll->latency_prepare = 0U; @@ -183,7 +174,7 @@ static int prepare_cb(struct lll_prepare_param *p) se_curr = 1U; /* Adjust the SN and NESN for skipped CIG events */ - payload_count_lazy_update(cis_lll, lazy); + payload_count_lazy_update(cis_lll, cig_lll->latency_event); /* Start setting up of Radio h/w */ radio_reset(); @@ -369,8 +360,11 @@ static int prepare_cb(struct lll_prepare_param *p) do { cis_lll = ull_conn_iso_lll_stream_get_by_group(cig_lll, &cis_handle); if (cis_lll && cis_lll->active) { + /* Pick the event_count calculated in the ULL prepare */ + cis_lll->event_count = cis_lll->event_count_prepare; + /* Adjust sn and nesn for skipped CIG events */ - payload_count_lazy_update(cis_lll, lazy); + payload_count_lazy_update(cis_lll, cig_lll->latency_event); /* Adjust sn and nesn for canceled events */ if (err) { @@ -395,13 +389,13 @@ static int prepare_cb(struct lll_prepare_param *p) static void abort_cb(struct lll_prepare_param *prepare_param, void *param) { + struct lll_conn_iso_group *cig_lll; int err; /* NOTE: This is not a prepare being cancelled */ if (!prepare_param) { struct lll_conn_iso_stream *next_cis_lll; struct lll_conn_iso_stream *cis_lll; - struct lll_conn_iso_group *cig_lll; cis_lll = ull_conn_iso_lll_stream_get(cis_handle_curr); cig_lll = param; @@ -431,6 +425,13 @@ static void abort_cb(struct lll_prepare_param *prepare_param, void *param) err = lll_hfclock_off(); LL_ASSERT(err >= 0); + /* Get reference to CIG LLL context */ + cig_lll = prepare_param->param; + + /* Accumulate the latency as event is aborted while being in pipeline */ + cig_lll->lazy_prepare = prepare_param->lazy; + cig_lll->latency_prepare += (cig_lll->lazy_prepare + 1U); + lll_done(param); } @@ -546,6 +547,8 @@ static void isr_tx(void *param) if (se_curr < cis_lll->nse) { const struct lll_conn *evt_conn_lll; uint16_t data_chan_id; + +#if !defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) uint32_t subevent_us; uint32_t start_us; @@ -555,6 +558,7 @@ static void isr_tx(void *param) start_us = radio_tmr_start_us(1U, subevent_us); LL_ASSERT(start_us == (subevent_us + 1U)); +#endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ /* Get reference to ACL context */ evt_conn_lll = ull_conn_lll_get(cis_lll->acl_handle); @@ -574,9 +578,7 @@ static void isr_tx(void *param) uint64_t payload_count; uint16_t event_counter; uint16_t data_chan_id; - uint32_t subevent_us; uint16_t cis_handle; - uint32_t start_us; memq_link_t *link; /* Calculate channel for next CIS */ @@ -590,12 +592,23 @@ static void isr_tx(void *param) return; } - /* Get reference to ACL context */ - next_conn_lll = ull_conn_lll_get(next_cis_lll->acl_handle); +#if !defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) + uint32_t subevent_us; + uint32_t start_us; + + subevent_us = radio_tmr_ready_restore(); + subevent_us += next_cis_lll->offset - cis_offset_first; + + start_us = radio_tmr_start_us(1U, subevent_us); + LL_ASSERT(start_us == (subevent_us + 1U)); +#endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ /* Event counter value, 0-15 bit of cisEventCounter */ event_counter = next_cis_lll->event_count; + /* Get reference to ACL context */ + next_conn_lll = ull_conn_lll_get(next_cis_lll->acl_handle); + /* Calculate the radio channel to use for ISO event */ data_chan_id = lll_chan_id(next_cis_lll->access_addr); next_cis_chan = lll_chan_iso_event(event_counter, data_chan_id, @@ -604,12 +617,6 @@ static void isr_tx(void *param) &next_cis_chan_prn_s, &next_cis_chan_remap_idx); - subevent_us = radio_tmr_ready_restore(); - subevent_us += next_cis_lll->offset - cis_offset_first; - - start_us = radio_tmr_start_us(1U, subevent_us); - LL_ASSERT(start_us == (subevent_us + 1U)); - cis_lll = next_cis_lll; /* Tx Ack stale ISO Data */ @@ -838,9 +845,18 @@ static void isr_rx(void *param) uint64_t payload_count; uint16_t event_counter; uint16_t data_chan_id; + memq_link_t *link; + +#if !defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) uint32_t subevent_us; uint32_t start_us; - memq_link_t *link; + + subevent_us = radio_tmr_ready_restore(); + subevent_us += next_cis_lll->offset - cis_offset_first; + + start_us = radio_tmr_start_us(1U, subevent_us); + LL_ASSERT(start_us == (subevent_us + 1U)); +#endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ /* Event counter value, 0-15 bit of cisEventCounter */ event_counter = next_cis_lll->event_count; @@ -853,12 +869,6 @@ static void isr_rx(void *param) &next_cis_chan_prn_s, &next_cis_chan_remap_idx); - subevent_us = radio_tmr_ready_restore(); - subevent_us += next_cis_lll->offset - cis_offset_first; - - start_us = radio_tmr_start_us(1U, subevent_us); - LL_ASSERT(start_us == (subevent_us + 1U)); - old_cis_lll = cis_lll; cis_lll = next_cis_lll; @@ -935,7 +945,6 @@ static void isr_prepare_subevent(void *param) struct pdu_cis *pdu_tx; uint64_t payload_count; uint8_t payload_index; - uint32_t subevent_us; uint32_t start_us; /* Get reference to CIS LLL context */ @@ -1052,12 +1061,26 @@ static void isr_prepare_subevent(void *param) radio_switch_complete_and_rx(0U); #endif /* !CONFIG_BT_CTLR_PHY */ +#if defined(HAL_RADIO_GPIO_HAVE_PA_PIN) || \ + defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) + uint32_t subevent_us; + subevent_us = radio_tmr_ready_restore(); subevent_us += cis_lll->offset - cis_offset_first + (cis_lll->sub_interval * se_curr); +#if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) + start_us = radio_tmr_start_us(1U, subevent_us); + LL_ASSERT(start_us == (subevent_us + 1U)); + +#else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ /* Compensate for the 1 us added by radio_tmr_start_us() */ start_us = subevent_us + 1U; +#endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ + +#endif /* HAL_RADIO_GPIO_HAVE_PA_PIN || + * CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER + */ /* capture end of Tx-ed PDU, used to calculate HCTO. */ radio_tmr_end_capture(); diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c index 4f61cba9665b..3ff4e29efea8 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_conn.c @@ -67,6 +67,7 @@ static struct pdu_data *get_last_tx_pdu(struct lll_conn *lll); static uint8_t crc_expire; static uint8_t crc_valid; static uint8_t is_aborted; +static uint16_t tx_cnt; static uint16_t trx_cnt; #if defined(CONFIG_BT_CTLR_LE_ENC) @@ -147,6 +148,7 @@ void lll_conn_flush(uint16_t handle, struct lll_conn *lll) void lll_conn_prepare_reset(void) { + tx_cnt = 0U; trx_cnt = 0U; crc_valid = 0U; crc_expire = 0U; @@ -193,7 +195,7 @@ int lll_conn_peripheral_is_abort_cb(void *next, void *curr, /* Do not be aborted by same event if a single peripheral trx has not * been exchanged. */ - if ((next == curr) && (trx_cnt <= 1U)) { + if ((next == curr) && (tx_cnt < 1U)) { return -EBUSY; } @@ -216,7 +218,7 @@ void lll_conn_abort_cb(struct lll_prepare_param *prepare_param, void *param) * back to central, otherwise let the supervision timeout * countdown be started. */ - if ((lll->role == BT_HCI_ROLE_PERIPHERAL) && (trx_cnt <= 1U)) { + if ((lll->role == BT_HCI_ROLE_PERIPHERAL) && (tx_cnt < 1U)) { is_aborted = 1U; } @@ -263,6 +265,8 @@ void lll_conn_abort_cb(struct lll_prepare_param *prepare_param, void *param) e->type = EVENT_DONE_EXTRA_TYPE_CONN; e->trx_cnt = 0U; e->crc_valid = 0U; + e->is_aborted = 1U; + #if defined(CONFIG_BT_CTLR_LE_ENC) e->mic_state = LLL_CONN_MIC_NONE; #endif /* CONFIG_BT_CTLR_LE_ENC */ @@ -607,6 +611,8 @@ void lll_conn_isr_tx(void *param) /* Clear radio tx status and events */ lll_isr_tx_status_reset(); + tx_cnt++; + lll = param; /* setup tIFS switching */ @@ -692,10 +698,26 @@ void lll_conn_isr_tx(void *param) } #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_TX */ +#if !defined(CONFIG_BOARD_NRF52_BSIM) && \ + !defined(CONFIG_BOARD_NRF5340BSIM_NRF5340_CPUNET) && \ + !defined(CONFIG_BOARD_NRF54L15BSIM_NRF54L15_CPUAPP) + /* +/- 2us active clock jitter, +1 us PPI to timer start compensation */ hcto = radio_tmr_tifs_base_get() + lll->tifs_hcto_us + (EVENT_CLOCK_JITTER_US << 1) + RANGE_DELAY_US + HAL_RADIO_TMR_START_DELAY_US; + +#else /* FIXME: Why different for BabbleSIM? */ + /* HACK: Have exact 150 us */ + hcto = radio_tmr_tifs_base_get() + lll->tifs_hcto_us; + + /* HACK: Could wrong MODE register value (next in tIFS switching) being + * use for Rx Chain Delay in BabbleSIM? or is there a bug in + * target implementation? + */ + hcto += radio_rx_chain_delay_get(lll->phy_tx, PHY_FLAGS_S8); +#endif /* FIXME: Why different for BabbleSIM? */ + #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_TX) hcto += cte_len; #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_TX */ @@ -749,9 +771,9 @@ void lll_conn_isr_tx(void *param) radio_isr_set(lll_conn_isr_rx, param); -#if defined(CONFIG_BT_CTLR_LOW_LAT_ULL) +#if defined(CONFIG_BT_CTLR_LOW_LAT) ull_conn_lll_tx_demux_sched(lll); -#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL */ +#endif /* CONFIG_BT_CTLR_LOW_LAT */ } void lll_conn_rx_pkt_set(struct lll_conn *lll) @@ -987,7 +1009,7 @@ static void isr_done(void *param) #if defined(CONFIG_BT_CTLR_PHY) preamble_to_addr_us = - addr_us_get(lll->phy_rx); + addr_us_get(lll->periph.phy_rx_event); #else /* !CONFIG_BT_CTLR_PHY */ preamble_to_addr_us = addr_us_get(0); diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral.c index c15ca24eb909..0ed7a63af8d8 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral.c @@ -177,6 +177,11 @@ static int prepare_cb(struct lll_prepare_param *p) lll->periph.window_size_prepare_us; lll->periph.window_size_prepare_us = 0; +#if defined(CONFIG_BT_CTLR_PHY) + /* back up rx PHY for use in drift compensation */ + lll->periph.phy_rx_event = lll->phy_rx; +#endif /* CONFIG_BT_CTLR_PHY */ + /* Ensure that empty flag reflects the state of the Tx queue, as a * peripheral if this is the first connection event and as no prior PDU * is transmitted, an incorrect acknowledgment by peer should not diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c index d189a22d61e4..00e641fd151e 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_peripheral_iso.c @@ -164,6 +164,9 @@ static int prepare_cb(struct lll_prepare_param *p) /* Get reference to ACL context */ conn_lll = ull_conn_lll_get(cis_lll->acl_handle); + /* Pick the event_count calculated in the ULL prepare */ + cis_lll->event_count = cis_lll->event_count_prepare; + /* Event counter value, 0-15 bit of cisEventCounter */ event_counter = cis_lll->event_count; @@ -204,7 +207,7 @@ static int prepare_cb(struct lll_prepare_param *p) se_curr = 1U; /* Adjust sn and nesn for skipped CIG events */ - payload_count_lazy(cis_lll, cig_lll->lazy_prepare); + payload_count_lazy(cis_lll, cig_lll->latency_event); /* Start setting up of Radio h/w */ radio_reset(); @@ -374,8 +377,11 @@ static int prepare_cb(struct lll_prepare_param *p) break; } + /* Pick the event_count calculated in the ULL prepare */ + cis_lll->event_count = cis_lll->event_count_prepare; + /* Adjust sn and nesn for skipped CIG events */ - payload_count_lazy(cis_lll, cig_lll->lazy_prepare); + payload_count_lazy(cis_lll, cig_lll->latency_event); /* Adjust sn and nesn for canceled events */ if (err) { @@ -462,8 +468,6 @@ static void isr_rx(void *param) struct pdu_cis *pdu_tx; uint64_t payload_count; uint8_t payload_index; - uint32_t subevent_us; - uint32_t start_us; uint8_t trx_done; uint8_t crc_ok; uint8_t cie; @@ -807,6 +811,12 @@ static void isr_rx(void *param) se_curr = 0U; } + radio_isr_set(isr_tx, cis_lll); + +#if !defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) + uint32_t subevent_us; + uint32_t start_us; + /* Schedule next subevent reception */ subevent_us = radio_tmr_aa_restore(); subevent_us += cis_lll->offset - cis_offset_first + @@ -825,8 +835,7 @@ static void isr_rx(void *param) start_us = radio_tmr_start_us(0U, subevent_us); LL_ASSERT(start_us == (subevent_us + 1U)); - - radio_isr_set(isr_tx, cis_lll); +#endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ } static void isr_tx(void *param) @@ -923,8 +932,14 @@ static void isr_tx(void *param) subevent_us -= radio_rx_chain_delay_get(0U, 0U); #endif /* !CONFIG_BT_CTLR_PHY */ +#if defined(CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER) + start_us = radio_tmr_start_us(0U, subevent_us); + LL_ASSERT(start_us == (subevent_us + 1U)); + +#else /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ /* Compensate for the 1 us added by radio_tmr_start_us() */ start_us = subevent_us + 1U; +#endif /* !CONFIG_BT_CTLR_SW_SWITCH_SINGLE_TIMER */ hcto = start_us + ((EVENT_JITTER_US + EVENT_TICKER_RES_MARGIN_US + @@ -941,7 +956,7 @@ static void isr_tx(void *param) hcto += radio_rx_chain_delay_get(0U, 0U); #endif /* !CONFIG_BT_CTLR_PHY */ - radio_tmr_hcto_configure(hcto); + radio_tmr_hcto_configure_abs(hcto); #if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN) radio_gpio_lna_setup(); @@ -1172,7 +1187,7 @@ static void isr_prepare_subevent_common(void *param) hcto += radio_rx_chain_delay_get(0U, 0U); #endif /* !CONFIG_BT_CTLR_PHY */ - radio_tmr_hcto_configure(hcto); + radio_tmr_hcto_configure_abs(hcto); #if defined(HAL_RADIO_GPIO_HAVE_LNA_PIN) radio_gpio_lna_setup(); diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan.c index 37bc040b8837..5f51c55f4255 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan.c @@ -287,7 +287,7 @@ void lll_scan_prepare_connect_req(struct lll_scan *lll, struct pdu_adv *pdu_tx, *conn_space_us = conn_offset_us; pdu_tx->connect_ind.win_offset = sys_cpu_to_le16(0); } else { - uint32_t win_offset_us = + uint32_t win_offset_us = radio_tmr_start_latency_get() + lll->conn_win_offset_us + radio_rx_ready_delay_get(phy, PHY_FLAGS_S8); @@ -1089,6 +1089,9 @@ static void isr_done_cleanup(void *param) lll->is_stop = 1U; } + /* LLL scheduled auxiliary PDU reception is_abort on duration expire or + * aborted in the unreserved time space. + */ if (lll->is_aux_sched) { struct node_rx_pdu *node_rx2; @@ -1100,6 +1103,7 @@ static void isr_done_cleanup(void *param) node_rx2->hdr.type = NODE_RX_TYPE_EXT_AUX_RELEASE; node_rx2->rx_ftr.param = lll; + node_rx2->rx_ftr.lll_aux = lll->lll_aux; ull_rx_put_sched(node_rx2->hdr.link, node_rx2); } diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan_aux.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan_aux.c index 7bbd7abe6afe..7cc128c48523 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan_aux.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_scan_aux.c @@ -365,7 +365,7 @@ void lll_scan_aux_isr_aux_setup(void *param) hcto += window_size_us; hcto += radio_rx_chain_delay_get(phy_aux, PHY_FLAGS_S8); hcto += addr_us_get(phy_aux); - radio_tmr_hcto_configure(hcto); + radio_tmr_hcto_configure_abs(hcto); /* capture end of Rx-ed PDU, extended scan to schedule auxiliary * channel chaining, create connection or to create periodic sync. @@ -710,6 +710,7 @@ static void isr_done(void *param) node_rx->hdr.type = NODE_RX_TYPE_EXT_AUX_RELEASE; node_rx->rx_ftr.param = lll; + node_rx->rx_ftr.lll_aux = lll->lll_aux; node_rx->rx_ftr.aux_failed = 1U; ull_rx_put_sched(node_rx->hdr.link, node_rx); @@ -897,6 +898,7 @@ static void isr_rx(struct lll_scan *lll, struct lll_scan_aux *lll_aux, * free it. */ node_rx2->rx_ftr.param = lll; + node_rx2->rx_ftr.lll_aux = lll->lll_aux; ull_rx_put_sched(node_rx2->hdr.link, node_rx2); } @@ -1620,7 +1622,8 @@ static void isr_rx_connect_rsp(void *param) node_rx->hdr.type = NODE_RX_TYPE_EXT_AUX_RELEASE; - node_rx->rx_ftr.param = lll->lll_aux; + node_rx->rx_ftr.param = lll; + node_rx->rx_ftr.lll_aux = lll->lll_aux; ull_rx_put_sched(node_rx->hdr.link, node_rx); diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync.c index 40eac85cb777..c80591939b1c 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync.c @@ -757,7 +757,7 @@ static void isr_aux_setup(void *param) hcto += window_size_us; hcto += radio_rx_chain_delay_get(phy_aux, PHY_FLAGS_S8); hcto += addr_us_get(phy_aux); - radio_tmr_hcto_configure(hcto); + radio_tmr_hcto_configure_abs(hcto); /* capture end of Rx-ed PDU, extended scan to schedule auxiliary * channel chaining, create connection or to create periodic sync. @@ -814,11 +814,6 @@ static int isr_rx(struct lll_sync *lll, uint8_t node_type, uint8_t crc_ok, * again a node_rx for periodic report incomplete. */ if (node_type != NODE_RX_TYPE_EXT_AUX_REPORT) { - /* Reset Sync context association with any Aux context - * as a new chain is being setup for reception here. - */ - lll->lll_aux = NULL; - node_rx = ull_pdu_rx_alloc_peek(4); } else { node_rx = ull_pdu_rx_alloc_peek(3); @@ -834,6 +829,7 @@ static int isr_rx(struct lll_sync *lll, uint8_t node_type, uint8_t crc_ok, ftr = &(node_rx->rx_ftr); ftr->param = lll; + ftr->lll_aux = lll->lll_aux; ftr->aux_failed = 0U; ftr->rssi = (rssi_ready) ? radio_rssi_get() : BT_HCI_LE_RSSI_NOT_AVAILABLE; @@ -1148,6 +1144,7 @@ static void isr_rx_aux_chain(void *param) node_rx->hdr.type = NODE_RX_TYPE_EXT_AUX_RELEASE; node_rx->rx_ftr.param = lll; + node_rx->rx_ftr.lll_aux = lll->lll_aux; node_rx->rx_ftr.aux_failed = 1U; ull_rx_put(node_rx->hdr.link, node_rx); @@ -1184,6 +1181,13 @@ static void isr_rx_done_cleanup(struct lll_sync *lll, uint8_t crc_ok, bool sync_ { struct event_done_extra *e; + /* Reset Sync context association with any Aux context as the chain reception is done. + * By code inspection there should not be a race that ULL execution context assigns lll_aux + * that would be reset here, because either we are here not receiving a chain PDU or the + * lll_aux has been set in the node rx type NODE_RX_TYPE_EXT_AUX_RELEASE before we are here. + */ + lll->lll_aux = NULL; + /* Calculate and place the drift information in done event */ e = ull_event_done_extra_get(); LL_ASSERT(e); @@ -1243,6 +1247,7 @@ static void isr_done(void *param) node_rx->hdr.type = NODE_RX_TYPE_EXT_AUX_RELEASE; node_rx->rx_ftr.param = lll; + node_rx->rx_ftr.lll_aux = lll->lll_aux; node_rx->rx_ftr.aux_failed = 1U; ull_rx_put_sched(node_rx->hdr.link, node_rx); diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync_iso.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync_iso.c index b3af4fd8404e..0257bc0eafaa 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync_iso.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll_sync_iso.c @@ -52,6 +52,7 @@ static void isr_rx_estab(void *param); static void isr_rx(void *param); static void isr_rx_done(void *param); static void isr_done(void *param); +static uint16_t payload_index_get(const struct lll_sync_iso *lll); static void next_chan_calc(struct lll_sync_iso *lll, uint16_t event_counter, uint16_t data_chan_id); static void isr_rx_iso_data_valid(const struct lll_sync_iso *const lll, @@ -659,8 +660,7 @@ static void isr_rx(void *param) * Ensure we are not having offset values over 255 in payload_count_max, used to * allocate the buffers. */ - payload_offset = (lll->latency_event * lll->bn) + (lll->bn_curr - 1U) + - (lll->ptc_curr * lll->pto); + payload_offset = (lll->latency_event * lll->bn) + payload_index_get(lll); if (payload_offset >= lll->payload_count_max) { goto isr_rx_done; } @@ -1031,8 +1031,7 @@ static void isr_rx(void *param) if (bis) { struct node_rx_pdu *node_rx; - payload_count += (lll->bn_curr - 1U) + - (lll->ptc_curr * lll->pto); + payload_count += payload_index_get(lll); /* By design, there shall always be one free node rx * available for setting up radio for new PDU reception. @@ -1093,6 +1092,9 @@ static void isr_rx(void *param) /* Setup radio packet timer header complete timeout for * subsequent subevent PDU. */ + uint32_t jitter_max_us; + uint32_t overhead_us; + uint32_t jitter_us; /* Calculate the radio start with consideration of the drift * based on the access address capture timestamp. @@ -1103,7 +1105,17 @@ static void isr_rx(void *param) hcto -= radio_rx_chain_delay_get(lll->phy, PHY_FLAGS_S8); hcto -= addr_us_get(lll->phy); hcto -= radio_rx_ready_delay_get(lll->phy, PHY_FLAGS_S8); - hcto -= (EVENT_CLOCK_JITTER_US << 1) * nse; + overhead_us = radio_rx_chain_delay_get(lll->phy, PHY_FLAGS_S8); + overhead_us += addr_us_get(lll->phy); + overhead_us += radio_rx_ready_delay_get(lll->phy, PHY_FLAGS_S8); + overhead_us += (EVENT_CLOCK_JITTER_US << 1); + jitter_max_us = (EVENT_IFS_US - overhead_us) >> 1; + jitter_max_us -= RANGE_DELAY_US + HAL_RADIO_TMR_START_DELAY_US; + jitter_us = (EVENT_CLOCK_JITTER_US << 1) * nse; + if (jitter_us > jitter_max_us) { + jitter_us = jitter_max_us; + } + hcto -= jitter_us; start_us = hcto; hcto = radio_tmr_start_us(0U, start_us); @@ -1113,8 +1125,8 @@ static void isr_rx(void *param) * 4 us early and subevents could have a 4 us drift each until * the current subevent we are listening. */ - hcto += (((EVENT_CLOCK_JITTER_US << 1) * nse) << 1) + - RANGE_DELAY_US + HAL_RADIO_TMR_START_DELAY_US; + hcto += (jitter_us << 1); + hcto += RANGE_DELAY_US + HAL_RADIO_TMR_START_DELAY_US; } else { /* First subevent PDU was not received, hence setup radio packet * timer header complete timeout from where the first subevent @@ -1140,7 +1152,7 @@ static void isr_rx(void *param) hcto += radio_rx_chain_delay_get(lll->phy, PHY_FLAGS_S8); /* setup absolute PDU header reception timeout */ - radio_tmr_hcto_configure(hcto); + radio_tmr_hcto_configure_abs(hcto); /* setup capture of PDU end timestamp */ radio_tmr_end_capture(); @@ -1336,6 +1348,35 @@ static void isr_done(void *param) } } +static uint16_t payload_index_get(const struct lll_sync_iso *lll) +{ + uint16_t payload_index; + + if (lll->ptc_curr) { + /* FIXME: Do not remember why ptc is 4 bits, it should be 5 bits as ptc is a + * running buffer offset related to nse. + * Fix ptc and ptc_curr definitions, until then there is an assertion + * check when ptc is calculated in ptc_calc function. + */ + uint8_t ptx_idx = lll->ptc_curr - 1U; /* max. nse 5 bits */ + uint8_t ptx_payload_idx; + uint16_t ptx_group_mult; + uint8_t ptx_group_idx; + + /* Calculate group index and multiplier for deriving + * pre-transmission payload index. + */ + ptx_group_idx = ptx_idx / lll->bn; /* 5 bits */ + ptx_payload_idx = ptx_idx - ptx_group_idx * lll->bn; /* 8 bits */ + ptx_group_mult = (ptx_group_idx + 1U) * lll->pto; /* 9 bits */ + payload_index = ptx_payload_idx + ptx_group_mult * lll->bn; /* 13 bits */ + } else { + payload_index = lll->bn_curr - 1U; /* 3 bits */ + } + + return payload_index; +} + static void next_chan_calc(struct lll_sync_iso *lll, uint16_t event_counter, uint16_t data_chan_id) { @@ -1377,8 +1418,7 @@ static void isr_rx_iso_data_valid(const struct lll_sync_iso *const lll, node_rx->hdr.handle = handle; iso_meta = &node_rx->rx_iso_meta; - iso_meta->payload_number = lll->payload_count + (lll->bn_curr - 1U) + - (lll->ptc_curr * lll->pto); + iso_meta->payload_number = lll->payload_count + payload_index_get(lll); /* Decrement BN as payload_count was pre-incremented */ iso_meta->payload_number -= lll->bn; diff --git a/subsys/bluetooth/controller/ll_sw/ull.c b/subsys/bluetooth/controller/ll_sw/ull.c index 40c335dee854..52ab480b6635 100644 --- a/subsys/bluetooth/controller/ll_sw/ull.c +++ b/subsys/bluetooth/controller/ll_sw/ull.c @@ -221,6 +221,9 @@ FLASH_TICKER_NODES + \ COEX_TICKER_NODES) +/* Ticker implementation supports up to 255 ticker node count value */ +BUILD_ASSERT(TICKER_NODES <= UINT8_MAX); + /* When both central and peripheral are supported, one each Rx node will be * needed by connectable advertising and the initiator to generate connection * complete event, hence conditionally set the count. diff --git a/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c b/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c index 32afe0b75fca..d041f1e2a30b 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_adv_iso.c @@ -51,6 +51,17 @@ #include "hal/debug.h" +/* Controller implementation dependent minimum Pre-Transmission Offset and + * Pre-Transmission Group Count to use when there is available time space in the + * BIG events. + * The number of Pre-Transmission Group Count configure how many future ISO SDUs + * from the Offset will be Pre-Transmitted in advance in the current BIG event. + * + * TODO: These could be a Kconfig option. + */ +#define BT_CTLR_ADV_ISO_PTO_MIN 1U +#define BT_CTLR_ADV_ISO_PTO_GROUP_COUNT 1U + static int init_reset(void); static struct ll_adv_iso_set *adv_iso_get(uint8_t handle); static struct stream *adv_iso_stream_acquire(void); @@ -201,12 +212,11 @@ static uint8_t big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bi return BT_HCI_ERR_INVALID_PARAM; } - /* FIXME: PTO is currently limited to BN */ - if (!IN_RANGE(pto, 0x00, bn /*0x0F*/)) { + if (pto > 0x0F) { return BT_HCI_ERR_INVALID_PARAM; } - if (bn * irc + pto < nse) { + if (pto && !(bn * irc < nse)) { return BT_HCI_ERR_INVALID_PARAM; } } else { @@ -358,7 +368,12 @@ static uint8_t big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bi lll_adv_iso->max_pdu = MIN(LL_BIS_OCTETS_TX_MAX, max_sdu); } - /* FIXME: SDU per max latency */ + /* FIXME: SDU per max latency, consider how to use Pre-transmission in the + * calculations. + * Take decision based on how ptc_calc function forces the use of + * Pre-Transmission when not using test command. Refer to comments in + * ptc_calc function. + */ sdu_per_event = MAX((max_latency * USEC_PER_MSEC / sdu_interval), 2U) - 1U; @@ -444,6 +459,9 @@ static uint8_t big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bi return BT_HCI_ERR_INVALID_PARAM; } + /* Decision to use requested Pre-Transmission Offset or force Pre-Transmission when + * possible (Zephyr Controller decision). + */ lll_adv_iso->ptc = ptc_calc(lll_adv_iso, event_spacing, event_spacing_max); if (test_config) { @@ -455,7 +473,7 @@ static uint8_t big_create(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bi } else { /* Pre-Transmission Offset (PTO) */ if (lll_adv_iso->ptc) { - lll_adv_iso->pto = bn / lll_adv_iso->bn; + lll_adv_iso->pto = MAX((bn / lll_adv_iso->bn), BT_CTLR_ADV_ISO_PTO_MIN); } else { lll_adv_iso->pto = 0U; } @@ -1155,17 +1173,49 @@ static uint8_t ptc_calc(const struct lll_adv_iso *lll, uint32_t event_spacing, uint32_t event_spacing_max) { if (event_spacing < event_spacing_max) { - uint8_t ptc; + uint32_t ptc; + uint8_t nse; - /* Possible maximum Pre-transmission Subevents per BIS */ + /* Possible maximum Pre-transmission Subevents per BIS. + * sub_interval is at least T_MSS_150 + MPT (hence a value in 8 bits or more), i.e. + * the below division and the subsequent multiplication with lll->bn does not + * overflow. + */ ptc = ((event_spacing_max - event_spacing) / (lll->sub_interval * lll->bn * lll->num_bis)) * lll->bn; - /* FIXME: Here we restrict to a maximum of BN Pre-Transmission - * subevents per BIS + /* Required NSE */ + nse = lll->bn * lll->irc; /* 3 bits * 4 bits, total 7 bits */ + + /* Requested NSE is greater than Required NSE, Pre-Transmission offset has been + * provided. + * + * NOTE: This is the case under HCI test command use to create BIG, i.e. test_config + * variable is true. + */ + if (lll->nse > nse) { + /* Restrict PTC to number of available subevents */ + ptc = MIN(ptc, lll->nse - nse); + } else { + /* No PTO requested, Zephyr Controller implementation here will try using + * Pre-Transmisson offset of BT_CTLR_ADV_ISO_PTO_MIN, i.e. restrict to a + * maximum of BN Pre-Transmission subevents per BIS. This allows for a + * better time diversity ensuring skipped or missing reception at the ISO + * Sync Receiver so it can still have another chance at receiving the ISO + * PDUs within the permitted maximum transport latency. + * + * Usecases where BAP Broadcast Audio Assistant role device has a drifting + * ACL Peripheral role active in the BAP Broadcast Audio Sink device. + */ + ptc = MIN(ptc, (lll->bn * BT_CTLR_ADV_ISO_PTO_GROUP_COUNT)); + } + + /* FIXME: Do not remember why ptc is 4 bits, it should be 5 bits as ptc is a + * running buffer offset related to nse. Fix ptc and ptc_curr definitions, + * until then lets have an assert check here. */ - ptc = MIN(ptc, lll->bn); + LL_ASSERT(ptc <= BIT_MASK(4)); return ptc; } diff --git a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c index fa3e37156645..d49256e3b095 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_central_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_central_iso.c @@ -929,6 +929,11 @@ uint8_t ull_central_iso_setup(uint16_t cis_handle, #if defined(CONFIG_BT_CTLR_ISOAL_PSN_IGNORE) cis->pkt_seq_num = 0U; #endif /* CONFIG_BT_CTLR_ISOAL_PSN_IGNORE */ + /* It is intentional to initialize to the 39 bit maximum value and rollover to 0 in the + * prepare function, the event counter is pre-incremented in prepare function for the + * current ISO event. + */ + cis->lll.event_count_prepare = LLL_CONN_ISO_EVENT_COUNT_MAX; cis->lll.event_count = LLL_CONN_ISO_EVENT_COUNT_MAX; cis->lll.next_subevent = 0U; cis->lll.tifs_us = conn->lll.tifs_cis_us; diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn.c b/subsys/bluetooth/controller/ll_sw/ull_conn.c index 93a610fa705f..7661bfa6dd23 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn.c @@ -82,9 +82,9 @@ LOG_MODULE_REGISTER(bt_ctlr_ull_conn); static int init_reset(void); -#if !defined(CONFIG_BT_CTLR_LOW_LAT_ULL) +#if !defined(CONFIG_BT_CTLR_LOW_LAT) static void tx_demux_sched(struct ll_conn *conn); -#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL */ +#endif /* CONFIG_BT_CTLR_LOW_LAT */ static void tx_demux(void *param); static struct node_tx *tx_ull_dequeue(struct ll_conn *conn, struct node_tx *tx); @@ -240,7 +240,7 @@ int ll_tx_mem_enqueue(uint16_t handle, void *tx) MFIFO_ENQUEUE(conn_tx, idx); -#if !defined(CONFIG_BT_CTLR_LOW_LAT_ULL) +#if !defined(CONFIG_BT_CTLR_LOW_LAT) if (ull_ref_get(&conn->ull)) { #if defined(CONFIG_BT_CTLR_FORCE_MD_AUTO) if (tx_cnt >= CONFIG_BT_BUF_ACL_TX_COUNT) { @@ -261,7 +261,7 @@ int ll_tx_mem_enqueue(uint16_t handle, void *tx) lll_conn_force_md_cnt_set(0U); #endif /* CONFIG_BT_CTLR_FORCE_MD_AUTO */ } -#endif /* !CONFIG_BT_CTLR_LOW_LAT_ULL */ +#endif /* !CONFIG_BT_CTLR_LOW_LAT */ if (IS_ENABLED(CONFIG_BT_PERIPHERAL) && conn->lll.role) { ull_periph_latency_cancel(conn, handle); @@ -1074,7 +1074,7 @@ void ull_conn_done(struct node_rx_event_done *done) if (done->extra.trx_cnt) { if (0) { #if defined(CONFIG_BT_PERIPHERAL) - } else if (lll->role) { + } else if (lll->role == BT_HCI_ROLE_PERIPHERAL) { if (!conn->periph.drift_skip) { ull_drift_ticks_get(done, &ticks_drift_plus, &ticks_drift_minus); @@ -1103,6 +1103,12 @@ void ull_conn_done(struct node_rx_event_done *done) /* Reset connection failed to establish countdown */ conn->connect_expire = 0U; + } else { +#if defined(CONFIG_BT_PERIPHERAL) + if (lll->role == BT_HCI_ROLE_PERIPHERAL) { + conn->periph.drift_skip = 0U; + } +#endif /* CONFIG_BT_PERIPHERAL */ } elapsed_event = latency_event + lll->lazy_prepare + 1U; @@ -1389,7 +1395,7 @@ void ull_conn_done(struct node_rx_event_done *done) } } -#if defined(CONFIG_BT_CTLR_LOW_LAT_ULL) +#if defined(CONFIG_BT_CTLR_LOW_LAT) void ull_conn_lll_tx_demux_sched(struct lll_conn *lll) { static memq_link_t link; @@ -1399,7 +1405,7 @@ void ull_conn_lll_tx_demux_sched(struct lll_conn *lll) mayfly_enqueue(TICKER_USER_ID_LLL, TICKER_USER_ID_ULL_HIGH, 1U, &mfy); } -#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL */ +#endif /* CONFIG_BT_CTLR_LOW_LAT */ void ull_conn_tx_demux(uint8_t count) { @@ -1696,7 +1702,7 @@ static int init_reset(void) return 0; } -#if !defined(CONFIG_BT_CTLR_LOW_LAT_ULL) +#if !defined(CONFIG_BT_CTLR_LOW_LAT) static void tx_demux_sched(struct ll_conn *conn) { static memq_link_t link; @@ -1706,7 +1712,7 @@ static void tx_demux_sched(struct ll_conn *conn) mayfly_enqueue(TICKER_USER_ID_THREAD, TICKER_USER_ID_ULL_HIGH, 0U, &mfy); } -#endif /* !CONFIG_BT_CTLR_LOW_LAT_ULL */ +#endif /* !CONFIG_BT_CTLR_LOW_LAT */ static void tx_demux(void *param) { @@ -2179,8 +2185,9 @@ static void ull_conn_update_ticker(struct ll_conn *conn, /* start periph/central with new timings */ uint8_t ticker_id_conn = TICKER_ID_CONN_BASE + ll_conn_handle_get(conn); - uint32_t ticker_status = ticker_stop(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_ULL_HIGH, - ticker_id_conn, ticker_stop_conn_op_cb, (void *)conn); + uint32_t ticker_status = ticker_stop_abs(TICKER_INSTANCE_ID_CTLR, TICKER_USER_ID_ULL_HIGH, + ticker_id_conn, ticks_at_expire, + ticker_stop_conn_op_cb, (void *)conn); LL_ASSERT((ticker_status == TICKER_STATUS_SUCCESS) || (ticker_status == TICKER_STATUS_BUSY)); ticker_status = ticker_start( diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c b/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c index a55d023668f6..b25267a34bd2 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn_iso.c @@ -711,17 +711,17 @@ void ull_conn_iso_ticker_cb(uint32_t ticks_at_expire, uint32_t ticks_drift, * has been reached, and offset calculated. */ if (cis->lll.handle != 0xFFFF && cis->lll.active) { - cis->lll.event_count += (lazy + 1U); + cis->lll.event_count_prepare += (lazy + 1U); #if !defined(CONFIG_BT_CTLR_JIT_SCHEDULING) - cis->lll.event_count -= cis->lll.lazy_active; + cis->lll.event_count_prepare -= cis->lll.lazy_active; cis->lll.lazy_active = 0U; #endif /* !CONFIG_BT_CTLR_JIT_SCHEDULING */ leading_event_count = MAX(leading_event_count, - cis->lll.event_count); + cis->lll.event_count_prepare); - ull_iso_lll_event_prepare(cis->lll.handle, cis->lll.event_count); + ull_iso_lll_event_prepare(cis->lll.handle, cis->lll.event_count_prepare); } /* Latch datapath validity entering event */ @@ -975,7 +975,7 @@ void ull_conn_iso_start(struct ll_conn *conn, uint16_t cis_handle, cis_offset = cis->offset + iso_interval_us - acl_latency_us; } - cis->lll.event_count += lost_cig_events; + cis->lll.event_count_prepare += lost_cig_events; lost_payloads = (lost_cig_events - (cis->lll.rx.ft - 1)) * cis->lll.rx.bn; cis->lll.rx.payload_count += lost_payloads; @@ -1520,7 +1520,7 @@ void ull_conn_iso_transmit_test_cig_interval(uint16_t handle, uint32_t ticks_at_ * on 64-bit sdu_counter: * (39 bits x 22 bits (4x10^6 us) = 61 bits / 8 bits (255 us) = 53 bits) */ - sdu_counter = DIV_ROUND_UP((cis->lll.event_count + 1U) * iso_interval, + sdu_counter = DIV_ROUND_UP((cis->lll.event_count_prepare + 1U) * iso_interval, sdu_interval); if (cis->hdr.test_mode.tx.sdu_counter == 0U) { diff --git a/subsys/bluetooth/controller/ll_sw/ull_iso.c b/subsys/bluetooth/controller/ll_sw/ull_iso.c index 2e34cef275f2..f10b4c15f112 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_iso.c @@ -4,11 +4,14 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include + #include #include #include #include #include +#include #include "hal/cpu.h" #include "hal/ccm.h" @@ -233,10 +236,7 @@ uint8_t ll_setup_iso_path(uint16_t handle, uint8_t path_dir, uint8_t path_id, ARG_UNUSED(controller_delay); ARG_UNUSED(codec_config); - if (false) { - -#if defined(CONFIG_BT_CTLR_CONN_ISO) - } else if (IS_CIS_HANDLE(handle)) { + if (IS_ENABLED(CONFIG_BT_CTLR_CONN_ISO) && IS_CIS_HANDLE(handle)) { struct ll_conn_iso_group *cig; struct ll_conn *conn; @@ -307,8 +307,6 @@ uint8_t ll_setup_iso_path(uint16_t handle, uint8_t path_dir, uint8_t path_id, sdu_interval = cig->c_sdu_interval; } } -#endif /* CONFIG_BT_CTLR_CONN_ISO */ - #if defined(CONFIG_BT_CTLR_ADV_ISO) } else if (IS_ADV_ISO_HANDLE(handle)) { struct ll_adv_iso_set *adv_iso; @@ -450,7 +448,7 @@ uint8_t ll_setup_iso_path(uint16_t handle, uint8_t path_dir, uint8_t path_id, } if (!err) { - if (cis) { + if (IS_ENABLED(CONFIG_BT_CTLR_CONN_ISO) && cis != NULL) { cis->hdr.datapath_out = dp; } diff --git a/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c b/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c index 345fddb87465..77b3f240f1b1 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_peripheral_iso.c @@ -333,6 +333,11 @@ uint8_t ull_peripheral_iso_setup(struct pdu_data_llctrl_cis_ind *ind, #if defined(CONFIG_BT_CTLR_ISOAL_PSN_IGNORE) cis->pkt_seq_num = 0U; #endif /* CONFIG_BT_CTLR_ISOAL_PSN_IGNORE */ + /* It is intentional to initialize to the 39 bit maximum value and rollover to 0 in the + * prepare function, the event counter is pre-incremented in prepare function for the + * current ISO event. + */ + cis->lll.event_count_prepare = LLL_CONN_ISO_EVENT_COUNT_MAX; cis->lll.event_count = LLL_CONN_ISO_EVENT_COUNT_MAX; cis->lll.next_subevent = 0U; cis->lll.tifs_us = conn->lll.tifs_cis_us; diff --git a/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c b/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c index 312cabdfc676..7419325254a8 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c +++ b/subsys/bluetooth/controller/ll_sw/ull_scan_aux.c @@ -293,7 +293,13 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_pdu *rx) */ sync_lll = ftr->param; - lll_aux = sync_lll->lll_aux; + /* We can not retrieve aux context that was stored in + * lll_sync when superior PDU was handled, as it may be + * reset to NULL before this node rx is processed here. + * The reset happens when new Periodic Advertising chain + * is being received before we process the node here. + */ + lll_aux = ftr->lll_aux; LL_ASSERT(lll_aux); aux = HDR_LLL2ULL(lll_aux); @@ -444,19 +450,30 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_pdu *rx) ptr = h->data; +#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC) + bool is_aux_addr_match = false; +#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */ + if (h->adv_addr) { #if defined(CONFIG_BT_CTLR_SYNC_PERIODIC) /* Check if Periodic Advertising Synchronization to be created */ if (sync && (scan->periodic.state != LL_SYNC_STATE_CREATED)) { - /* Check address and update internal state */ #if defined(CONFIG_BT_CTLR_PRIVACY) - ull_sync_setup_addr_check(sync, scan, pdu->tx_addr, ptr, - ftr->rl_idx); + uint8_t rl_idx = ftr->rl_idx; #else /* !CONFIG_BT_CTLR_PRIVACY */ - ull_sync_setup_addr_check(sync, scan, pdu->tx_addr, ptr, 0U); + uint8_t rl_idx = 0U; #endif /* !CONFIG_BT_CTLR_PRIVACY */ + /* Check address and update internal state */ + is_aux_addr_match = + ull_sync_setup_addr_check(sync, scan->periodic.filter_policy, + pdu->tx_addr, ptr, rl_idx); + if (is_aux_addr_match) { + scan->periodic.state = LL_SYNC_STATE_ADDR_MATCH; + } else { + scan->periodic.state = LL_SYNC_STATE_IDLE; + } } #endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */ @@ -489,14 +506,21 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_pdu *rx) si = (void *)ptr; ptr += sizeof(*si); +#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC) /* Check if Periodic Advertising Synchronization to be created. * Setup synchronization if address and SID match in the * Periodic Advertiser List or with the explicitly supplied. + * + * is_aux_addr_match, device address in auxiliary channel PDU; + * scan->periodic.param has not been assigned yet. + * Otherwise, address was in primary channel PDU and we are now + * checking SID (in SyncInfo) in auxiliary channel PDU. */ - if (IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC) && aux && sync && adi && + if (sync && aux && (is_aux_addr_match || (scan->periodic.param == aux)) && adi && ull_sync_setup_sid_match(sync, scan, PDU_ADV_ADI_SID_GET(adi))) { ull_sync_setup(scan, aux->lll.phy, rx, si); } +#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */ } if (h->tx_pwr) { @@ -692,6 +716,15 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_pdu *rx) #endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */ #if defined(CONFIG_BT_CTLR_SYNC_PERIODIC) + /* Store the aux context that has Periodic Advertising + * Synchronization address match. + */ + if (sync && (scan->periodic.state == LL_SYNC_STATE_ADDR_MATCH)) { + scan->periodic.param = aux; + } + + /* Store the node rx allocated for incomplete report, if needed. + */ aux->rx_incomplete = rx_incomplete; rx_incomplete = NULL; #endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */ @@ -916,6 +949,7 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_pdu *rx) #if defined(CONFIG_BT_CTLR_SYNC_PERIODIC) if (sync && (scan->periodic.state != LL_SYNC_STATE_CREATED)) { scan->periodic.state = LL_SYNC_STATE_IDLE; + scan->periodic.param = NULL; } #endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */ @@ -1092,16 +1126,33 @@ void ull_scan_aux_release(memq_link_t *link, struct node_rx_pdu *rx) param_ull = HDR_LLL2ULL(rx->rx_ftr.param); if (ull_scan_is_valid_get(param_ull)) { + /* Release aux context when LLL scheduled auxiliary PDU + * reception is_abort on duration expire or aborted in the + * unreserved time space. + */ struct lll_scan *lll; /* Mark for buffer for release */ rx->hdr.type = NODE_RX_TYPE_RELEASE; lll = rx->rx_ftr.param; - lll_aux = lll->lll_aux; + lll_aux = rx->rx_ftr.lll_aux; + + /* Under race condition when LLL scheduling a reception of + * auxiliary PDU, a scan aux context may be assigned late and + * the node rx releasing the aux context will not have it. + * Release the scan aux context assigned in the scan context. + */ + if (!lll_aux) { + lll_aux = lll->lll_aux; + } } else if (!IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC) || ull_scan_aux_is_valid_get(param_ull)) { + /* Release aux context when ULL scheduled auxiliary PDU + * reception is aborted. + */ + /* Mark for buffer for release */ rx->hdr.type = NODE_RX_TYPE_RELEASE; @@ -1116,8 +1167,20 @@ void ull_scan_aux_release(memq_link_t *link, struct node_rx_pdu *rx) /* reset data len total */ sync->data_len = 0U; + /* Release aux context in case of chain PDU reception, otherwise + * lll_aux is NULL. + */ lll = rx->rx_ftr.param; - lll_aux = lll->lll_aux; + lll_aux = rx->rx_ftr.lll_aux; + + /* Under race condition when LLL scheduling a reception of + * auxiliary PDU, a scan aux context may be assigned late and + * the node rx releasing the aux context will not have it. + * Release the scan aux context assigned in the sync context. + */ + if (!lll_aux) { + lll_aux = lll->lll_aux; + } /* Change node type so HCI can dispatch report for truncated * data properly. @@ -1149,13 +1212,16 @@ void ull_scan_aux_release(memq_link_t *link, struct node_rx_pdu *rx) scan = ull_scan_is_valid_get(scan); if (scan) { is_stop = scan->is_stop; - } else { + } else if (IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC)) { struct lll_sync *sync_lll; struct ll_sync_set *sync; sync_lll = (void *)lll; sync = HDR_LLL2ULL(sync_lll); is_stop = sync->is_stop; + } else { + LL_ASSERT(0); + return; } if (!is_stop) { @@ -1518,7 +1584,16 @@ static void ticker_op_cb(uint32_t status, void *param) } #else /* CONFIG_BT_CTLR_SCAN_AUX_USE_CHAINS */ - +/* NOTE: BT_CTLR_SCAN_AUX_USE_CHAINS is alternative new design with less RAM + * usage for supporting Extended Scanning of simultaneous interleaved + * Extended Advertising chains. + * + * TODO: As the previous design has Bluetooth Qualified Design Listing by + * Nordic Semiconductor ASA, both implementation are present in this file, + * and default builds use CONFIG_BT_CTLR_SCAN_AUX_USE_CHAINS=n. Remove old + * implementation when we have a new Bluetooth Qualified Design Listing + * with the new Extended Scanning and Periodic Sync implementation. + */ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_pdu *rx) { struct node_rx_pdu *rx_incomplete; @@ -1778,19 +1853,30 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_pdu *rx) ptr = h->data; +#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC) + bool is_aux_addr_match = false; +#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */ + if (h->adv_addr) { #if defined(CONFIG_BT_CTLR_SYNC_PERIODIC) /* Check if Periodic Advertising Synchronization to be created */ if (sync && (scan->periodic.state != LL_SYNC_STATE_CREATED)) { - /* Check address and update internal state */ #if defined(CONFIG_BT_CTLR_PRIVACY) - ull_sync_setup_addr_check(sync, scan, pdu->tx_addr, ptr, - ftr->rl_idx); + uint8_t rl_idx = ftr->rl_idx; #else /* !CONFIG_BT_CTLR_PRIVACY */ - ull_sync_setup_addr_check(sync, scan, pdu->tx_addr, ptr, 0U); + uint8_t rl_idx = 0U; #endif /* !CONFIG_BT_CTLR_PRIVACY */ + /* Check address and update internal state */ + is_aux_addr_match = + ull_sync_setup_addr_check(sync, scan->periodic.filter_policy, + pdu->tx_addr, ptr, rl_idx); + if (is_aux_addr_match) { + scan->periodic.state = LL_SYNC_STATE_ADDR_MATCH; + } else { + scan->periodic.state = LL_SYNC_STATE_IDLE; + } } #endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */ @@ -1823,14 +1909,21 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_pdu *rx) si = (void *)ptr; ptr += sizeof(*si); +#if defined(CONFIG_BT_CTLR_SYNC_PERIODIC) /* Check if Periodic Advertising Synchronization to be created. * Setup synchronization if address and SID match in the * Periodic Advertiser List or with the explicitly supplied. + * + * is_aux_addr_match, device address in auxiliary channel PDU; + * scan->periodic.param has not been assigned yet. + * Otherwise, address was in primary channel PDU and we are now + * checking SID (in SyncInfo) in auxiliary channel PDU. */ - if (IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC) && chain && sync && adi && - ull_sync_setup_sid_match(sync, scan, PDU_ADV_ADI_SID_GET(adi))) { + if (sync && chain && (is_aux_addr_match || (scan->periodic.param == chain)) && + adi && ull_sync_setup_sid_match(sync, scan, PDU_ADV_ADI_SID_GET(adi))) { ull_sync_setup(scan, chain->lll.phy, rx, si); } +#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */ } if (h->tx_pwr) { @@ -2012,6 +2105,13 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_pdu *rx) #endif /* CONFIG_BT_CTLR_JIT_SCHEDULING */ #if defined(CONFIG_BT_CTLR_SYNC_PERIODIC) + /* Store the chain context that has Periodic Advertising + * Synchronization address match. + */ + if (sync && (scan->periodic.state == LL_SYNC_STATE_ADDR_MATCH)) { + scan->periodic.param = chain; + } + if (sync_lll) { struct ll_sync_set *sync_set = HDR_LLL2ULL(sync_lll); @@ -2153,6 +2253,7 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_pdu *rx) #if defined(CONFIG_BT_CTLR_SYNC_PERIODIC) if (sync && (scan->periodic.state != LL_SYNC_STATE_CREATED)) { scan->periodic.state = LL_SYNC_STATE_IDLE; + scan->periodic.param = NULL; } #endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */ diff --git a/subsys/bluetooth/controller/ll_sw/ull_scan_types.h b/subsys/bluetooth/controller/ll_sw/ull_scan_types.h index c9d2c073f8f9..f4458825a5aa 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_scan_types.h +++ b/subsys/bluetooth/controller/ll_sw/ull_scan_types.h @@ -31,6 +31,11 @@ struct ll_scan_set { * cancelling sync create, hence the volatile keyword. */ struct ll_sync_set *volatile sync; + + /* Non-NULL when Periodic Advertising Synchronisation address + * matched. + */ + void *param; } periodic; #endif }; diff --git a/subsys/bluetooth/controller/ll_sw/ull_sync.c b/subsys/bluetooth/controller/ll_sw/ull_sync.c index 63e9e7ef57c8..9094366716ff 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_sync.c +++ b/subsys/bluetooth/controller/ll_sw/ull_sync.c @@ -152,11 +152,13 @@ uint8_t ll_sync_create(uint8_t options, uint8_t sid, uint8_t adv_addr_type, scan->periodic.cancelled = 0U; scan->periodic.state = LL_SYNC_STATE_IDLE; + scan->periodic.param = NULL; scan->periodic.filter_policy = options & BT_HCI_LE_PER_ADV_CREATE_SYNC_FP_USE_LIST; if (IS_ENABLED(CONFIG_BT_CTLR_PHY_CODED)) { scan_coded->periodic.cancelled = 0U; scan_coded->periodic.state = LL_SYNC_STATE_IDLE; + scan_coded->periodic.param = NULL; scan_coded->periodic.filter_policy = scan->periodic.filter_policy; } @@ -880,12 +882,12 @@ void ull_sync_release(struct ll_sync_set *sync) mem_release(sync, &sync_free); } -void ull_sync_setup_addr_check(struct ll_sync_set *sync, struct ll_scan_set *scan, +bool ull_sync_setup_addr_check(struct ll_sync_set *sync, uint8_t filter_policy, uint8_t addr_type, uint8_t *addr, uint8_t rl_idx) { /* Check if Periodic Advertiser list to be used */ if (IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC_ADV_LIST) && - scan->periodic.filter_policy) { + filter_policy) { /* Check in Periodic Advertiser List */ if (ull_filter_ull_pal_addr_match(addr_type, addr)) { /* Remember the address, to check with @@ -896,7 +898,7 @@ void ull_sync_setup_addr_check(struct ll_sync_set *sync, struct ll_scan_set *sca BDADDR_SIZE); /* Address matched */ - scan->periodic.state = LL_SYNC_STATE_ADDR_MATCH; + return true; /* Check in Resolving List */ } else if (IS_ENABLED(CONFIG_BT_CTLR_PRIVACY) && @@ -911,14 +913,14 @@ void ull_sync_setup_addr_check(struct ll_sync_set *sync, struct ll_scan_set *sca sync->peer_addr_resolved = 1U; /* Address matched */ - scan->periodic.state = LL_SYNC_STATE_ADDR_MATCH; + return true; } /* Check with explicitly supplied address */ } else if ((addr_type == sync->peer_id_addr_type) && !memcmp(addr, sync->peer_id_addr, BDADDR_SIZE)) { /* Address matched */ - scan->periodic.state = LL_SYNC_STATE_ADDR_MATCH; + return true; /* Check identity address with explicitly supplied address */ } else if (IS_ENABLED(CONFIG_BT_CTLR_PRIVACY) && @@ -930,9 +932,11 @@ void ull_sync_setup_addr_check(struct ll_sync_set *sync, struct ll_scan_set *sca sync->peer_addr_resolved = 1U; /* Identity address matched */ - scan->periodic.state = LL_SYNC_STATE_ADDR_MATCH; + return true; } } + + return false; } bool ull_sync_setup_sid_match(struct ll_sync_set *sync, struct ll_scan_set *scan, uint8_t sid) @@ -1060,6 +1064,7 @@ void ull_sync_setup(struct ll_scan_set *scan, uint8_t phy, /* Set the state to sync create */ scan->periodic.state = LL_SYNC_STATE_CREATED; + scan->periodic.param = NULL; if (IS_ENABLED(CONFIG_BT_CTLR_PHY_CODED)) { struct ll_scan_set *scan_1m; @@ -1069,8 +1074,10 @@ void ull_sync_setup(struct ll_scan_set *scan, uint8_t phy, scan_coded = ull_scan_set_get(SCAN_HANDLE_PHY_CODED); scan_coded->periodic.state = LL_SYNC_STATE_CREATED; + scan_coded->periodic.param = NULL; } else { scan_1m->periodic.state = LL_SYNC_STATE_CREATED; + scan_1m->periodic.param = NULL; } } diff --git a/subsys/bluetooth/controller/ll_sw/ull_sync_internal.h b/subsys/bluetooth/controller/ll_sw/ull_sync_internal.h index 79f2f3d67de8..e8111a783c90 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_sync_internal.h +++ b/subsys/bluetooth/controller/ll_sw/ull_sync_internal.h @@ -9,7 +9,7 @@ int ull_sync_reset(void); uint16_t ull_sync_handle_get(struct ll_sync_set *sync); struct ll_sync_set *ull_sync_is_enabled_get(uint16_t handle); void ull_sync_release(struct ll_sync_set *sync); -void ull_sync_setup_addr_check(struct ll_sync_set *sync, struct ll_scan_set *scan, +bool ull_sync_setup_addr_check(struct ll_sync_set *sync, uint8_t filter_policy, uint8_t addr_type, uint8_t *addr, uint8_t rl_idx); bool ull_sync_setup_sid_match(struct ll_sync_set *sync, struct ll_scan_set *scan, uint8_t sid); void ull_sync_create_from_sync_transfer(uint16_t conn_handle, uint16_t service_data, diff --git a/subsys/bluetooth/controller/ll_sw/ull_sync_iso.c b/subsys/bluetooth/controller/ll_sw/ull_sync_iso.c index a249dc1b2dfa..f9aa64863cfa 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_sync_iso.c +++ b/subsys/bluetooth/controller/ll_sw/ull_sync_iso.c @@ -483,13 +483,27 @@ void ull_sync_iso_setup(struct ll_sync_iso_set *sync_iso, lll->sub_interval = PDU_BIG_INFO_SUB_INTERVAL_GET(bi); lll->max_pdu = bi->max_pdu; lll->pto = PDU_BIG_INFO_PTO_GET(bi); + lll->bis_spacing = PDU_BIG_INFO_SPACING_GET(bi); + lll->irc = PDU_BIG_INFO_IRC_GET(bi); if (lll->pto) { - lll->ptc = lll->bn; + uint8_t nse; + + nse = lll->irc * lll->bn; /* 4 bits * 3 bits, total 7 bits */ + if (nse >= lll->nse) { + return; + } + + lll->ptc = lll->nse - nse; + + /* FIXME: Do not remember why ptc is 4 bits, it should be 5 bits as ptc is a + * running buffer offset related to nse. + * Fix ptc and ptc_curr definitions, until then we keep an assertion check + * here. + */ + LL_ASSERT(lll->ptc <= BIT_MASK(4)); } else { lll->ptc = 0U; } - lll->bis_spacing = PDU_BIG_INFO_SPACING_GET(bi); - lll->irc = PDU_BIG_INFO_IRC_GET(bi); lll->sdu_interval = PDU_BIG_INFO_SDU_INTERVAL_GET(bi); /* Pick the 39-bit payload count, 1 MSb is framing bit */ diff --git a/tests/bluetooth/controller/mock_ctrl/src/ticker.c b/tests/bluetooth/controller/mock_ctrl/src/ticker.c index 2d5381eeeb17..f4a18b8253ad 100644 --- a/tests/bluetooth/controller/mock_ctrl/src/ticker.c +++ b/tests/bluetooth/controller/mock_ctrl/src/ticker.c @@ -33,6 +33,13 @@ uint8_t ticker_stop(uint8_t instance_index, uint8_t user_id, uint8_t ticker_id, return TICKER_STATUS_SUCCESS; } +uint8_t ticker_stop_abs(uint8_t instance_index, uint8_t user_id, + uint8_t ticker_id, uint32_t ticks_at_stop, + ticker_op_func fp_op_func, void *op_context) +{ + return TICKER_STATUS_SUCCESS; +} + void ticker_job_sched(uint8_t instance_index, uint8_t user_id) { }