Bluetooth: controller: radio: add setting of S1 byte in radio packet

To transmit CTE with data channel packet the CTE configuration must
be stored in S1 field, that is placed just after length field.

The commit changes radio_pkt_configure function to allow configuration
of S1 field. When S1 field is used to store information about CTE
then its length is 8 bits. The content of the field is filled with
CTEInfo data. The same as the one used in periodic advertising.

The signature of the radio_pkt_configure function was not changed.
There were not used bits in flags parameter of the function.
From now on, bit 3 of the flags parameter will be used to store
information whether CTE will be added to the packet.

Besides that changed, the commit provides set of macros that
help in preparation and validation of the flags parameter content.
Macros provide information about bits that are currently used.
Ther are also macros that help to retrieve particular information
stored in the flags parameter.

Every place of code where the radio_pkt_configure function occurs
was changed to use provided macros.

Signed-off-by: Piotr Pryga <piotr.pryga@nordicsemi.no>
This commit is contained in:
Piotr Pryga 2021-12-10 21:18:43 +01:00 committed by Carles Cufí
parent 1ff9baf010
commit 1dcbe73cc8
12 changed files with 105 additions and 39 deletions

View File

@ -288,7 +288,8 @@ void radio_aa_set(uint8_t *aa)
void radio_pkt_configure(uint8_t bits_len, uint8_t max_len, uint8_t flags)
{
uint8_t dc = flags & 0x01; /* Adv or Data channel */
const uint8_t pdu_type = RADIO_PKT_CONF_PDU_TYPE_GET(flags); /* Adv or Data channel */
uint8_t bits_s1;
uint32_t extra;
uint8_t phy;
@ -298,14 +299,16 @@ void radio_pkt_configure(uint8_t bits_len, uint8_t max_len, uint8_t flags)
extra = 0U;
/* nRF51 supports only 27 byte PDU when using h/w CCM for encryption. */
if (!IS_ENABLED(CONFIG_BT_CTLR_DATA_LENGTH_CLEAR) && dc) {
if (!IS_ENABLED(CONFIG_BT_CTLR_DATA_LENGTH_CLEAR) &&
pdu_type == RADIO_PKT_CONF_PDU_TYPE_DC) {
bits_len = 5U;
bits_s1 = 3U;
}
#elif defined(CONFIG_SOC_COMPATIBLE_NRF52X) || \
defined(CONFIG_SOC_SERIES_NRF53X)
extra = 0U;
phy = (flags >> 1) & 0x07; /* phy */
phy = RADIO_PKT_CONF_PHY_GET(flags);
switch (phy) {
case PHY_1M:
default:
@ -334,31 +337,34 @@ void radio_pkt_configure(uint8_t bits_len, uint8_t max_len, uint8_t flags)
/* To use same Data Channel PDU structure with nRF5 specific overhead
* byte, include the S1 field in radio packet configuration.
*/
if (dc) {
if (pdu_type == RADIO_PKT_CONF_PDU_TYPE_DC) {
extra |= (RADIO_PCNF0_S1INCL_Include <<
RADIO_PCNF0_S1INCL_Pos) & RADIO_PCNF0_S1INCL_Msk;
#if defined(CONFIG_BT_CTLR_DF)
if (RADIO_PKT_CONF_CTE_GET(flags) == RADIO_PKT_CONF_CTE_ENABLED) {
bits_s1 = 8U;
} else
#endif /* CONFIG_BT_CTLR_DF */
{
bits_s1 = 0U;
}
} else {
bits_s1 = 0U;
}
#endif /* CONFIG_SOC_COMPATIBLE_NRF52X */
NRF_RADIO->PCNF0 = (((1UL) << RADIO_PCNF0_S0LEN_Pos) &
RADIO_PCNF0_S0LEN_Msk) |
((((uint32_t)bits_len) << RADIO_PCNF0_LFLEN_Pos) &
RADIO_PCNF0_LFLEN_Msk) |
((((uint32_t)8-bits_len) << RADIO_PCNF0_S1LEN_Pos) &
RADIO_PCNF0_S1LEN_Msk) |
extra;
NRF_RADIO->PCNF0 =
(((1UL) << RADIO_PCNF0_S0LEN_Pos) & RADIO_PCNF0_S0LEN_Msk) |
((((uint32_t)bits_len) << RADIO_PCNF0_LFLEN_Pos) & RADIO_PCNF0_LFLEN_Msk) |
((((uint32_t)bits_s1) << RADIO_PCNF0_S1LEN_Pos) & RADIO_PCNF0_S1LEN_Msk) | extra;
NRF_RADIO->PCNF1 &= ~(RADIO_PCNF1_MAXLEN_Msk | RADIO_PCNF1_STATLEN_Msk |
RADIO_PCNF1_BALEN_Msk | RADIO_PCNF1_ENDIAN_Msk);
NRF_RADIO->PCNF1 |= ((((uint32_t)max_len) << RADIO_PCNF1_MAXLEN_Pos) &
RADIO_PCNF1_MAXLEN_Msk) |
(((0UL) << RADIO_PCNF1_STATLEN_Pos) &
RADIO_PCNF1_STATLEN_Msk) |
(((3UL) << RADIO_PCNF1_BALEN_Pos) &
RADIO_PCNF1_BALEN_Msk) |
(((RADIO_PCNF1_ENDIAN_Little) <<
RADIO_PCNF1_ENDIAN_Pos) &
RADIO_PCNF1_ENDIAN_Msk);
NRF_RADIO->PCNF1 |=
((((uint32_t)max_len) << RADIO_PCNF1_MAXLEN_Pos) & RADIO_PCNF1_MAXLEN_Msk) |
(((0UL) << RADIO_PCNF1_STATLEN_Pos) & RADIO_PCNF1_STATLEN_Msk) |
(((3UL) << RADIO_PCNF1_BALEN_Pos) & RADIO_PCNF1_BALEN_Msk) |
(((RADIO_PCNF1_ENDIAN_Little) << RADIO_PCNF1_ENDIAN_Pos) & RADIO_PCNF1_ENDIAN_Msk);
}
void radio_pkt_rx_set(void *rx_packet)

View File

@ -5,6 +5,47 @@
* SPDX-License-Identifier: Apache-2.0
*/
/* Set of macros related with Radio packet configuration flags */
/* PDU type, 1 bit field*/
#define RADIO_PKT_CONF_PDU_TYPE_POS (0U)
#define RADIO_PKT_CONF_PDU_TYPE_MSK BIT(RADIO_PKT_CONF_PDU_TYPE_POS)
#define RADIO_PKT_CONF_PDU_TYPE_AC (0U)
#define RADIO_PKT_CONF_PDU_TYPE_DC (1U)
/* PHY type, two bit field */
#define RADIO_PKT_CONF_PHY_POS (1U)
#define RADIO_PKT_CONF_PHY_MSK (BIT_MASK(2U) << RADIO_PKT_CONF_PHY_POS)
#define RADIO_PKT_CONF_PHY_LEGACY (0U)
#define RADIO_PKT_CONF_PHY_1M (1U)
#define RADIO_PKT_CONF_PHY_2M (2U)
#define RADIO_PKT_CONF_PHY_CODED (3U)
/* CTE enabled, 1 bit field */
#define RADIO_PKT_CONF_CTE_POS (3U)
#define RADIO_PKT_CONF_CTE_MSK BIT(RADIO_PKT_CONF_PDU_TYPE_POS)
#define RADIO_PKT_CONF_CTE_DISABLED (0U)
#define RADIO_PKT_CONF_CTE_ENABLED (1U)
/* Macro to define length of the BLE packet length field in bits */
#define RADIO_PKT_CONF_LENGTH_8BIT (8U)
/* Helper macro to create bitfield with PDU type only*/
#define RADIO_PKT_CONF_PDU_TYPE(phy) ((uint8_t)((phy) << RADIO_PKT_CONF_PDU_TYPE_POS))
/* Helper macro to get PDU type from radio packet configuration bitfield */
#define RADIO_PKT_CONF_PDU_TYPE_GET(flags) \
((uint8_t)(((flags) >> RADIO_PKT_CONF_PDU_TYPE_POS) & RADIO_PKT_CONF_PDU_TYPE_MSK))
/* Helper macro to create bitfield with PHY type only */
#define RADIO_PKT_CONF_PHY(phy) ((uint8_t)((phy) << RADIO_PKT_CONF_PHY_POS))
/* Helper macro to get PHY type from radio packet configuration bitfield */
#define RADIO_PKT_CONF_PHY_GET(flags) \
((uint8_t)((((flags) >> RADIO_PKT_CONF_PHY_POS)) & RADIO_PKT_CONF_PHY_MSK))
/* Helper macro to create bitfield with CTE type only */
#define RADIO_PKT_CONF_CTE(phy) ((uint8_t)((phy) << RADIO_PKT_CONF_CTE_POS))
/* Helper macro to get CTE enable field value from radion packet configuration bitfield */
#define RADIO_PKT_CONF_CTE_GET(flags) \
((uint8_t)((((flags) >> RADIO_PKT_CONF_CTE_POS)) & RADIO_PKT_CONF_CTE_MSK))
/* Helper macro to create a radio packet configure bitfield */
#define RADIO_PKT_CONF_FLAGS(pdu, phy, cte) \
(RADIO_PKT_CONF_PDU_TYPE((pdu)) | RADIO_PKT_CONF_PHY((phy)) | RADIO_PKT_CONF_CTE((cte)))
typedef void (*radio_isr_cb_t) (void *param);
void isr_radio(void);

View File

@ -894,10 +894,12 @@ static int prepare_cb(struct lll_prepare_param *p)
#if defined(CONFIG_BT_CTLR_ADV_EXT)
/* TODO: if coded we use S8? */
radio_phy_set(lll->phy_p, lll->phy_flags);
radio_pkt_configure(8, PDU_AC_LEG_PAYLOAD_SIZE_MAX, (lll->phy_p << 1));
radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, PDU_AC_LEG_PAYLOAD_SIZE_MAX,
RADIO_PKT_CONF_PHY(lll->phy_p));
#else /* !CONFIG_BT_CTLR_ADV_EXT */
radio_phy_set(0, 0);
radio_pkt_configure(8, PDU_AC_LEG_PAYLOAD_SIZE_MAX, 0);
radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, PDU_AC_LEG_PAYLOAD_SIZE_MAX,
RADIO_PKT_CONF_PHY(RADIO_PKT_CONF_PHY_LEGACY));
#endif /* !CONFIG_BT_CTLR_ADV_EXT */
aa = sys_cpu_to_le32(PDU_AC_ACCESS_ADDR);

View File

@ -191,7 +191,8 @@ static int prepare_cb(struct lll_prepare_param *p)
/* TODO: if coded we use S8? */
radio_phy_set(phy_s, lll_adv->phy_flags);
radio_pkt_configure(8, PDU_AC_PAYLOAD_SIZE_MAX, (phy_s << 1));
radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, PDU_AC_PAYLOAD_SIZE_MAX,
RADIO_PKT_CONF_PHY(phy_s));
/* Access address and CRC */
aa = sys_cpu_to_le32(PDU_AC_ACCESS_ADDR);

View File

@ -236,7 +236,7 @@ static int prepare_cb_common(struct lll_prepare_param *p)
phy = lll->phy;
radio_phy_set(phy, lll->phy_flags);
radio_pkt_configure(8U, lll->max_pdu, (phy << 1));
radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, lll->max_pdu, RADIO_PKT_CONF_PHY(phy));
radio_aa_set(access_addr);
radio_crc_configure(PDU_CRC_POLYNOMIAL, sys_get_le24(crc_init));
lll_chan_set(data_chan_use);

View File

@ -172,7 +172,8 @@ static int prepare_cb(struct lll_prepare_param *p)
/* TODO: if coded we use S8? */
radio_phy_set(phy_s, lll->adv->phy_flags);
radio_pkt_configure(8, PDU_AC_PAYLOAD_SIZE_MAX, (phy_s << 1));
radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, PDU_AC_PAYLOAD_SIZE_MAX,
RADIO_PKT_CONF_PHY(phy_s));
radio_aa_set(lll->access_addr);
radio_crc_configure(PDU_CRC_POLYNOMIAL,
sys_get_le24(lll->crc_init));

View File

@ -30,6 +30,7 @@
#include "lll_conn.h"
#include "lll_internal.h"
#include "lll_df_internal.h"
#include "lll_tim_internal.h"
#include "lll_prof_internal.h"
@ -500,7 +501,9 @@ void lll_conn_rx_pkt_set(struct lll_conn *lll)
if (0) {
#if defined(CONFIG_BT_CTLR_LE_ENC)
} else if (lll->enc_rx) {
radio_pkt_configure(8, (max_rx_octets + 4), (phy << 1) | 0x01);
radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, (max_rx_octets + PDU_MIC_SIZE),
RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_DC, phy,
RADIO_PKT_CONF_CTE_DISABLED));
#if defined(CONFIG_SOC_COMPATIBLE_NRF52832) && \
defined(HAL_RADIO_PDU_LEN_MAX) && \
@ -516,7 +519,9 @@ void lll_conn_rx_pkt_set(struct lll_conn *lll)
#endif
#endif /* CONFIG_BT_CTLR_LE_ENC */
} else {
radio_pkt_configure(8, max_rx_octets, (phy << 1) | 0x01);
radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, max_rx_octets,
RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_DC, phy,
RADIO_PKT_CONF_CTE_DISABLED));
radio_pkt_rx_set(node_rx->pdu);
}
@ -550,14 +555,17 @@ void lll_conn_tx_pkt_set(struct lll_conn *lll, struct pdu_data *pdu_data_tx)
if (0) {
#if defined(CONFIG_BT_CTLR_LE_ENC)
} else if (lll->enc_tx) {
radio_pkt_configure(8, (max_tx_octets + 4U),
(phy << 1) | 0x01);
radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, (max_tx_octets + PDU_MIC_SIZE),
RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_DC, phy,
RADIO_PKT_CONF_CTE_DISABLED));
radio_pkt_tx_set(radio_ccm_tx_pkt_set(&lll->ccm_tx,
pdu_data_tx));
#endif /* CONFIG_BT_CTLR_LE_ENC */
} else {
radio_pkt_configure(8, max_tx_octets, (phy << 1) | 0x01);
radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, max_tx_octets,
RADIO_PKT_CONF_FLAGS(RADIO_PKT_CONF_PDU_TYPE_DC, phy,
RADIO_PKT_CONF_CTE_DISABLED));
radio_pkt_tx_set(pdu_data_tx);
}

View File

@ -382,13 +382,15 @@ static int common_prepare_cb(struct lll_prepare_param *p, bool is_resume)
#if defined(CONFIG_BT_CTLR_ADV_EXT)
/* TODO: if coded we use S8? */
radio_phy_set(lll->phy, 1);
radio_pkt_configure(8, PDU_AC_LEG_PAYLOAD_SIZE_MAX, (lll->phy << 1));
radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, PDU_AC_LEG_PAYLOAD_SIZE_MAX,
RADIO_PKT_CONF_PHY(lll->phy));
lll->is_adv_ind = 0U;
lll->is_aux_sched = 0U;
#else /* !CONFIG_BT_CTLR_ADV_EXT */
radio_phy_set(0, 0);
radio_pkt_configure(8, PDU_AC_LEG_PAYLOAD_SIZE_MAX, 0);
radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, PDU_AC_LEG_PAYLOAD_SIZE_MAX,
RADIO_PKT_CONF_PHY(RADIO_PKT_CONF_PHY_LEGACY));
#endif /* !CONFIG_BT_CTLR_ADV_EXT */
node_rx = ull_pdu_rx_alloc_peek(1);

View File

@ -278,7 +278,8 @@ void lll_scan_aux_isr_aux_setup(void *param)
/* Setup radio for auxiliary PDU scan */
radio_phy_set(phy_aux, PHY_FLAGS_S8);
radio_pkt_configure(8, LL_EXT_OCTETS_RX_MAX, (phy_aux << 1));
radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, LL_EXT_OCTETS_RX_MAX,
RADIO_PKT_CONF_PHY(phy_aux));
lll_chan_set(aux_ptr->chan_idx);
radio_pkt_rx_set(node_rx->pdu);
@ -470,7 +471,8 @@ static int prepare_cb(struct lll_prepare_param *p)
#endif
radio_phy_set(lll_aux->phy, PHY_FLAGS_S8);
radio_pkt_configure(8, LL_EXT_OCTETS_RX_MAX, (lll_aux->phy << 1));
radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, LL_EXT_OCTETS_RX_MAX,
RADIO_PKT_CONF_PHY(lll_aux->phy));
node_rx = ull_pdu_rx_alloc_peek(1);
LL_ASSERT(node_rx);

View File

@ -152,7 +152,8 @@ void lll_sync_aux_prepare_cb(struct lll_sync *lll,
#endif
radio_phy_set(lll_aux->phy, 1);
radio_pkt_configure(8, LL_EXT_OCTETS_RX_MAX, (lll_aux->phy << 1));
radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, LL_EXT_OCTETS_RX_MAX,
RADIO_PKT_CONF_PHY(lll_aux->phy));
node_rx = ull_pdu_rx_alloc_peek(1);
LL_ASSERT(node_rx);
@ -402,7 +403,8 @@ static int prepare_cb_common(struct lll_prepare_param *p, uint8_t chan_idx)
#endif /* CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL */
radio_phy_set(lll->phy, 1);
radio_pkt_configure(8, LL_EXT_OCTETS_RX_MAX, (lll->phy << 1));
radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, LL_EXT_OCTETS_RX_MAX,
RADIO_PKT_CONF_PHY(lll->phy));
radio_aa_set(lll->access_addr);
radio_crc_configure(PDU_CRC_POLYNOMIAL,
sys_get_le24(lll->crc_init));
@ -541,7 +543,8 @@ static void isr_aux_setup(void *param)
/* Setup radio for auxiliary PDU scan */
radio_phy_set(phy_aux, 1);
radio_pkt_configure(8, LL_EXT_OCTETS_RX_MAX, (phy_aux << 1));
radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, LL_EXT_OCTETS_RX_MAX,
RADIO_PKT_CONF_PHY(phy_aux));
lll_chan_set(aux_ptr->chan_idx);

View File

@ -258,7 +258,7 @@ static int prepare_cb_common(struct lll_prepare_param *p)
phy = lll->phy;
radio_phy_set(phy, PHY_FLAGS_S8);
radio_pkt_configure(8U, lll->max_pdu, (phy << 1));
radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, lll->max_pdu, RADIO_PKT_CONF_PHY(phy));
radio_aa_set(access_addr);
radio_crc_configure(PDU_CRC_POLYNOMIAL, sys_get_le24(crc_init));
lll_chan_set(data_chan_use);

View File

@ -197,7 +197,7 @@ static uint32_t init(uint8_t chan, uint8_t phy, void (*isr)(void *))
radio_freq_chan_set((chan << 1) + 2);
radio_aa_set((uint8_t *)&test_sync_word);
radio_crc_configure(0x65b, PDU_AC_CRC_IV);
radio_pkt_configure(8, 255, (test_phy << 1));
radio_pkt_configure(RADIO_PKT_CONF_LENGTH_8BIT, 255, RADIO_PKT_CONF_PHY(test_phy));
return 0;
}