Bluetooth: controller: Prepare to introduce LL split architecture

Preparation to introduce the Upper Link Layer (ULL) and
Lower Link Layer (LLL) split architecture.

- Move SoC dependent HAL to vendor specific folder.
- Preparation to split data structures into ULL and LLL
  types.
- Added more role and state conditional compilations.
- Added some work-in-progress implementation of advertising
  extensions, will be used as inspiration in the new split
  architecture work.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
Vinayak Kariappa Chettimada 2018-12-17 10:46:13 +01:00 committed by Carles Cufí
commit 87fe440f01
55 changed files with 2457 additions and 1437 deletions

View file

@ -45,6 +45,10 @@ zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_STM32
)
endif()
zephyr_library_sources_ifdef(CONFIG_FLASH_SHELL flash_shell.c)
zephyr_include_directories_ifdef(
CONFIG_SOC_FLASH_NRF_RADIO_SYNC
${ZEPHYR_BASE}/subsys/bluetooth
${ZEPHYR_BASE}/subsys/bluetooth/controller/ll_sw/nordic
)
zephyr_include_directories_ifdef(CONFIG_SOC_FLASH_NRF_RADIO_SYNC ${ZEPHYR_BASE}/subsys/bluetooth)
zephyr_library_sources_ifdef(CONFIG_FLASH_SHELL flash_shell.c)

View file

@ -18,7 +18,7 @@
#if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
#include <misc/__assert.h>
#include <bluetooth/hci.h>
#include "controller/hal/nrf5/ticker.h"
#include "controller/hal/ticker.h"
#include "controller/ticker/ticker.h"
#include "controller/include/ll.h"

View file

@ -7,8 +7,6 @@ zephyr_library_sources(
ticker/ticker.c
ll_sw/ll_addr.c
ll_sw/ll_tx_pwr.c
ll_sw/ctrl.c
ll_sw/ll.c
hci/hci_driver.c
hci/hci.c
)
@ -18,25 +16,36 @@ zephyr_library_sources_ifdef(
crypto/crypto.c
)
zephyr_library_sources_ifdef(
if(CONFIG_BT_LL_SW)
zephyr_library_sources(
ll_sw/ctrl.c
ll_sw/ll.c
)
zephyr_library_sources_ifdef(
CONFIG_BT_BROADCASTER
ll_sw/ll_adv.c
)
zephyr_library_sources_ifdef(
zephyr_library_sources_ifdef(
CONFIG_BT_OBSERVER
ll_sw/ll_scan.c
)
zephyr_library_sources_ifdef(
zephyr_library_sources_ifdef(
CONFIG_BT_CTLR_FILTER
ll_sw/ll_filter.c
)
zephyr_library_sources_ifdef(
CONFIG_BT_CENTRAL
ll_sw/ll_master.c
)
zephyr_library_sources_ifdef(
zephyr_library_sources_ifdef(
CONFIG_BT_CTLR_ADV_EXT
ll_sw/ll_adv_aux.c
)
zephyr_library_sources_ifdef(
CONFIG_BT_CTLR_DTM
ll_sw/ll_test.c
)
endif()
zephyr_library_sources_ifdef(
CONFIG_BT_CTLR_FILTER
@ -45,21 +54,25 @@ zephyr_library_sources_ifdef(
zephyr_library_sources_ifdef(
CONFIG_SOC_COMPATIBLE_NRF
hal/nrf5/cntr.c
hal/nrf5/ecb.c
hal/nrf5/radio/radio.c
hal/nrf5/mayfly.c
hal/nrf5/ticker.c
ll_sw/nordic/hal/nrf5/cntr.c
ll_sw/nordic/hal/nrf5/ecb.c
ll_sw/nordic/hal/nrf5/radio/radio.c
ll_sw/nordic/hal/nrf5/mayfly.c
ll_sw/nordic/hal/nrf5/ticker.c
)
zephyr_library_include_directories(
.
util
hal
ticker
include
ll_sw
)
if(CONFIG_SOC_COMPATIBLE_NRF)
zephyr_library_include_directories(
ll_sw/nordic
)
endif()
zephyr_library_compile_options_ifdef(
CONFIG_BT_CTLR_FAST_ENC
${OPTIMIZE_FOR_SPEED_FLAG}

View file

@ -52,12 +52,6 @@ config BT_CTLR_RX_PRIO
int
default 6
config BT_CTLR_FILTER
# Hidden option to enable controller whitelist feature
depends on BT_LL_SW
bool
default y
config BT_CTLR_HCI_VS_BUILD_INFO
string "Zephyr HCI VS Build Info string"
default ""
@ -69,7 +63,6 @@ config BT_CTLR_HCI_VS_BUILD_INFO
character is required at the beginning to separate it from the
already included information.
if BT_LL_SW
config BT_CTLR_DUP_FILTER_LEN
int "Number of addresses in the scan duplicate filter"
depends on BT_OBSERVER
@ -205,13 +198,29 @@ config BT_CTLR_LE_ENC
config BT_CTLR_CONN_PARAM_REQ
bool "Connection Parameter Request"
select BT_CTLR_EXT_REJ_IND
default y
help
Enable support for Bluetooth v4.1 Connection Parameter Request feature
in the Controller.
config BT_CTLR_EXT_REJ_IND
bool "Extended Reject Indication"
default y
help
Enable support for Bluetooth v4.1 Extended Reject Indication feature
in the Controller.
config BT_CTLR_SLAVE_FEAT_REQ
bool "Slave-initiated Features Exchange"
default y
help
Enable support for Bluetooth v4.1 Slave-initiated Features Exchange
feature in the Controller.
config BT_CTLR_LE_PING
bool "LE Ping"
depends on BT_CTLR_LE_ENC
default y
help
Enable support for Bluetooth v4.1 LE Ping feature in the Controller.
@ -220,6 +229,7 @@ config BT_CTLR_PRIVACY
bool "LE Controller-based Privacy"
depends on !SOC_SERIES_NRF51X
default y
select BT_CTLR_FILTER
select BT_RPA
help
Enable support for Bluetooth v4.2 LE Controller-based Privacy feature
@ -263,6 +273,7 @@ config BT_CTLR_PHY
# Procedure in the Controller.
bool
depends on BT_PHY_UPDATE
select BT_CTLR_EXT_REJ_IND
default y if SOC_COMPATIBLE_NRF52X
endif # BT_CONN
@ -309,6 +320,13 @@ config BT_CTLR_ADVANCED_FEATURES
menu "Advanced features"
visible if BT_CTLR_ADVANCED_FEATURES
config BT_CTLR_FILTER
prompt "Device Whitelist Support"
bool
default y
help
Enable support for controller device whitelist feature
config BT_CTLR_DATA_LENGTH_CLEAR
bool "Data Length Support (Cleartext only)"
depends on BT_CTLR_DATA_LENGTH && SOC_SERIES_NRF51X
@ -334,14 +352,16 @@ config BT_CTLR_PHY_2M_NRF
Enable support for Nordic Semiconductor proprietary 2Mbps PHY in the
Controller. Encrypted connections are not supported.
endif # BT_CTLR_PHY
config BT_CTLR_PHY_CODED
bool "Coded PHY Support"
depends on SOC_NRF52840
depends on (BT_CTLR_PHY || BT_CTLR_ADV_EXT) && SOC_NRF52840
default y
help
Enable support for Bluetooth 5.0 Coded PHY in the Controller.
endif # BT_CTLR_PHY
if BT_LL_SW
config BT_CTLR_WORKER_PRIO
int "Radio and Ticker's Worker IRQ priority"
@ -361,6 +381,8 @@ config BT_CTLR_JOB_PRIO
The interrupt priority for Ticker's Job (SWI4) IRQ. This value shall
be greater than or equal to the Ticker's Worker IRQ priority value.
endif # BT_LL_SW
config BT_CTLR_XTAL_ADVANCED
bool "Advanced event preparation"
default y
@ -477,11 +499,13 @@ endif # BT_CONN
config BT_CTLR_ADV_INDICATION
bool "Advertisement indications"
depends on BT_BROADCASTER
help
Generate events indicating on air advertisement events.
config BT_CTLR_SCAN_REQ_NOTIFY
bool "Scan Request Notifications"
depends on BT_BROADCASTER
help
Generate events notifying the on air scan requests received.
@ -491,6 +515,12 @@ config BT_CTLR_SCAN_REQ_RSSI
help
Measure RSSI of the on air scan requests received.
config BT_CTLR_SCAN_INDICATION
bool "Scanner indications"
depends on BT_OBSERVER
help
Generate events indicating on air scanner events.
endmenu
comment "BLE Controller hardware configuration"
@ -590,6 +620,4 @@ config BT_CTLR_DEBUG_PINS
when debugging with a logic analyzer or profiling certain sections of
the code.
endif # BT_LL_SW
endif # BT_CTLR

View file

@ -15,4 +15,4 @@ void bt_ctlr_assert_handle(char *file, u32_t line);
#define LL_ASSERT(cond) BT_ASSERT(cond)
#endif
#include "nrf5/debug.h"
#include "hal/debug_vendor_hal.h"

View file

@ -1,245 +0,0 @@
/*
* Copyright (c) 2016-2017 Nordic Semiconductor ASA
* Copyright (c) 2016 Vinayak Kariappa Chettimada
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifdef CONFIG_BT_CTLR_DEBUG_PINS
#if defined(CONFIG_BOARD_NRF52840_PCA10056)
#define DEBUG_PORT NRF_P1
#define DEBUG_PIN0 BIT(1)
#define DEBUG_PIN1 BIT(2)
#define DEBUG_PIN2 BIT(3)
#define DEBUG_PIN3 BIT(4)
#define DEBUG_PIN4 BIT(5)
#define DEBUG_PIN5 BIT(6)
#define DEBUG_PIN6 BIT(7)
#define DEBUG_PIN7 BIT(8)
#define DEBUG_PIN8 BIT(10)
#define DEBUG_PIN9 BIT(11)
#elif defined(CONFIG_BOARD_NRF52_PCA10040) || \
defined(CONFIG_BOARD_NRF52810_PCA10040)
#define DEBUG_PORT NRF_GPIO
#define DEBUG_PIN0 BIT(11)
#define DEBUG_PIN1 BIT(12)
#define DEBUG_PIN2 BIT(13)
#define DEBUG_PIN3 BIT(14)
#define DEBUG_PIN4 BIT(15)
#define DEBUG_PIN5 BIT(16)
#define DEBUG_PIN6 BIT(17)
#define DEBUG_PIN7 BIT(18)
#define DEBUG_PIN8 BIT(19)
#define DEBUG_PIN9 BIT(20)
#elif defined(CONFIG_BOARD_NRF51_PCA10028)
#define DEBUG_PORT NRF_GPIO
#define DEBUG_PIN0 BIT(12)
#define DEBUG_PIN1 BIT(13)
#define DEBUG_PIN2 BIT(14)
#define DEBUG_PIN3 BIT(15)
#define DEBUG_PIN4 BIT(16)
#define DEBUG_PIN5 BIT(17)
#define DEBUG_PIN6 BIT(18)
#define DEBUG_PIN7 BIT(19)
#define DEBUG_PIN8 BIT(20)
#define DEBUG_PIN9 BIT(23)
#else
#error BT_CTLR_DEBUG_PINS not supported on this board.
#endif
#define DEBUG_PIN_MASK (DEBUG_PIN0 | DEBUG_PIN1 | DEBUG_PIN2 | DEBUG_PIN3 | \
DEBUG_PIN4 | DEBUG_PIN5 | DEBUG_PIN6 | DEBUG_PIN7 | \
DEBUG_PIN8 | DEBUG_PIN9)
#define DEBUG_CLOSE_MASK (DEBUG_PIN3 | DEBUG_PIN4 | DEBUG_PIN5 | DEBUG_PIN6)
/* below are some interesting macros referenced by controller
* which can be defined to SoC's GPIO toggle to observe/debug the
* controller's runtime behavior.
*/
#define DEBUG_INIT() do { \
DEBUG_PORT->DIRSET = DEBUG_PIN_MASK; \
DEBUG_PORT->OUTCLR = DEBUG_PIN_MASK; } \
while (0)
#define DEBUG_CPU_SLEEP(flag) do { \
if (flag) { \
DEBUG_PORT->OUTSET = DEBUG_PIN0; \
DEBUG_PORT->OUTCLR = DEBUG_PIN0; } \
else { \
DEBUG_PORT->OUTCLR = DEBUG_PIN0; \
DEBUG_PORT->OUTSET = DEBUG_PIN0; } \
} while (0)
#define DEBUG_TICKER_ISR(flag) do { \
if (flag) { \
DEBUG_PORT->OUTCLR = DEBUG_PIN1; \
DEBUG_PORT->OUTSET = DEBUG_PIN1; } \
else { \
DEBUG_PORT->OUTSET = DEBUG_PIN1; \
DEBUG_PORT->OUTCLR = DEBUG_PIN1; } \
} while (0)
#define DEBUG_TICKER_TASK(flag) do { \
if (flag) { \
DEBUG_PORT->OUTCLR = DEBUG_PIN1; \
DEBUG_PORT->OUTSET = DEBUG_PIN1; } \
else { \
DEBUG_PORT->OUTSET = DEBUG_PIN1; \
DEBUG_PORT->OUTCLR = DEBUG_PIN1; } \
} while (0)
#define DEBUG_TICKER_JOB(flag) do { \
if (flag) { \
DEBUG_PORT->OUTCLR = DEBUG_PIN2; \
DEBUG_PORT->OUTSET = DEBUG_PIN2; } \
else { \
DEBUG_PORT->OUTSET = DEBUG_PIN2; \
DEBUG_PORT->OUTCLR = DEBUG_PIN2; } \
} while (0)
#define DEBUG_RADIO_ISR(flag) do { \
if (flag) { \
DEBUG_PORT->OUTCLR = DEBUG_PIN7; \
DEBUG_PORT->OUTSET = DEBUG_PIN7; } \
else { \
DEBUG_PORT->OUTSET = DEBUG_PIN7; \
DEBUG_PORT->OUTCLR = DEBUG_PIN7; } \
} while (0)
#define DEBUG_RADIO_XTAL(flag) do { \
if (flag) { \
DEBUG_PORT->OUTCLR = DEBUG_PIN8; \
DEBUG_PORT->OUTSET = DEBUG_PIN8; } \
else { \
DEBUG_PORT->OUTSET = DEBUG_PIN8; \
DEBUG_PORT->OUTCLR = DEBUG_PIN8; } \
} while (0)
#define DEBUG_RADIO_ACTIVE(flag) do { \
if (flag) { \
DEBUG_PORT->OUTCLR = DEBUG_PIN9; \
DEBUG_PORT->OUTSET = DEBUG_PIN9; } \
else { \
DEBUG_PORT->OUTSET = DEBUG_PIN9; \
DEBUG_PORT->OUTCLR = DEBUG_PIN9; } \
} while (0)
#define DEBUG_RADIO_CLOSE(flag) do { \
if (flag) { \
DEBUG_PORT->OUTCLR = 0x00000000; \
DEBUG_PORT->OUTSET = 0x00000000; } \
else { \
DEBUG_PORT->OUTCLR = DEBUG_CLOSE_MASK; } \
} while (0)
#define DEBUG_RADIO_PREPARE_A(flag) do { \
if (flag) { \
DEBUG_PORT->OUTCLR = DEBUG_PIN3; \
DEBUG_PORT->OUTSET = DEBUG_PIN3; } \
else { \
DEBUG_PORT->OUTCLR = DEBUG_PIN3; \
DEBUG_PORT->OUTSET = DEBUG_PIN3; } \
} while (0)
#define DEBUG_RADIO_START_A(flag) do { \
if (flag) { \
DEBUG_PORT->OUTCLR = DEBUG_PIN3; \
DEBUG_PORT->OUTSET = DEBUG_PIN3; } \
else { \
DEBUG_PORT->OUTCLR = DEBUG_PIN3; \
DEBUG_PORT->OUTSET = DEBUG_PIN3; } \
} while (0)
#define DEBUG_RADIO_PREPARE_S(flag) do { \
if (flag) { \
DEBUG_PORT->OUTCLR = DEBUG_PIN4; \
DEBUG_PORT->OUTSET = DEBUG_PIN4; } \
else { \
DEBUG_PORT->OUTCLR = DEBUG_PIN4; \
DEBUG_PORT->OUTSET = DEBUG_PIN4; } \
} while (0)
#define DEBUG_RADIO_START_S(flag) do { \
if (flag) { \
DEBUG_PORT->OUTCLR = DEBUG_PIN4; \
DEBUG_PORT->OUTSET = DEBUG_PIN4; } \
else { \
DEBUG_PORT->OUTCLR = DEBUG_PIN4; \
DEBUG_PORT->OUTSET = DEBUG_PIN4; } \
} while (0)
#define DEBUG_RADIO_PREPARE_O(flag) do { \
if (flag) { \
DEBUG_PORT->OUTCLR = DEBUG_PIN5; \
DEBUG_PORT->OUTSET = DEBUG_PIN5; } \
else { \
DEBUG_PORT->OUTCLR = DEBUG_PIN5; \
DEBUG_PORT->OUTSET = DEBUG_PIN5; } \
} while (0)
#define DEBUG_RADIO_START_O(flag) do { \
if (flag) { \
DEBUG_PORT->OUTCLR = DEBUG_PIN5; \
DEBUG_PORT->OUTSET = DEBUG_PIN5; } \
else { \
DEBUG_PORT->OUTCLR = DEBUG_PIN5; \
DEBUG_PORT->OUTSET = DEBUG_PIN5; } \
} while (0)
#define DEBUG_RADIO_PREPARE_M(flag) do { \
if (flag) { \
DEBUG_PORT->OUTCLR = DEBUG_PIN6; \
DEBUG_PORT->OUTSET = DEBUG_PIN6; } \
else { \
DEBUG_PORT->OUTCLR = DEBUG_PIN6; \
DEBUG_PORT->OUTSET = DEBUG_PIN6; } \
} while (0)
#define DEBUG_RADIO_START_M(flag) do { \
if (flag) { \
DEBUG_PORT->OUTCLR = DEBUG_PIN6; \
DEBUG_PORT->OUTSET = DEBUG_PIN6; } \
else { \
DEBUG_PORT->OUTCLR = DEBUG_PIN6; \
DEBUG_PORT->OUTSET = DEBUG_PIN6; } \
} while (0)
#else
#define DEBUG_INIT()
#define DEBUG_CPU_SLEEP(flag)
#define DEBUG_TICKER_ISR(flag)
#define DEBUG_TICKER_TASK(flag)
#define DEBUG_TICKER_JOB(flag)
#define DEBUG_RADIO_ISR(flag)
#define DEBUG_RADIO_HCTO(flag)
#define DEBUG_RADIO_XTAL(flag)
#define DEBUG_RADIO_ACTIVE(flag)
#define DEBUG_RADIO_CLOSE(flag)
#define DEBUG_RADIO_PREPARE_A(flag)
#define DEBUG_RADIO_START_A(flag)
#define DEBUG_RADIO_PREPARE_S(flag)
#define DEBUG_RADIO_START_S(flag)
#define DEBUG_RADIO_PREPARE_O(flag)
#define DEBUG_RADIO_START_O(flag)
#define DEBUG_RADIO_PREPARE_M(flag)
#define DEBUG_RADIO_START_M(flag)
#endif /* CONFIG_BT_CTLR_DEBUG_PINS */

View file

@ -1,98 +1,7 @@
/*
* Copyright (c) 2016 Nordic Semiconductor ASA
* Copyright (c) 2016 Vinayak Kariappa Chettimada
* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
typedef void (*radio_isr_fp) (void);
void isr_radio(void);
void radio_isr_set(radio_isr_fp fp_radio_isr);
void radio_setup(void);
void radio_reset(void);
void radio_phy_set(u8_t phy, u8_t flags);
void radio_tx_power_set(u32_t power);
void radio_tx_power_max_set(void);
void radio_freq_chan_set(u32_t chan);
void radio_whiten_iv_set(u32_t iv);
void radio_aa_set(u8_t *aa);
void radio_pkt_configure(u8_t bits_len, u8_t max_len, u8_t flags);
void radio_pkt_rx_set(void *rx_packet);
void radio_pkt_tx_set(void *tx_packet);
u32_t radio_tx_ready_delay_get(u8_t phy, u8_t flags);
u32_t radio_tx_chain_delay_get(u8_t phy, u8_t flags);
u32_t radio_rx_ready_delay_get(u8_t phy, u8_t flags);
u32_t radio_rx_chain_delay_get(u8_t phy, u8_t flags);
void radio_rx_enable(void);
void radio_tx_enable(void);
void radio_disable(void);
void radio_status_reset(void);
u32_t radio_is_ready(void);
u32_t radio_is_done(void);
u32_t radio_has_disabled(void);
u32_t radio_is_idle(void);
void radio_crc_configure(u32_t polynomial, u32_t iv);
u32_t radio_crc_is_valid(void);
void *radio_pkt_empty_get(void);
void *radio_pkt_scratch_get(void);
void radio_switch_complete_and_rx(u8_t phy_rx);
void radio_switch_complete_and_tx(u8_t phy_rx, u8_t flags_rx, u8_t phy_tx,
u8_t flags_tx);
void radio_switch_complete_and_disable(void);
void radio_rssi_measure(void);
u32_t radio_rssi_get(void);
void radio_rssi_status_reset(void);
u32_t radio_rssi_is_ready(void);
void radio_filter_configure(u8_t bitmask_enable, u8_t bitmask_addr_type,
u8_t *bdaddr);
void radio_filter_disable(void);
void radio_filter_status_reset(void);
u32_t radio_filter_has_match(void);
u32_t radio_filter_match_get(void);
void radio_bc_configure(u32_t n);
void radio_bc_status_reset(void);
u32_t radio_bc_has_match(void);
void radio_tmr_status_reset(void);
void radio_tmr_tifs_set(u32_t tifs);
u32_t radio_tmr_start(u8_t trx, u32_t ticks_start, u32_t remainder);
void radio_tmr_start_us(u8_t trx, u32_t us);
u32_t radio_tmr_start_now(u8_t trx);
void radio_tmr_stop(void);
void radio_tmr_hcto_configure(u32_t hcto);
void radio_tmr_aa_capture(void);
u32_t radio_tmr_aa_get(void);
void radio_tmr_aa_save(u32_t aa);
u32_t radio_tmr_aa_restore(void);
u32_t radio_tmr_ready_get(void);
void radio_tmr_end_capture(void);
u32_t radio_tmr_end_get(void);
u32_t radio_tmr_tifs_base_get(void);
void radio_tmr_sample(void);
u32_t radio_tmr_sample_get(void);
void radio_gpio_pa_setup(void);
void radio_gpio_lna_setup(void);
void radio_gpio_lna_on(void);
void radio_gpio_lna_off(void);
void radio_gpio_pa_lna_enable(u32_t trx_us);
void radio_gpio_pa_lna_disable(void);
void *radio_ccm_rx_pkt_set(struct ccm *ccm, u8_t phy, void *pkt);
void *radio_ccm_tx_pkt_set(struct ccm *ccm, void *pkt);
u32_t radio_ccm_is_done(void);
u32_t radio_ccm_mic_is_valid(void);
void radio_ar_configure(u32_t nirk, void *irk);
u32_t radio_ar_match_get(void);
void radio_ar_status_reset(void);
u32_t radio_ar_has_match(void);
#include "hal/radio_vendor_hal.h"

View file

@ -5,11 +5,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdbool.h>
#if defined(CONFIG_SOC_COMPATIBLE_NRF)
#include "hal/nrf5/ticker.h"
#endif /* CONFIG_SOC_FAMILY_NRF */
#include "hal/ticker_vendor_hal.h"
u8_t hal_ticker_instance0_caller_id_get(u8_t user_id);
void hal_ticker_instance0_sched(u8_t caller_id, u8_t callee_id, u8_t chain,

File diff suppressed because it is too large Load diff

View file

@ -33,18 +33,22 @@
#include "common/log.h"
#include "util/util.h"
#include "util/memq.h"
#include "hal/ccm.h"
#if defined(CONFIG_SOC_FAMILY_NRF)
#include "hal/radio.h"
#endif /* CONFIG_SOC_FAMILY_NRF */
#include "ll_sw/pdu.h"
#include "ll_sw/ctrl.h"
#include "ll_sw/lll.h"
#include "ll.h"
#include "hci_internal.h"
#include "hal/debug.h"
#define NODE_RX(_node) CONTAINER_OF(_node, struct radio_pdu_node_rx, \
hdr.onion.node)
static K_SEM_DEFINE(sem_prio_recv, 0, UINT_MAX);
static K_FIFO_DEFINE(recv_fifo);
@ -109,7 +113,7 @@ static void prio_recv_thread(void *p1, void *p2, void *p3)
}
}
static inline struct net_buf *encode_node(struct radio_pdu_node_rx *node_rx,
static inline struct net_buf *encode_node(struct node_rx_pdu *node_rx,
s8_t class)
{
struct net_buf *buf = NULL;
@ -141,16 +145,20 @@ static inline struct net_buf *encode_node(struct radio_pdu_node_rx *node_rx,
}
#if defined(CONFIG_BT_LL_SW)
{
extern u8_t radio_rx_fc_set(u16_t handle, u8_t fc);
radio_rx_fc_set(node_rx->hdr.handle, 0);
}
#endif /* CONFIG_BT_LL_SW */
node_rx->hdr.onion.next = 0;
node_rx->hdr.next = NULL;
ll_rx_mem_release((void **)&node_rx);
return buf;
}
static inline struct net_buf *process_node(struct radio_pdu_node_rx *node_rx)
static inline struct net_buf *process_node(struct node_rx_pdu *node_rx)
{
s8_t class = hci_get_class(node_rx);
struct net_buf *buf = NULL;
@ -170,8 +178,7 @@ static inline struct net_buf *process_node(struct radio_pdu_node_rx *node_rx)
/* fallthrough */
case HCI_CLASS_ACL_DATA:
if (pend || !hbuf_count) {
sys_slist_append(&hbuf_pend,
&node_rx->hdr.onion.node);
sys_slist_append(&hbuf_pend, (void *)node_rx);
BT_DBG("FC: Queuing item: %d", class);
return NULL;
}
@ -190,13 +197,12 @@ static inline struct net_buf *process_node(struct radio_pdu_node_rx *node_rx)
}
#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
static inline struct net_buf *process_hbuf(struct radio_pdu_node_rx *n)
static inline struct net_buf *process_hbuf(struct node_rx_pdu *n)
{
/* shadow total count in case of preemption */
struct radio_pdu_node_rx *node_rx = NULL;
struct node_rx_pdu *node_rx = NULL;
s32_t hbuf_total = hci_hbuf_total;
struct net_buf *buf = NULL;
sys_snode_t *node = NULL;
s8_t class;
int reset;
@ -215,13 +221,12 @@ static inline struct net_buf *process_hbuf(struct radio_pdu_node_rx *n)
hbuf_count = hbuf_total - (hci_hbuf_sent - hci_hbuf_acked);
/* host acked ACL packets, try to dequeue from hbuf */
node = sys_slist_peek_head(&hbuf_pend);
if (!node) {
node_rx = (void *)sys_slist_peek_head(&hbuf_pend);
if (!node_rx) {
return NULL;
}
/* Return early if this iteration already has a node to process */
node_rx = NODE_RX(node);
class = hci_get_class(node_rx);
if (n) {
if (class == HCI_CLASS_EVT_CONNECTION ||
@ -244,7 +249,7 @@ static inline struct net_buf *process_hbuf(struct radio_pdu_node_rx *n)
(void) sys_slist_get(&hbuf_pend);
} else {
/* no buffers, HCI will signal */
node = NULL;
node_rx = NULL;
}
break;
case HCI_CLASS_EVT_DISCARDABLE:
@ -254,14 +259,13 @@ static inline struct net_buf *process_hbuf(struct radio_pdu_node_rx *n)
break;
}
if (node) {
if (node_rx) {
buf = encode_node(node_rx, class);
/* Update host buffers after encoding */
hbuf_count = hbuf_total - (hci_hbuf_sent - hci_hbuf_acked);
/* next node */
node = sys_slist_peek_head(&hbuf_pend);
if (node) {
node_rx = NODE_RX(node);
node_rx = (void *)sys_slist_peek_head(&hbuf_pend);
if (node_rx) {
class = hci_get_class(node_rx);
if (class == HCI_CLASS_EVT_CONNECTION ||
@ -294,7 +298,7 @@ static void recv_thread(void *p1, void *p2, void *p3)
#endif
while (1) {
struct radio_pdu_node_rx *node_rx = NULL;
struct node_rx_pdu *node_rx = NULL;
struct net_buf *buf = NULL;
BT_DBG("blocking");

View file

@ -33,10 +33,10 @@ extern atomic_t hci_state_mask;
void hci_init(struct k_poll_signal *signal_host_buf);
struct net_buf *hci_cmd_handle(struct net_buf *cmd, void **node_rx);
void hci_evt_encode(struct radio_pdu_node_rx *node_rx, struct net_buf *buf);
s8_t hci_get_class(struct radio_pdu_node_rx *node_rx);
void hci_evt_encode(struct node_rx_pdu *node_rx, struct net_buf *buf);
s8_t hci_get_class(struct node_rx_pdu *node_rx);
#if defined(CONFIG_BT_CONN)
int hci_acl_handle(struct net_buf *acl, struct net_buf **evt);
void hci_acl_encode(struct radio_pdu_node_rx *node_rx, struct net_buf *buf);
void hci_acl_encode(struct node_rx_pdu *node_rx, struct net_buf *buf);
void hci_num_cmplt_encode(struct net_buf *buf, u16_t handle, u8_t num);
#endif

View file

@ -1,77 +1,85 @@
/*
* Copyright (c) 2016 Nordic Semiconductor ASA
* Copyright (c) 2016-2018 Nordic Semiconductor ASA
* Copyright (c) 2016 Vinayak Kariappa Chettimada
*
* SPDX-License-Identifier: Apache-2.0
*/
#define LL_VERSION_NUMBER BT_HCI_VERSION_5_0
int ll_init(struct k_sem *sem_rx);
void ll_reset(void);
u8_t *ll_addr_get(u8_t addr_type, u8_t *p_bdaddr);
u32_t ll_addr_set(u8_t addr_type, u8_t const *const p_bdaddr);
u8_t ll_addr_set(u8_t addr_type, u8_t const *const p_bdaddr);
#if defined(CONFIG_BT_CTLR_ADV_EXT)
u32_t ll_adv_params_set(u8_t handle, u16_t evt_prop, u32_t interval,
u8_t ll_adv_params_set(u8_t handle, u16_t evt_prop, u32_t interval,
u8_t adv_type, u8_t own_addr_type,
u8_t direct_addr_type, u8_t const *const direct_addr,
u8_t chan_map, u8_t filter_policy, u8_t *tx_pwr,
u8_t phy_p, u8_t skip, u8_t phy_s, u8_t sid, u8_t sreq);
u8_t ll_adv_data_set(u16_t handle, u8_t len, u8_t const *const p_data);
u8_t ll_adv_scan_rsp_set(u16_t handle, u8_t len, u8_t const *const p_data);
#else /* !CONFIG_BT_CTLR_ADV_EXT */
u32_t ll_adv_params_set(u16_t interval, u8_t adv_type,
u8_t ll_adv_params_set(u16_t interval, u8_t adv_type,
u8_t own_addr_type, u8_t direct_addr_type,
u8_t const *const direct_addr, u8_t chan_map,
u8_t filter_policy);
u8_t ll_adv_data_set(u8_t len, u8_t const *const p_data);
u8_t ll_adv_scan_rsp_set(u8_t len, u8_t const *const p_data);
#endif /* !CONFIG_BT_CTLR_ADV_EXT */
void ll_adv_data_set(u8_t len, u8_t const *const p_data);
void ll_scan_data_set(u8_t len, u8_t const *const p_data);
u32_t ll_adv_enable(u8_t enable);
u32_t ll_scan_params_set(u8_t type, u16_t interval, u16_t window,
u8_t own_addr_type, u8_t filter_policy);
u32_t ll_scan_enable(u8_t enable);
#if defined(CONFIG_BT_CTLR_ADV_EXT)
u8_t ll_adv_enable(u16_t handle, u8_t enable);
#else /* !CONFIG_BT_CTLR_ADV_EXT */
u8_t ll_adv_enable(u8_t enable);
#endif /* !CONFIG_BT_CTLR_ADV_EXT */
u32_t ll_wl_size_get(void);
u32_t ll_wl_clear(void);
u32_t ll_wl_add(bt_addr_le_t *addr);
u32_t ll_wl_remove(bt_addr_le_t *addr);
u8_t ll_scan_params_set(u8_t type, u16_t interval, u16_t window,
u8_t own_addr_type, u8_t filter_policy);
u8_t ll_scan_enable(u8_t enable);
u8_t ll_wl_size_get(void);
u8_t ll_wl_clear(void);
u8_t ll_wl_add(bt_addr_le_t *addr);
u8_t ll_wl_remove(bt_addr_le_t *addr);
void ll_rl_id_addr_get(u8_t rl_idx, u8_t *id_addr_type, u8_t *id_addr);
u32_t ll_rl_size_get(void);
u32_t ll_rl_clear(void);
u32_t ll_rl_add(bt_addr_le_t *id_addr, const u8_t pirk[16],
u8_t ll_rl_size_get(void);
u8_t ll_rl_clear(void);
u8_t ll_rl_add(bt_addr_le_t *id_addr, const u8_t pirk[16],
const u8_t lirk[16]);
u32_t ll_rl_remove(bt_addr_le_t *id_addr);
u8_t ll_rl_remove(bt_addr_le_t *id_addr);
void ll_rl_crpa_set(u8_t id_addr_type, u8_t *id_addr, u8_t rl_idx, u8_t *crpa);
u32_t ll_rl_crpa_get(bt_addr_le_t *id_addr, bt_addr_t *crpa);
u32_t ll_rl_lrpa_get(bt_addr_le_t *id_addr, bt_addr_t *lrpa);
u32_t ll_rl_enable(u8_t enable);
u8_t ll_rl_crpa_get(bt_addr_le_t *id_addr, bt_addr_t *crpa);
u8_t ll_rl_lrpa_get(bt_addr_le_t *id_addr, bt_addr_t *lrpa);
u8_t ll_rl_enable(u8_t enable);
void ll_rl_timeout_set(u16_t timeout);
u32_t ll_priv_mode_set(bt_addr_le_t *id_addr, u8_t mode);
u8_t ll_priv_mode_set(bt_addr_le_t *id_addr, u8_t mode);
u32_t ll_create_connection(u16_t scan_interval, u16_t scan_window,
u8_t ll_create_connection(u16_t scan_interval, u16_t scan_window,
u8_t filter_policy, u8_t peer_addr_type,
u8_t *p_peer_addr, u8_t own_addr_type,
u16_t interval, u16_t latency,
u16_t timeout);
u32_t ll_connect_disable(void **node_rx);
u32_t ll_conn_update(u16_t handle, u8_t cmd, u8_t status, u16_t interval_min,
u16_t interval, u16_t latency, u16_t timeout);
u8_t ll_connect_disable(void **rx);
u8_t ll_conn_update(u16_t handle, u8_t cmd, u8_t status, u16_t interval_min,
u16_t interval_max, u16_t latency, u16_t timeout);
u32_t ll_chm_update(u8_t *chm);
u32_t ll_chm_get(u16_t handle, u8_t *chm);
u32_t ll_enc_req_send(u16_t handle, u8_t *rand, u8_t *ediv,
u8_t ll_chm_update(u8_t *chm);
u8_t ll_chm_get(u16_t handle, u8_t *chm);
u8_t ll_enc_req_send(u16_t handle, u8_t *rand, u8_t *ediv,
u8_t *ltk);
u32_t ll_start_enc_req_send(u16_t handle, u8_t err_code,
u8_t ll_start_enc_req_send(u16_t handle, u8_t err_code,
u8_t const *const ltk);
u32_t ll_feature_req_send(u16_t handle);
u32_t ll_version_ind_send(u16_t handle);
u32_t ll_terminate_ind_send(u16_t handle, u8_t reason);
u32_t ll_rssi_get(u16_t handle, u8_t *rssi);
u32_t ll_tx_pwr_lvl_get(u16_t handle, u8_t type, s8_t *tx_pwr_lvl);
u8_t ll_feature_req_send(u16_t handle);
u8_t ll_version_ind_send(u16_t handle);
u8_t ll_terminate_ind_send(u16_t handle, u8_t reason);
u8_t ll_rssi_get(u16_t handle, u8_t *rssi);
u8_t ll_tx_pwr_lvl_get(u16_t handle, u8_t type, s8_t *tx_pwr_lvl);
void ll_tx_pwr_get(s8_t *min, s8_t *max);
u32_t ll_apto_get(u16_t handle, u16_t *apto);
u32_t ll_apto_set(u16_t handle, u16_t apto);
u8_t ll_apto_get(u16_t handle, u16_t *apto);
u8_t ll_apto_set(u16_t handle, u16_t apto);
u32_t ll_length_req_send(u16_t handle, u16_t tx_octets, u16_t tx_time);
void ll_length_default_get(u16_t *max_tx_octets, u16_t *max_tx_time);
@ -86,7 +94,7 @@ u32_t ll_phy_req_send(u16_t handle, u8_t tx, u8_t flags, u8_t rx);
/* Downstream - Data */
void *ll_tx_mem_acquire(void);
void ll_tx_mem_release(void *node_tx);
u32_t ll_tx_mem_enqueue(u16_t handle, void *node_tx);
int ll_tx_mem_enqueue(u16_t handle, void *node_tx);
/* Upstream - Num. Completes, Events and Data */
u8_t ll_rx_get(void **node_rx, u16_t *handle);

View file

@ -0,0 +1,100 @@
/*
* Copyright (c) 2016-2018 Nordic Semiconductor ASA
* Copyright (c) 2016 Vinayak Kariappa Chettimada
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef BIT64
#define BIT64(n) (1ULL << (n))
#endif
#if defined(CONFIG_BT_CTLR_LE_ENC)
#define LL_FEAT_BIT_ENC BIT64(BT_LE_FEAT_BIT_ENC)
#else /* !CONFIG_BT_CTLR_LE_ENC */
#define LL_FEAT_BIT_ENC 0
#endif /* !CONFIG_BT_CTLR_LE_ENC */
#if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
#define LL_FEAT_BIT_CONN_PARAM_REQ BIT64(BT_LE_FEAT_BIT_CONN_PARAM_REQ)
#else /* !CONFIG_BT_CTLR_CONN_PARAM_REQ */
#define LL_FEAT_BIT_CONN_PARAM_REQ 0
#endif /* !CONFIG_BT_CTLR_CONN_PARAM_REQ */
#if defined(CONFIG_BT_CTLR_EXT_REJ_IND)
#define LL_FEAT_BIT_EXT_REJ_IND BIT64(BT_LE_FEAT_BIT_EXT_REJ_IND)
#else /* !CONFIG_BT_CTLR_EXT_REJ_IND */
#define LL_FEAT_BIT_EXT_REJ_IND 0
#endif /* !CONFIG_BT_CTLR_EXT_REJ_IND */
#if defined(CONFIG_BT_CTLR_SLAVE_FEAT_REQ)
#define LL_FEAT_BIT_SLAVE_FEAT_REQ BIT64(BT_LE_FEAT_BIT_SLAVE_FEAT_REQ)
#else /* !CONFIG_BT_CTLR_SLAVE_FEAT_REQ */
#define LL_FEAT_BIT_SLAVE_FEAT_REQ 0
#endif /* !CONFIG_BT_CTLR_SLAVE_FEAT_REQ */
#if defined(CONFIG_BT_CTLR_LE_PING)
#define LL_FEAT_BIT_PING BIT64(BT_LE_FEAT_BIT_PING)
#else /* !CONFIG_BT_CTLR_LE_PING */
#define LL_FEAT_BIT_PING 0
#endif /* !CONFIG_BT_CTLR_LE_PING */
#if defined(CONFIG_BT_CTLR_DATA_LENGTH_MAX)
#define LL_FEAT_BIT_DLE BIT64(BT_LE_FEAT_BIT_DLE)
#define LL_LENGTH_OCTETS_RX_MAX CONFIG_BT_CTLR_DATA_LENGTH_MAX
#else
#define LL_FEAT_BIT_DLE 0
#define LL_LENGTH_OCTETS_RX_MAX 27
#endif /* CONFIG_BT_CTLR_DATA_LENGTH_MAX */
#if defined(CONFIG_BT_CTLR_PRIVACY)
#define LL_FEAT_BIT_PRIVACY BIT64(BT_LE_FEAT_BIT_PRIVACY)
#else /* !CONFIG_BT_CTLR_PRIVACY */
#define LL_FEAT_BIT_PRIVACY 0
#endif /* !CONFIG_BT_CTLR_PRIVACY */
#if defined(CONFIG_BT_CTLR_EXT_SCAN_FP)
#define LL_FEAT_BIT_EXT_SCAN BIT64(BT_LE_FEAT_BIT_EXT_SCAN)
#else /* !CONFIG_BT_CTLR_EXT_SCAN_FP */
#define LL_FEAT_BIT_EXT_SCAN 0
#endif /* !CONFIG_BT_CTLR_EXT_SCAN_FP */
#if defined(CONFIG_BT_CTLR_CHAN_SEL_2)
#define LL_FEAT_BIT_CHAN_SEL_2 BIT64(BT_LE_FEAT_BIT_CHAN_SEL_ALGO_2)
#else /* !CONFIG_BT_CTLR_CHAN_SEL_2 */
#define LL_FEAT_BIT_CHAN_SEL_2 0
#endif /* !CONFIG_BT_CTLR_CHAN_SEL_2 */
#if defined(CONFIG_BT_CTLR_MIN_USED_CHAN)
#define LL_FEAT_BIT_MIN_USED_CHAN \
BIT64(BT_LE_FEAT_BIT_MIN_USED_CHAN_PROC)
#else /* !CONFIG_BT_CTLR_MIN_USED_CHAN */
#define LL_FEAT_BIT_MIN_USED_CHAN 0
#endif /* !CONFIG_BT_CTLR_MIN_USED_CHAN */
#if defined(CONFIG_BT_CTLR_PHY_2M)
#define LL_FEAT_BIT_PHY_2M BIT64(BT_LE_FEAT_BIT_PHY_2M)
#else /* !CONFIG_BT_CTLR_PHY_2M */
#define LL_FEAT_BIT_PHY_2M 0
#endif /* !CONFIG_BT_CTLR_PHY_2M */
#if defined(CONFIG_BT_CTLR_PHY_CODED)
#define LL_FEAT_BIT_PHY_CODED BIT64(BT_LE_FEAT_BIT_PHY_CODED)
#else /* !CONFIG_BT_CTLR_PHY_CODED */
#define LL_FEAT_BIT_PHY_CODED 0
#endif /* !CONFIG_BT_CTLR_PHY_CODED */
#define LL_FEAT_BIT_MASK 0x1FFFF
#define LL_FEAT_BIT_MASK_VALID 0x1CF2F
#define LL_FEAT (LL_FEAT_BIT_ENC | \
LL_FEAT_BIT_CONN_PARAM_REQ | \
LL_FEAT_BIT_EXT_REJ_IND | \
LL_FEAT_BIT_SLAVE_FEAT_REQ | \
LL_FEAT_BIT_PING | \
LL_FEAT_BIT_DLE | \
LL_FEAT_BIT_PRIVACY | \
LL_FEAT_BIT_EXT_SCAN | \
LL_FEAT_BIT_PHY_2M | \
LL_FEAT_BIT_PHY_CODED | \
LL_FEAT_BIT_CHAN_SEL_2 | \
LL_FEAT_BIT_MIN_USED_CHAN)

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016 Nordic Semiconductor ASA
* Copyright (c) 2016-2018 Nordic Semiconductor ASA
* Copyright (c) 2016 Vinayak Kariappa Chettimada
*
* SPDX-License-Identifier: Apache-2.0
@ -26,71 +26,6 @@
#define RADIO_PACKET_TX_DATA_SIZE CONFIG_BT_CTLR_TX_BUFFER_SIZE
#endif
#define BIT64(n) (1ULL << (n))
#if defined(CONFIG_BT_CTLR_LE_ENC)
#define RADIO_BLE_FEAT_BIT_ENC BIT64(BT_LE_FEAT_BIT_ENC)
#else /* !CONFIG_BT_CTLR_LE_ENC */
#define RADIO_BLE_FEAT_BIT_ENC 0
#endif /* !CONFIG_BT_CTLR_LE_ENC */
#if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
#define RADIO_BLE_FEAT_BIT_CONN_PARAM_REQ BIT64(BT_LE_FEAT_BIT_CONN_PARAM_REQ)
#else /* !CONFIG_BT_CTLR_CONN_PARAM_REQ */
#define RADIO_BLE_FEAT_BIT_CONN_PARAM_REQ 0
#endif /* !CONFIG_BT_CTLR_CONN_PARAM_REQ */
#if defined(CONFIG_BT_CTLR_LE_PING)
#define RADIO_BLE_FEAT_BIT_PING BIT64(BT_LE_FEAT_BIT_PING)
#else /* !CONFIG_BT_CTLR_LE_PING */
#define RADIO_BLE_FEAT_BIT_PING 0
#endif /* !CONFIG_BT_CTLR_LE_PING */
#if defined(CONFIG_BT_CTLR_DATA_LENGTH_MAX)
#define RADIO_BLE_FEAT_BIT_DLE BIT64(BT_LE_FEAT_BIT_DLE)
#define RADIO_LL_LENGTH_OCTETS_RX_MAX CONFIG_BT_CTLR_DATA_LENGTH_MAX
#else
#define RADIO_BLE_FEAT_BIT_DLE 0
#define RADIO_LL_LENGTH_OCTETS_RX_MAX 27
#endif /* CONFIG_BT_CTLR_DATA_LENGTH_MAX */
#if defined(CONFIG_BT_CTLR_PRIVACY)
#define RADIO_BLE_FEAT_BIT_PRIVACY BIT64(BT_LE_FEAT_BIT_PRIVACY)
#else /* !CONFIG_BT_CTLR_PRIVACY */
#define RADIO_BLE_FEAT_BIT_PRIVACY 0
#endif /* !CONFIG_BT_CTLR_PRIVACY */
#if defined(CONFIG_BT_CTLR_EXT_SCAN_FP)
#define RADIO_BLE_FEAT_BIT_EXT_SCAN BIT64(BT_LE_FEAT_BIT_EXT_SCAN)
#else /* !CONFIG_BT_CTLR_EXT_SCAN_FP */
#define RADIO_BLE_FEAT_BIT_EXT_SCAN 0
#endif /* !CONFIG_BT_CTLR_EXT_SCAN_FP */
#if defined(CONFIG_BT_CTLR_CHAN_SEL_2)
#define RADIO_BLE_FEAT_BIT_CHAN_SEL_2 BIT64(BT_LE_FEAT_BIT_CHAN_SEL_ALGO_2)
#else /* !CONFIG_BT_CTLR_CHAN_SEL_2 */
#define RADIO_BLE_FEAT_BIT_CHAN_SEL_2 0
#endif /* !CONFIG_BT_CTLR_CHAN_SEL_2 */
#if defined(CONFIG_BT_CTLR_MIN_USED_CHAN)
#define RADIO_BLE_FEAT_BIT_MIN_USED_CHAN \
BIT64(BT_LE_FEAT_BIT_MIN_USED_CHAN_PROC)
#else /* !CONFIG_BT_CTLR_MIN_USED_CHAN */
#define RADIO_BLE_FEAT_BIT_MIN_USED_CHAN 0
#endif /* !CONFIG_BT_CTLR_MIN_USED_CHAN */
#if defined(CONFIG_BT_CTLR_PHY_2M)
#define RADIO_BLE_FEAT_BIT_PHY_2M BIT64(BT_LE_FEAT_BIT_PHY_2M)
#else /* !CONFIG_BT_CTLR_PHY_2M */
#define RADIO_BLE_FEAT_BIT_PHY_2M 0
#endif /* !CONFIG_BT_CTLR_PHY_2M */
#if defined(CONFIG_BT_CTLR_PHY_CODED)
#define RADIO_BLE_FEAT_BIT_PHY_CODED BIT64(BT_LE_FEAT_BIT_PHY_CODED)
#else /* !CONFIG_BT_CTLR_PHY_CODED */
#define RADIO_BLE_FEAT_BIT_PHY_CODED 0
#endif /* !CONFIG_BT_CTLR_PHY_CODED */
/*****************************************************************************
* Timer Resources (Controller defined)
****************************************************************************/
@ -115,46 +50,16 @@
#define RADIO_TICKER_USER_WORKER_OPS (7 + 1)
#define RADIO_TICKER_USER_JOB_OPS (2 + 1)
#define RADIO_TICKER_USER_APP_OPS (1 + 1)
#define RADIO_TICKER_USER_OPS (RADIO_TICKER_USER_WORKER_OPS \
+ RADIO_TICKER_USER_JOB_OPS \
+ RADIO_TICKER_USER_APP_OPS \
)
#define RADIO_TICKER_USER_OPS (RADIO_TICKER_USER_WORKER_OPS + \
RADIO_TICKER_USER_JOB_OPS + \
RADIO_TICKER_USER_APP_OPS)
#define RADIO_TICKER_NODES (RADIO_TICKER_ID_FIRST_CONNECTION \
+ RADIO_CONNECTION_CONTEXT_MAX \
)
#define RADIO_TICKER_NODES (RADIO_TICKER_ID_FIRST_CONNECTION + \
RADIO_CONNECTION_CONTEXT_MAX)
/*****************************************************************************
* Controller Interface Defines
****************************************************************************/
#define RADIO_BLE_VERSION_NUMBER BT_HCI_VERSION_5_0
#if defined(CONFIG_BT_CTLR_COMPANY_ID)
#define RADIO_BLE_COMPANY_ID CONFIG_BT_CTLR_COMPANY_ID
#else
#define RADIO_BLE_COMPANY_ID 0xFFFF
#endif
#if defined(CONFIG_BT_CTLR_SUBVERSION_NUMBER)
#define RADIO_BLE_SUB_VERSION_NUMBER \
CONFIG_BT_CTLR_SUBVERSION_NUMBER
#else
#define RADIO_BLE_SUB_VERSION_NUMBER 0xFFFF
#endif
#define RADIO_BLE_FEAT_BIT_MASK 0x1FFFF
#define RADIO_BLE_FEAT_BIT_MASK_VALID 0x1CF2F
#define RADIO_BLE_FEAT (RADIO_BLE_FEAT_BIT_ENC | \
RADIO_BLE_FEAT_BIT_CONN_PARAM_REQ | \
BIT(BT_LE_FEAT_BIT_EXT_REJ_IND) | \
BIT(BT_LE_FEAT_BIT_SLAVE_FEAT_REQ) | \
RADIO_BLE_FEAT_BIT_PING | \
RADIO_BLE_FEAT_BIT_DLE | \
RADIO_BLE_FEAT_BIT_PRIVACY | \
RADIO_BLE_FEAT_BIT_EXT_SCAN | \
RADIO_BLE_FEAT_BIT_PHY_2M | \
RADIO_BLE_FEAT_BIT_PHY_CODED | \
RADIO_BLE_FEAT_BIT_CHAN_SEL_2 | \
RADIO_BLE_FEAT_BIT_MIN_USED_CHAN)
#if defined(CONFIG_BT_CTLR_WORKER_PRIO)
#define RADIO_TICKER_USER_ID_WORKER_PRIO CONFIG_BT_CTLR_WORKER_PRIO
#else
@ -170,45 +75,32 @@
/*****************************************************************************
* Controller Reference Defines (compile time override-able)
****************************************************************************/
/* Minimum LL Payload support (Dont change). */
#define RADIO_LL_LENGTH_OCTETS_RX_MIN 27
/* Maximum LL Payload support (27 to 251). */
#ifndef RADIO_LL_LENGTH_OCTETS_RX_MAX
#define RADIO_LL_LENGTH_OCTETS_RX_MAX 251
#endif
/* Implementation default L2CAP MTU */
#ifndef RADIO_L2CAP_MTU_MAX
#define RADIO_L2CAP_MTU_MAX (RADIO_LL_LENGTH_OCTETS_RX_MAX - 4)
#define RADIO_L2CAP_MTU_MAX (LL_LENGTH_OCTETS_RX_MAX - 4)
#endif
/* Maximise L2CAP MTU to LL data PDU size */
#if (RADIO_L2CAP_MTU_MAX < (RADIO_LL_LENGTH_OCTETS_RX_MAX - 4))
#if (RADIO_L2CAP_MTU_MAX < (LL_LENGTH_OCTETS_RX_MAX - 4))
#undef RADIO_L2CAP_MTU_MAX
#define RADIO_L2CAP_MTU_MAX (RADIO_LL_LENGTH_OCTETS_RX_MAX - 4)
#define RADIO_L2CAP_MTU_MAX (LL_LENGTH_OCTETS_RX_MAX - 4)
#endif
/* Maximum LL PDU Receive pool size. */
#ifndef RADIO_PACKET_COUNT_RX_MAX
#define RADIO_PACKET_COUNT_RX ((RADIO_L2CAP_MTU_MAX + \
RADIO_LL_LENGTH_OCTETS_RX_MAX \
+ 3) \
/ \
RADIO_LL_LENGTH_OCTETS_RX_MAX \
)
LL_LENGTH_OCTETS_RX_MAX + 3) / \
LL_LENGTH_OCTETS_RX_MAX)
#define RADIO_PACKET_COUNT_RX_MAX (RADIO_PACKET_COUNT_RX + \
((RADIO_CONNECTION_CONTEXT_MAX - 1) * \
(RADIO_PACKET_COUNT_RX - 1)) \
)
(RADIO_PACKET_COUNT_RX - 1)))
#endif /* RADIO_PACKET_COUNT_RX_MAX */
/* Maximum LL PDU Transmit pool size and application tx count. */
#ifndef RADIO_PACKET_COUNT_TX_MAX
#define RADIO_PACKET_COUNT_APP_TX_MAX (RADIO_CONNECTION_CONTEXT_MAX)
#define RADIO_PACKET_COUNT_APP_TX_MAX RADIO_CONNECTION_CONTEXT_MAX
#define RADIO_PACKET_COUNT_TX_MAX (RADIO_PACKET_COUNT_RX_MAX + \
RADIO_PACKET_COUNT_APP_TX_MAX \
)
RADIO_PACKET_COUNT_APP_TX_MAX)
#else
#define RADIO_PACKET_COUNT_APP_TX_MAX (RADIO_PACKET_COUNT_TX_MAX)
#endif
@ -233,48 +125,6 @@ struct radio_pdu_node_tx {
u8_t pdu_data[1];
};
enum radio_pdu_node_rx_type {
NODE_RX_TYPE_NONE,
NODE_RX_TYPE_DC_PDU,
NODE_RX_TYPE_REPORT,
#if defined(CONFIG_BT_CTLR_ADV_EXT)
NODE_RX_TYPE_EXT_1M_REPORT,
NODE_RX_TYPE_EXT_CODED_REPORT,
#endif /* CONFIG_BT_CTLR_ADV_EXT */
#if defined(CONFIG_BT_CTLR_SCAN_REQ_NOTIFY)
NODE_RX_TYPE_SCAN_REQ,
#endif /* CONFIG_BT_CTLR_SCAN_REQ_NOTIFY */
NODE_RX_TYPE_CONNECTION,
NODE_RX_TYPE_TERMINATE,
NODE_RX_TYPE_CONN_UPDATE,
NODE_RX_TYPE_ENC_REFRESH,
#if defined(CONFIG_BT_CTLR_LE_PING)
NODE_RX_TYPE_APTO,
#endif /* CONFIG_BT_CTLR_LE_PING */
NODE_RX_TYPE_CHAN_SEL_ALGO,
#if defined(CONFIG_BT_CTLR_PHY)
NODE_RX_TYPE_PHY_UPDATE,
#endif /* CONFIG_BT_CTLR_PHY */
#if defined(CONFIG_BT_CTLR_CONN_RSSI)
NODE_RX_TYPE_RSSI,
#endif /* CONFIG_BT_CTLR_CONN_RSSI */
#if defined(CONFIG_BT_CTLR_PROFILE_ISR)
NODE_RX_TYPE_PROFILE,
#endif /* CONFIG_BT_CTLR_PROFILE_ISR */
#if defined(CONFIG_BT_CTLR_ADV_INDICATION)
NODE_RX_TYPE_ADV_INDICATION,
#endif /* CONFIG_BT_CTLR_ADV_INDICATION */
};
struct radio_le_conn_cmplt {
u8_t status;
u8_t role;
@ -289,24 +139,24 @@ struct radio_le_conn_cmplt {
u16_t latency;
u16_t timeout;
u8_t mca;
} __packed;
};
struct radio_le_conn_update_cmplt {
u8_t status;
u16_t interval;
u16_t latency;
u16_t timeout;
} __packed;
};
struct radio_le_chan_sel_algo {
u8_t chan_sel_algo;
} __packed;
};
struct radio_le_phy_upd_cmplt {
u8_t status;
u8_t tx;
u8_t rx;
} __packed;
};
struct radio_pdu_node_rx_hdr {
union {
@ -314,9 +164,9 @@ struct radio_pdu_node_rx_hdr {
void *next; /* used also by k_fifo once pulled */
void *link;
u8_t packet_release_last;
} onion;
};
enum radio_pdu_node_rx_type type;
enum node_rx_type type;
u16_t handle;
};
@ -349,15 +199,15 @@ u32_t radio_adv_enable(u16_t interval, u8_t chan_map, u8_t filter_policy,
u8_t rl_idx);
#endif /* !CONFIG_BT_CTLR_ADV_EXT */
u32_t radio_adv_disable(void);
u32_t ll_adv_is_enabled(void);
u8_t radio_adv_disable(void);
u32_t ll_adv_is_enabled(u16_t handle);
u32_t radio_adv_filter_pol_get(void);
/* Downstream - Scanner */
u32_t radio_scan_enable(u8_t type, u8_t init_addr_type, u8_t *init_addr,
u16_t interval, u16_t window, u8_t filter_policy,
u8_t rpa_gen, u8_t rl_idx);
u32_t radio_scan_disable(bool scanner);
u32_t ll_scan_is_enabled(void);
u8_t radio_scan_disable(bool scanner);
u32_t ll_scan_is_enabled(u16_t handle);
u32_t radio_scan_filter_pol_get(void);
u32_t radio_connect_enable(u8_t adv_addr_type, u8_t *adv_addr,

View file

@ -296,18 +296,6 @@ struct pdu_data_q_tx {
struct radio_pdu_node_tx *node_tx;
};
/* Extra bytes for enqueued rx_node metadata: rssi (always) and resolving
* index and directed adv report (with privacy or extended scanner filter
* policies enabled).
* Note: to simplify the code, both bytes are allocated even if only one of
* the options is selected.
*/
#if defined(CONFIG_BT_CTLR_PRIVACY) || defined(CONFIG_BT_CTLR_EXT_SCAN_FP)
#define PDU_AC_SIZE_EXTRA 3
#else
#define PDU_AC_SIZE_EXTRA 1
#endif /* CONFIG_BT_CTLR_PRIVACY */
/* Minimum Rx Data allocation size */
#define PACKET_RX_DATA_SIZE_MIN \
MROUND(offsetof(struct radio_pdu_node_rx, pdu_data) + \
@ -333,7 +321,7 @@ struct pdu_data_q_tx {
pdu_data) + \
max((PDU_AC_SIZE_MAX + PDU_AC_SIZE_EXTRA), \
(offsetof(struct pdu_data, lldata) + \
RADIO_LL_LENGTH_OCTETS_RX_MAX))) * \
LL_LENGTH_OCTETS_RX_MAX))) * \
(RADIO_PACKET_COUNT_RX_MAX + 3))
#define LL_MEM_RX_LINK_POOL (sizeof(void *) * 2 * ((RADIO_PACKET_COUNT_RX_MAX +\

View file

@ -35,9 +35,11 @@
#include "ticker/ticker.h"
#include "pdu.h"
#include "lll.h"
#include "ctrl.h"
#include "ctrl_internal.h"
#include "ll.h"
#include "ll_feat.h"
#include "ll_filter.h"
/* Global singletons */
@ -81,40 +83,39 @@ void radio_event_callback(void)
ISR_DIRECT_DECLARE(radio_nrf5_isr)
{
DEBUG_RADIO_ISR(1);
isr_radio();
ISR_DIRECT_PM();
DEBUG_RADIO_ISR(0);
return 1;
}
static void rtc0_nrf5_isr(void *arg)
{
u32_t compare0, compare1;
/* store interested events */
compare0 = NRF_RTC0->EVENTS_COMPARE[0];
compare1 = NRF_RTC0->EVENTS_COMPARE[1];
DEBUG_TICKER_ISR(1);
/* On compare0 run ticker worker instance0 */
if (compare0) {
if (NRF_RTC0->EVENTS_COMPARE[0]) {
NRF_RTC0->EVENTS_COMPARE[0] = 0;
ticker_trigger(0);
}
/* On compare1 run ticker worker instance1 */
if (compare1) {
NRF_RTC0->EVENTS_COMPARE[1] = 0;
ticker_trigger(1);
}
mayfly_run(MAYFLY_CALL_ID_0);
DEBUG_TICKER_ISR(0);
}
static void swi4_nrf5_isr(void *arg)
static void swi5_nrf5_isr(void *arg)
{
DEBUG_TICKER_JOB(1);
mayfly_run(MAYFLY_CALL_ID_1);
DEBUG_TICKER_JOB(0);
}
int ll_init(struct k_sem *sem_rx)
@ -166,7 +167,7 @@ int ll_init(struct k_sem *sem_rx)
RADIO_CONNECTION_CONTEXT_MAX,
RADIO_PACKET_COUNT_RX_MAX,
RADIO_PACKET_COUNT_TX_MAX,
RADIO_LL_LENGTH_OCTETS_RX_MAX,
LL_LENGTH_OCTETS_RX_MAX,
RADIO_PACKET_TX_DATA_SIZE, &_radio[0], sizeof(_radio));
if (err) {
BT_ERR("Required RAM size: %d, supplied: %u.", err,
@ -180,12 +181,12 @@ int ll_init(struct k_sem *sem_rx)
radio_nrf5_isr, 0);
IRQ_CONNECT(NRF5_IRQ_RTC0_IRQn, CONFIG_BT_CTLR_WORKER_PRIO,
rtc0_nrf5_isr, NULL, 0);
IRQ_CONNECT(NRF5_IRQ_SWI4_IRQn, CONFIG_BT_CTLR_JOB_PRIO, swi4_nrf5_isr,
IRQ_CONNECT(NRF5_IRQ_SWI5_IRQn, CONFIG_BT_CTLR_JOB_PRIO, swi5_nrf5_isr,
NULL, 0);
irq_enable(NRF5_IRQ_RADIO_IRQn);
irq_enable(NRF5_IRQ_RTC0_IRQn);
irq_enable(NRF5_IRQ_SWI4_IRQn);
irq_enable(NRF5_IRQ_SWI5_IRQn);
return 0;
}

View file

@ -10,12 +10,17 @@
#include <zephyr/types.h>
#include <bluetooth/hci.h>
#include <bluetooth/controller.h>
#include <misc/slist.h>
#include "util/util.h"
#include "util/memq.h"
#include "ll_sw/pdu.h"
#include "ll_sw/ctrl.h"
#include "pdu.h"
#include "lll.h"
#if defined(CONFIG_BT_LL_SW)
#include <misc/slist.h>
#include "ctrl.h"
#endif
static u8_t pub_addr[BDADDR_SIZE];
static u8_t rnd_addr[BDADDR_SIZE];
@ -43,8 +48,13 @@ u8_t *ll_addr_get(u8_t addr_type, u8_t *bdaddr)
u32_t ll_addr_set(u8_t addr_type, u8_t const *const bdaddr)
{
if (ll_adv_is_enabled() ||
(ll_scan_is_enabled() & (BIT(1) | BIT(2)))) {
if (IS_ENABLED(CONFIG_BT_BROADCASTER) &&
ll_adv_is_enabled(0)) {
return BT_HCI_ERR_CMD_DISALLOWED;
}
if (IS_ENABLED(CONFIG_BT_OBSERVER) &&
(ll_scan_is_enabled(0) & (BIT(1) | BIT(2)))) {
return BT_HCI_ERR_CMD_DISALLOWED;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016-2017 Nordic Semiconductor ASA
* Copyright (c) 2016-2018 Nordic Semiconductor ASA
* Copyright (c) 2016 Vinayak Kariappa Chettimada
*
* SPDX-License-Identifier: Apache-2.0
@ -11,8 +11,10 @@
#include <bluetooth/hci.h>
#include "util/util.h"
#include "util/memq.h"
#include "pdu.h"
#include "lll.h"
#include "ctrl.h"
#include "ll.h"
@ -29,7 +31,7 @@ struct ll_adv_set *ll_adv_set_get(void)
}
#if defined(CONFIG_BT_CTLR_ADV_EXT)
u32_t ll_adv_params_set(u8_t handle, u16_t evt_prop, u32_t interval,
u8_t ll_adv_params_set(u8_t handle, u16_t evt_prop, u32_t interval,
u8_t adv_type, u8_t own_addr_type,
u8_t direct_addr_type, u8_t const *const direct_addr,
u8_t chan_map, u8_t filter_policy, u8_t *tx_pwr,
@ -42,7 +44,7 @@ u32_t ll_adv_params_set(u8_t handle, u16_t evt_prop, u32_t interval,
PDU_ADV_TYPE_DIRECT_IND,
PDU_ADV_TYPE_EXT_IND};
#else /* !CONFIG_BT_CTLR_ADV_EXT */
u32_t ll_adv_params_set(u16_t interval, u8_t adv_type,
u8_t ll_adv_params_set(u16_t interval, u8_t adv_type,
u8_t own_addr_type, u8_t direct_addr_type,
u8_t const *const direct_addr, u8_t chan_map,
u8_t filter_policy)
@ -57,7 +59,7 @@ u32_t ll_adv_params_set(u16_t interval, u8_t adv_type,
struct radio_adv_data *radio_adv_data;
struct pdu_adv *pdu;
if (ll_adv_is_enabled()) {
if (ll_adv_is_enabled(0)) {
return BT_HCI_ERR_CMD_DISALLOWED;
}
@ -141,24 +143,31 @@ u32_t ll_adv_params_set(u16_t interval, u8_t adv_type,
#if defined(CONFIG_BT_CTLR_ADV_EXT)
} else if (pdu->type == PDU_ADV_TYPE_EXT_IND) {
struct pdu_adv_com_ext_adv *p;
struct ext_adv_hdr *h;
u8_t *ptr;
struct ext_adv_hdr _h, *h;
u8_t *_ptr, *ptr;
u8_t len;
p = (void *)&pdu->adv_ext_ind;
h = (void *)p->ext_hdr_adi_adv_data;
ptr = (u8_t *)h + sizeof(*h);
_ptr = ptr;
/* No ACAD and no AdvData */
p->ext_hdr_len = 0;
p->adv_mode = evt_prop & 0x03;
/* Zero-init header flags */
*(u8_t *)&_h = *(u8_t *)h;
*(u8_t *)h = 0;
/* AdvA flag */
if (!(evt_prop & BIT(5)) && !p->adv_mode && (phy_p != BIT(2))) {
/* TODO: optional on 1M */
if (_h.adv_addr) {
_ptr += BDADDR_SIZE;
}
if (!p->adv_mode &&
(!_h.aux_ptr ||
(!(evt_prop & BIT(5)) && (phy_p != BIT(2))))) {
/* TODO: optional on 1M with Aux Ptr */
h->adv_addr = 1;
/* NOTE: AdvA is filled at enable */
@ -167,14 +176,23 @@ u32_t ll_adv_params_set(u16_t interval, u8_t adv_type,
/* TODO: TargetA flag */
/* TODO: ADI flag */
/* ADI flag */
if (_h.adi) {
h->adi = 1;
ptr += sizeof(struct ext_adv_adi);
}
/* TODO: AuxPtr flag */
/* AuxPtr flag */
if (_h.aux_ptr) {
h->aux_ptr = 1;
ptr += sizeof(struct ext_adv_aux_ptr);
}
/* TODO: SyncInfo flag */
/* No SyncInfo flag in primary channel PDU */
/* Tx Power flag */
if (evt_prop & BIT(6)) {
if (evt_prop & BIT(6) &&
(!_h.aux_ptr || (phy_p != BIT(2)))) {
h->tx_pwr = 1;
ptr++;
}
@ -194,9 +212,9 @@ u32_t ll_adv_params_set(u16_t interval, u8_t adv_type,
/* Start filling primary PDU payload based on flags */
/* TODO: AdvData */
/* No AdvData in primary channel PDU */
/* TODO: ACAD */
/* No ACAD in primary channel PDU */
/* Tx Power */
if (h->tx_pwr) {
@ -215,11 +233,32 @@ u32_t ll_adv_params_set(u16_t interval, u8_t adv_type,
*ptr = _tx_pwr;
}
/* TODO: SyncInfo */
/* No SyncInfo in primary channel PDU */
/* TODO: AuxPtr */
/* AuxPtr */
if (h->aux_ptr) {
struct ext_adv_aux_ptr *aux;
/* TODO: ADI */
ptr -= sizeof(struct ext_adv_aux_ptr);
/* NOTE: Channel Index, CA, Offset Units and AUX Offset
* will be set in Advertiser Event.
*/
aux = (void *)ptr;
aux->phy = find_lsb_set(phy_s);
}
/* ADI */
if (h->adi) {
struct ext_adv_adi *adi;
ptr -= sizeof(struct ext_adv_adi);
/* NOTE: memcpy shall handle overlapping buffers */
memcpy(ptr, _ptr, sizeof(struct ext_adv_adi));
adi = (void *)ptr;
adi->sid = sid;
}
/* NOTE: TargetA, filled at enable and RPA timeout */
@ -245,7 +284,11 @@ u32_t ll_adv_params_set(u16_t interval, u8_t adv_type,
return 0;
}
void ll_adv_data_set(u8_t len, u8_t const *const data)
#if defined(CONFIG_BT_CTLR_ADV_EXT)
u8_t ll_adv_data_set(u16_t handle, u8_t len, u8_t const *const data)
#else /* !CONFIG_BT_CTLR_ADV_EXT */
u8_t ll_adv_data_set(u8_t len, u8_t const *const data)
#endif /* !CONFIG_BT_CTLR_ADV_EXT */
{
struct radio_adv_data *radio_adv_data;
struct pdu_adv *prev;
@ -261,7 +304,7 @@ void ll_adv_data_set(u8_t len, u8_t const *const data)
/* TODO: remember data, to be used if type is changed using
* parameter set function ll_adv_params_set afterwards.
*/
return;
return 0;
}
/* use the last index in double buffer, */
@ -293,9 +336,15 @@ void ll_adv_data_set(u8_t len, u8_t const *const data)
/* commit the update so controller picks it. */
radio_adv_data->last = last;
return 0;
}
void ll_scan_data_set(u8_t len, u8_t const *const data)
#if defined(CONFIG_BT_CTLR_ADV_EXT)
u8_t ll_adv_scan_rsp_set(u16_t handle, u8_t len, u8_t const *const data)
#else /* !CONFIG_BT_CTLR_ADV_EXT */
u8_t ll_adv_scan_rsp_set(u8_t len, u8_t const *const data)
#endif /* !CONFIG_BT_CTLR_ADV_EXT */
{
struct radio_adv_data *radio_scan_data;
struct pdu_adv *prev;
@ -328,9 +377,15 @@ void ll_scan_data_set(u8_t len, u8_t const *const data)
/* commit the update so controller picks it. */
radio_scan_data->last = last;
return 0;
}
u32_t ll_adv_enable(u8_t enable)
#if defined(CONFIG_BT_CTLR_ADV_EXT)
u8_t ll_adv_enable(u16_t handle, u8_t enable)
#else /* !CONFIG_BT_CTLR_ADV_EXT */
u8_t ll_adv_enable(u8_t enable)
#endif /* !CONFIG_BT_CTLR_ADV_EXT */
{
struct radio_adv_data *radio_scan_data;
struct radio_adv_data *radio_adv_data;
@ -341,7 +396,7 @@ u32_t ll_adv_enable(u8_t enable)
if (!enable) {
return radio_adv_disable();
} else if (ll_adv_is_enabled()) {
} else if (ll_adv_is_enabled(0)) {
return 0;
}
@ -411,6 +466,7 @@ u32_t ll_adv_enable(u8_t enable)
BDADDR_SIZE);
}
}
#if defined(CONFIG_BT_CTLR_ADV_EXT)
status = radio_adv_enable(ll_adv.phy_p, ll_adv.interval,
ll_adv.chan_map, ll_adv.filter_policy,

View file

@ -0,0 +1,81 @@
/*
* Copyright (c) 2017 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <zephyr.h>
#include "util/util.h"
#include "util/memq.h"
#include "pdu.h"
#include "lll.h"
#include "ctrl.h"
u8_t ll_adv_aux_random_addr_set(u8_t handle, u8_t *addr)
{
/* TODO: store in adv set instance */
return 0;
}
u8_t *ll_adv_aux_random_addr_get(u8_t handle, u8_t *addr)
{
/* TODO: copy adv set instance addr into addr and/or return reference */
return NULL;
}
u8_t ll_adv_aux_ad_data_set(u8_t handle, u8_t op, u8_t frag_pref, u8_t len,
u8_t *data)
{
struct pdu_adv_com_ext_adv *p;
struct radio_adv_data *ad;
struct ext_adv_hdr *h;
struct pdu_adv *pdu;
/* TODO: */
ad = radio_adv_data_get();
pdu = (void *)ad->data[ad->last];
p = (void *)&pdu->adv_ext_ind;
h = (void *)p->ext_hdr_adi_adv_data;
if (!h->aux_ptr) {
}
return 0;
}
u8_t ll_adv_aux_sr_data_set(u8_t handle, u8_t op, u8_t frag_pref, u8_t len,
u8_t *data)
{
/* TODO: */
return 0;
}
u16_t ll_adv_aux_max_data_length_get(void)
{
/* TODO: return a Kconfig value */
return 0;
}
u8_t ll_adv_aux_set_count_get(void)
{
/* TODO: return a Kconfig value */
return 0;
}
u8_t ll_adv_aux_set_remove(u8_t handle)
{
/* TODO: reset/release primary channel and Aux channel PDUs */
return 0;
}
u8_t ll_adv_aux_set_clear(void)
{
/* TODO: reset/release all adv set primary channel and Aux channel
* PDUs
*/
return 0;
}

View file

@ -0,0 +1,16 @@
/*
* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
u8_t ll_adv_aux_random_addr_set(u8_t handle, u8_t *addr);
u8_t *ll_adv_aux_random_addr_get(u8_t handle, u8_t *addr);
u8_t ll_adv_aux_ad_data_set(u8_t handle, u8_t op, u8_t frag_pref, u8_t len,
u8_t *data);
u8_t ll_adv_aux_sr_data_set(u8_t handle, u8_t op, u8_t frag_pref, u8_t len,
u8_t *data);
u16_t ll_adv_aux_max_data_length_get(void);
u8_t ll_adv_aux_set_count_get(void);
u8_t ll_adv_aux_set_remove(u8_t handle);
u8_t ll_adv_aux_set_clear(void);

View file

@ -12,8 +12,10 @@
#include "util/util.h"
#include "util/mem.h"
#include "util/memq.h"
#include "pdu.h"
#include "lll.h"
#include "ctrl.h"
#include "ll.h"
#include "ll_adv.h"
@ -288,12 +290,12 @@ struct ll_filter *ctrl_filter_get(bool whitelist)
#endif
}
u32_t ll_wl_size_get(void)
u8_t ll_wl_size_get(void)
{
return WL_SIZE;
}
u32_t ll_wl_clear(void)
u8_t ll_wl_clear(void)
{
if (radio_adv_filter_pol_get() || (radio_scan_filter_pol_get() & 0x1)) {
return BT_HCI_ERR_CMD_DISALLOWED;
@ -309,7 +311,7 @@ u32_t ll_wl_clear(void)
return 0;
}
u32_t ll_wl_add(bt_addr_le_t *addr)
u8_t ll_wl_add(bt_addr_le_t *addr)
{
if (radio_adv_filter_pol_get() || (radio_scan_filter_pol_get() & 0x1)) {
return BT_HCI_ERR_CMD_DISALLOWED;
@ -327,7 +329,7 @@ u32_t ll_wl_add(bt_addr_le_t *addr)
#endif /* CONFIG_BT_CTLR_PRIVACY */
}
u32_t ll_wl_remove(bt_addr_le_t *addr)
u8_t ll_wl_remove(bt_addr_le_t *addr)
{
if (radio_adv_filter_pol_get() || (radio_scan_filter_pol_get() & 0x1)) {
return BT_HCI_ERR_CMD_DISALLOWED;
@ -396,7 +398,7 @@ void ll_filters_adv_update(u8_t adv_fp)
/* Clear before populating rl filter */
filter_clear(&rl_filter);
if (rl_enable && !ll_scan_is_enabled()) {
if (rl_enable && !ll_scan_is_enabled(0)) {
/* rl not in use, update resolving list LUT */
filter_rl_update();
}
@ -416,7 +418,7 @@ void ll_filters_scan_update(u8_t scan_fp)
/* Clear before populating rl filter */
filter_clear(&rl_filter);
if (rl_enable && !ll_adv_is_enabled()) {
if (rl_enable && !ll_adv_is_enabled(0)) {
/* rl not in use, update resolving list LUT */
filter_rl_update();
}
@ -618,7 +620,7 @@ static int rl_access_check(bool check_ar)
}
}
return (ll_adv_is_enabled() || ll_scan_is_enabled()) ? 0 : 1;
return (ll_adv_is_enabled(0) || ll_scan_is_enabled(0)) ? 0 : 1;
}
void ll_rl_rpa_update(bool timeout)
@ -667,7 +669,7 @@ void ll_rl_rpa_update(bool timeout)
if (timeout) {
#if defined(CONFIG_BT_BROADCASTER)
if (ll_adv_is_enabled()) {
if (ll_adv_is_enabled(0)) {
rpa_adv_refresh();
}
#endif
@ -708,12 +710,12 @@ void ll_adv_scan_state_cb(u8_t bm)
}
}
u32_t ll_rl_size_get(void)
u8_t ll_rl_size_get(void)
{
return CONFIG_BT_CTLR_RL_SIZE;
}
u32_t ll_rl_clear(void)
u8_t ll_rl_clear(void)
{
if (!rl_access_check(false)) {
return BT_HCI_ERR_CMD_DISALLOWED;
@ -724,7 +726,7 @@ u32_t ll_rl_clear(void)
return 0;
}
u32_t ll_rl_add(bt_addr_le_t *id_addr, const u8_t pirk[16],
u8_t ll_rl_add(bt_addr_le_t *id_addr, const u8_t pirk[16],
const u8_t lirk[16])
{
u8_t i, j;
@ -777,7 +779,7 @@ u32_t ll_rl_add(bt_addr_le_t *id_addr, const u8_t pirk[16],
return 0;
}
u32_t ll_rl_remove(bt_addr_le_t *id_addr)
u8_t ll_rl_remove(bt_addr_le_t *id_addr)
{
u8_t i;
@ -839,7 +841,7 @@ void ll_rl_crpa_set(u8_t id_addr_type, u8_t *id_addr, u8_t rl_idx, u8_t *crpa)
}
}
u32_t ll_rl_crpa_get(bt_addr_le_t *id_addr, bt_addr_t *crpa)
u8_t ll_rl_crpa_get(bt_addr_le_t *id_addr, bt_addr_t *crpa)
{
u8_t i;
@ -854,7 +856,7 @@ u32_t ll_rl_crpa_get(bt_addr_le_t *id_addr, bt_addr_t *crpa)
return BT_HCI_ERR_UNKNOWN_CONN_ID;
}
u32_t ll_rl_lrpa_get(bt_addr_le_t *id_addr, bt_addr_t *lrpa)
u8_t ll_rl_lrpa_get(bt_addr_le_t *id_addr, bt_addr_t *lrpa)
{
u8_t i;
@ -868,7 +870,7 @@ u32_t ll_rl_lrpa_get(bt_addr_le_t *id_addr, bt_addr_t *lrpa)
return BT_HCI_ERR_UNKNOWN_CONN_ID;
}
u32_t ll_rl_enable(u8_t enable)
u8_t ll_rl_enable(u8_t enable)
{
if (!rl_access_check(false)) {
return BT_HCI_ERR_CMD_DISALLOWED;
@ -893,7 +895,7 @@ void ll_rl_timeout_set(u16_t timeout)
rpa_timeout_ms = timeout * 1000;
}
u32_t ll_priv_mode_set(bt_addr_le_t *id_addr, u8_t mode)
u8_t ll_priv_mode_set(bt_addr_le_t *id_addr, u8_t mode)
{
u8_t i;

View file

@ -9,13 +9,15 @@
#include <bluetooth/hci.h>
#include "util/util.h"
#include "util/memq.h"
#include "pdu.h"
#include "lll.h"
#include "ctrl.h"
#include "ll.h"
#include "ll_filter.h"
u32_t ll_create_connection(u16_t scan_interval, u16_t scan_window,
u8_t ll_create_connection(u16_t scan_interval, u16_t scan_window,
u8_t filter_policy, u8_t peer_addr_type,
u8_t *peer_addr, u8_t own_addr_type,
u16_t interval, u16_t latency,
@ -25,7 +27,7 @@ u32_t ll_create_connection(u16_t scan_interval, u16_t scan_window,
u8_t rpa_gen = 0U;
u8_t rl_idx = FILTER_IDX_NONE;
if (ll_scan_is_enabled()) {
if (ll_scan_is_enabled(0)) {
return BT_HCI_ERR_CMD_DISALLOWED;
}

View file

@ -9,8 +9,10 @@
#include <bluetooth/hci.h>
#include "util/util.h"
#include "util/memq.h"
#include "pdu.h"
#include "lll.h"
#include "ctrl.h"
#include "ll.h"
#include "ll_filter.h"
@ -29,10 +31,10 @@ static struct {
u8_t filter_policy:2;
} ll_scan;
u32_t ll_scan_params_set(u8_t type, u16_t interval, u16_t window,
u8_t ll_scan_params_set(u8_t type, u16_t interval, u16_t window,
u8_t own_addr_type, u8_t filter_policy)
{
if (ll_scan_is_enabled()) {
if (ll_scan_is_enabled(0)) {
return BT_HCI_ERR_CMD_DISALLOWED;
}
@ -57,7 +59,7 @@ u32_t ll_scan_params_set(u8_t type, u16_t interval, u16_t window,
return 0;
}
u32_t ll_scan_enable(u8_t enable)
u8_t ll_scan_enable(u8_t enable)
{
u8_t rpa_gen = 0U;
u32_t status;
@ -67,7 +69,7 @@ u32_t ll_scan_enable(u8_t enable)
return radio_scan_disable(true);
}
scan = ll_scan_is_enabled();
scan = ll_scan_is_enabled(0);
/* Initiator and scanning are not supported */
if (scan & BIT(2)) {

View file

@ -17,10 +17,13 @@
#include "hal/ccm.h"
#include "hal/radio.h"
#if defined(CONFIG_BT_LL_SW)
#include "util/util.h"
#include "ll_sw/pdu.h"
#include "ll_sw/ctrl.h"
#include "util/memq.h"
#include "pdu.h"
#include "lll.h"
#include "ctrl.h"
#endif
#include "ll_test.h"
#define CNTR_MIN_DELTA 3
@ -77,7 +80,7 @@ static const u8_t prbs15[255] = { 0x00, };
static u8_t tx_req;
static u8_t volatile tx_ack;
static void isr_tx(void)
static void isr_tx(void *param)
{
u32_t l, i, s, t;
@ -125,7 +128,7 @@ static void isr_tx(void)
#endif /* CONFIG_BT_CTLR_GPIO_PA_PIN */
}
static void isr_rx(void)
static void isr_rx(void *param)
{
u8_t crc_ok = 0U;
u8_t trx_done;
@ -154,7 +157,7 @@ static void isr_rx(void)
}
}
static u32_t init(u8_t chan, u8_t phy, void (*isr)(void))
static u32_t init(u8_t chan, u8_t phy, void (*isr)(void *param))
{
struct device *hf_clock;
@ -171,7 +174,7 @@ static u32_t init(u8_t chan, u8_t phy, void (*isr)(void))
/* Reset Radio h/w */
radio_reset();
radio_isr_set(isr);
radio_isr_set(isr, NULL);
/* Store value needed in Tx/Rx ISR */
if (phy < 0x04) {

View file

@ -11,7 +11,7 @@
* controller implementation. */
#include <toolchain.h>
u32_t __weak ll_tx_pwr_lvl_get(u16_t handle, u8_t type, s8_t *tx_pwr_lvl)
u8_t __weak ll_tx_pwr_lvl_get(u16_t handle, u8_t type, s8_t *tx_pwr_lvl)
{
/* TODO: check for active connection */

View file

@ -0,0 +1,269 @@
/*
* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#define TICKER_INSTANCE_ID_CTLR 0
#define TICKER_USER_ID_LLL MAYFLY_CALL_ID_0
#define TICKER_USER_ID_ULL_HIGH MAYFLY_CALL_ID_1
#define TICKER_USER_ID_ULL_LOW MAYFLY_CALL_ID_2
#define TICKER_USER_ID_THREAD MAYFLY_CALL_ID_PROGRAM
#define EVENT_PIPELINE_MAX 5
#define HDR_ULL(p) ((void *)((u8_t *)(p) + sizeof(struct evt_hdr)))
#define HDR_ULL2LLL(p) ((struct lll_hdr *)((u8_t *)(p) + \
sizeof(struct ull_hdr)))
#define HDR_LLL2EVT(p) ((struct evt_hdr *)((struct lll_hdr *)(p))->parent)
#if defined(CONFIG_BT_CTLR_XTAL_ADVANCED)
#define XON_BITMASK BIT(31) /* XTAL has been retained from previous prepare */
#endif /* CONFIG_BT_CTLR_XTAL_ADVANCED */
#if defined(CONFIG_BT_BROADCASTER) && defined(CONFIG_BT_ADV_SET)
#define CONFIG_BT_ADV_MAX (CONFIG_BT_ADV_SET + 1)
#else
#define CONFIG_BT_ADV_MAX 1
#endif
enum {
TICKER_ID_LLL_PREEMPT = 0,
#if defined(CONFIG_BT_TMP)
TICKER_ID_TMP_BASE,
TICKER_ID_TMP_LAST = ((TICKER_ID_TMP_BASE) + (CONFIG_BT_TMP_MAX) - 1),
#endif /* CONFIG_BT_TMP */
#if defined(CONFIG_BT_BROADCASTER)
TICKER_ID_ADV_STOP,
TICKER_ID_ADV_BASE,
#if defined(CONFIG_BT_CTLR_ADV_EXT)
TICKER_ID_ADV_LAST = ((TICKER_ID_ADV_BASE) + (CONFIG_BT_ADV_MAX) - 1),
#endif /* !CONFIG_BT_CTLR_ADV_EXT */
#endif /* CONFIG_BT_BROADCASTER */
#if defined(CONFIG_BT_OBSERVER)
TICKER_ID_SCAN_STOP,
TICKER_ID_SCAN_BASE,
TICKER_ID_SCAN_LAST = TICKER_ID_SCAN_BASE,
#endif /* CONFIG_BT_OBSERVER */
#if defined(CONFIG_BT_CONN)
TICKER_ID_CONN_BASE,
TICKER_ID_CONN_LAST = ((TICKER_ID_CONN_BASE) + (CONFIG_BT_MAX_CONN) -
1),
#endif /* CONFIG_BT_CONN */
TICKER_ID_MAX,
};
#if defined(CONFIG_BT_BROADCASTER) && !defined(CONFIG_BT_CTLR_ADV_EXT)
#define TICKER_ID_ADV_LAST TICKER_ID_ADV_BASE
#endif
#define TICKER_ID_ULL_BASE ((TICKER_ID_LLL_PREEMPT) + 1)
enum ull_status {
ULL_STATUS_SUCCESS,
ULL_STATUS_FAILURE,
ULL_STATUS_BUSY,
};
struct evt_hdr {
u32_t ticks_xtal_to_start;
u32_t ticks_active_to_start;
u32_t ticks_preempt_to_start;
u32_t ticks_slot;
};
struct ull_hdr {
u8_t ref;
void (*disabled_cb)(void *param);
void *disabled_param;
};
struct lll_hdr {
void *parent;
u8_t is_stop:1;
};
struct lll_prepare_param {
u32_t ticks_at_expire;
u32_t remainder;
u16_t lazy;
void *param;
};
typedef int (*lll_prepare_cb_t)(struct lll_prepare_param *prepare_param);
typedef int (*lll_is_abort_cb_t)(void *next, int prio, void *curr,
lll_prepare_cb_t *resume_cb, int *resume_prio);
typedef void (*lll_abort_cb_t)(struct lll_prepare_param *prepare_param,
void *param);
struct lll_event {
struct lll_prepare_param prepare_param;
lll_prepare_cb_t prepare_cb;
lll_is_abort_cb_t is_abort_cb;
lll_abort_cb_t abort_cb;
int prio;
u8_t is_resume:1;
u8_t is_aborted:1;
};
enum node_rx_type {
NODE_RX_TYPE_NONE = 0x00,
NODE_RX_TYPE_EVENT_DONE = 0x01,
NODE_RX_TYPE_DC_PDU = 0x02,
NODE_RX_TYPE_DC_PDU_RELEASE = 0x03,
#if defined(CONFIG_BT_OBSERVER)
NODE_RX_TYPE_REPORT = 0x04,
#endif /* CONFIG_BT_OBSERVER */
#if defined(CONFIG_BT_CTLR_ADV_EXT)
NODE_RX_TYPE_EXT_1M_REPORT = 0x05,
NODE_RX_TYPE_EXT_CODED_REPORT = 0x06,
#endif /* CONFIG_BT_CTLR_ADV_EXT */
#if defined(CONFIG_BT_CTLR_SCAN_REQ_NOTIFY)
NODE_RX_TYPE_SCAN_REQ = 0x07,
#endif /* CONFIG_BT_CTLR_SCAN_REQ_NOTIFY */
#if defined(CONFIG_BT_CONN)
NODE_RX_TYPE_CONNECTION = 0x08,
NODE_RX_TYPE_TERMINATE = 0x09,
NODE_RX_TYPE_CONN_UPDATE = 0x0A,
NODE_RX_TYPE_ENC_REFRESH = 0x0B,
#if defined(CONFIG_BT_CTLR_LE_PING)
NODE_RX_TYPE_APTO = 0x0C,
#endif /* CONFIG_BT_CTLR_LE_PING */
NODE_RX_TYPE_CHAN_SEL_ALGO = 0x0D,
#if defined(CONFIG_BT_CTLR_PHY)
NODE_RX_TYPE_PHY_UPDATE = 0x0E,
#endif /* CONFIG_BT_CTLR_PHY */
#if defined(CONFIG_BT_CTLR_CONN_RSSI)
NODE_RX_TYPE_RSSI = 0x0F,
#endif /* CONFIG_BT_CTLR_CONN_RSSI */
#endif /* CONFIG_BT_CONN */
#if defined(CONFIG_BT_CTLR_PROFILE_ISR)
NODE_RX_TYPE_PROFILE = 0x10,
#endif /* CONFIG_BT_CTLR_PROFILE_ISR */
#if defined(CONFIG_BT_CTLR_ADV_INDICATION)
NODE_RX_TYPE_ADV_INDICATION = 0x11,
#endif /* CONFIG_BT_CTLR_ADV_INDICATION */
#if defined(CONFIG_BT_CTLR_SCAN_INDICATION)
NODE_RX_TYPE_SCAN_INDICATION = 0x12,
#endif /* CONFIG_BT_CTLR_SCAN_INDICATION */
};
struct node_rx_hdr {
union {
void *next;
memq_link_t *link;
u8_t ack_last;
};
enum node_rx_type type;
u16_t handle;
};
struct node_rx_ftr {
void *param;
void *extra;
u32_t ticks_anchor;
u32_t us_radio_end;
u32_t us_radio_rdy;
};
struct node_rx_pdu {
struct node_rx_hdr hdr;
u8_t pdu[0];
};
enum {
EVENT_DONE_EXTRA_TYPE_NONE,
EVENT_DONE_EXTRA_TYPE_CONN,
};
struct event_done_extra_slave {
u32_t start_to_address_actual_us;
u32_t window_widening_event_us;
u32_t preamble_to_addr_us;
};
struct event_done_extra {
u8_t type;
union {
struct {
u16_t trx_cnt;
u8_t crc_valid;
#if defined(CONFIG_BT_CTLR_LE_ENC)
u8_t mic_state;
#endif /* CONFIG_BT_CTLR_LE_ENC */
union {
struct event_done_extra_slave slave;
};
};
};
};
struct node_rx_event_done {
struct node_rx_hdr hdr;
void *param;
struct event_done_extra extra;
};
static inline void lll_hdr_init(void *lll, void *parent)
{
struct lll_hdr *hdr = lll;
hdr->parent = parent;
hdr->is_stop = 0;
}
static inline int lll_stop(void *lll)
{
struct lll_hdr *hdr = lll;
int ret = !!hdr->is_stop;
hdr->is_stop = 1;
return ret;
}
static inline int lll_is_stop(void *lll)
{
struct lll_hdr *hdr = lll;
return !!hdr->is_stop;
}
int lll_init(void);
int lll_prepare(lll_is_abort_cb_t is_abort_cb, lll_abort_cb_t abort_cb,
lll_prepare_cb_t prepare_cb, int prio,
struct lll_prepare_param *prepare_param);
void lll_resume(void *param);
void lll_disable(void *param);
int ull_prepare_enqueue(lll_is_abort_cb_t is_abort_cb,
lll_abort_cb_t abort_cb,
struct lll_prepare_param *prepare_param,
lll_prepare_cb_t prepare_cb, int prio,
u8_t is_resume);
void *ull_prepare_dequeue_get(void);
void *ull_prepare_dequeue_iter(u8_t *idx);
void *ull_pdu_rx_alloc_peek(u8_t count);
void *ull_pdu_rx_alloc_peek_iter(u8_t *idx);
void *ull_pdu_rx_alloc(void);
void ull_rx_put(memq_link_t *link, void *rx);
void ull_rx_sched(void);
void *ull_event_done_extra_get(void);
void *ull_event_done(void *param);

View file

@ -0,0 +1,14 @@
/*
* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
struct node_tx {
union {
void *next;
memq_link_t *link;
};
u8_t pdu[];
};

View file

@ -4,6 +4,4 @@
* SPDX-License-Identifier: Apache-2.0
*/
#if defined(CONFIG_SOC_COMPATIBLE_NRF)
#include "nrf5/radio/radio_nrf5_txp.h"
#endif
#include "hal/nrf5/debug.h"

View file

@ -24,10 +24,8 @@ static u8_t _refcount;
void cntr_init(void)
{
NRF_RTC->PRESCALER = 0;
nrf_rtc_event_enable(NRF_RTC, RTC_EVTENSET_COMPARE0_Msk |
RTC_EVTENSET_COMPARE1_Msk);
nrf_rtc_int_enable(NRF_RTC, RTC_INTENSET_COMPARE0_Msk |
RTC_INTENSET_COMPARE1_Msk);
nrf_rtc_event_enable(NRF_RTC, RTC_EVTENSET_COMPARE0_Msk);
nrf_rtc_int_enable(NRF_RTC, RTC_INTENSET_COMPARE0_Msk);
}
u32_t cntr_start(void)

View file

@ -0,0 +1,303 @@
/*
* Copyright (c) 2016-2017 Nordic Semiconductor ASA
* Copyright (c) 2016 Vinayak Kariappa Chettimada
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifdef CONFIG_BT_CTLR_DEBUG_PINS
#if defined(CONFIG_BOARD_NRF52840_PCA10056)
#define DEBUG_PORT NRF_P1
#define DEBUG_PIN0 BIT(1)
#define DEBUG_PIN1 BIT(2)
#define DEBUG_PIN2 BIT(3)
#define DEBUG_PIN3 BIT(4)
#define DEBUG_PIN4 BIT(5)
#define DEBUG_PIN5 BIT(6)
#define DEBUG_PIN6 BIT(7)
#define DEBUG_PIN7 BIT(8)
#define DEBUG_PIN8 BIT(10)
#define DEBUG_PIN9 BIT(11)
#elif defined(CONFIG_BOARD_NRF52_PCA10040) || \
defined(CONFIG_BOARD_NRF52810_PCA10040)
#define DEBUG_PORT NRF_GPIO
#define DEBUG_PIN0 BIT(11)
#define DEBUG_PIN1 BIT(12)
#define DEBUG_PIN2 BIT(13)
#define DEBUG_PIN3 BIT(14)
#define DEBUG_PIN4 BIT(15)
#define DEBUG_PIN5 BIT(16)
#define DEBUG_PIN6 BIT(17)
#define DEBUG_PIN7 BIT(18)
#define DEBUG_PIN8 BIT(19)
#define DEBUG_PIN9 BIT(20)
#elif defined(CONFIG_BOARD_NRF51_PCA10028)
#define DEBUG_PORT NRF_GPIO
#define DEBUG_PIN0 BIT(12)
#define DEBUG_PIN1 BIT(13)
#define DEBUG_PIN2 BIT(14)
#define DEBUG_PIN3 BIT(15)
#define DEBUG_PIN4 BIT(16)
#define DEBUG_PIN5 BIT(17)
#define DEBUG_PIN6 BIT(18)
#define DEBUG_PIN7 BIT(19)
#define DEBUG_PIN8 BIT(20)
#define DEBUG_PIN9 BIT(23)
#else
#error BT_CTLR_DEBUG_PINS not supported on this board.
#endif
#define DEBUG_PIN_MASK (DEBUG_PIN0 | DEBUG_PIN1 | DEBUG_PIN2 | DEBUG_PIN3 | \
DEBUG_PIN4 | DEBUG_PIN5 | DEBUG_PIN6 | DEBUG_PIN7 | \
DEBUG_PIN8 | DEBUG_PIN9)
#define DEBUG_CLOSE_MASK (DEBUG_PIN3 | DEBUG_PIN4 | DEBUG_PIN5 | DEBUG_PIN6)
/* below are some interesting macros referenced by controller
* which can be defined to SoC's GPIO toggle to observe/debug the
* controller's runtime behavior.
*/
#define DEBUG_INIT() \
do { \
DEBUG_PORT->DIRSET = DEBUG_PIN_MASK; \
DEBUG_PORT->OUTCLR = DEBUG_PIN_MASK; \
} while (0)
#define DEBUG_CPU_SLEEP(flag) \
do { \
if (flag) { \
DEBUG_PORT->OUTSET = DEBUG_PIN0; \
DEBUG_PORT->OUTCLR = DEBUG_PIN0; \
} else { \
DEBUG_PORT->OUTCLR = DEBUG_PIN0; \
DEBUG_PORT->OUTSET = DEBUG_PIN0; \
} \
} while (0)
#define DEBUG_TICKER_ISR(flag) \
do { \
if (flag) { \
DEBUG_PORT->OUTCLR = DEBUG_PIN1; \
DEBUG_PORT->OUTSET = DEBUG_PIN1; \
} else { \
DEBUG_PORT->OUTSET = DEBUG_PIN1; \
DEBUG_PORT->OUTCLR = DEBUG_PIN1; \
} \
} while (0)
#define DEBUG_TICKER_TASK(flag) \
do { \
if (flag) { \
DEBUG_PORT->OUTCLR = DEBUG_PIN1; \
DEBUG_PORT->OUTSET = DEBUG_PIN1; \
} else { \
DEBUG_PORT->OUTSET = DEBUG_PIN1; \
DEBUG_PORT->OUTCLR = DEBUG_PIN1; \
} \
} while (0)
#define DEBUG_TICKER_JOB(flag) \
do { \
if (flag) { \
DEBUG_PORT->OUTCLR = DEBUG_PIN2; \
DEBUG_PORT->OUTSET = DEBUG_PIN2; \
} else { \
DEBUG_PORT->OUTSET = DEBUG_PIN2; \
DEBUG_PORT->OUTCLR = DEBUG_PIN2; \
} \
} while (0)
#define DEBUG_RADIO_ISR(flag) \
do { \
if (flag) { \
DEBUG_PORT->OUTCLR = DEBUG_PIN7; \
DEBUG_PORT->OUTSET = DEBUG_PIN7; \
} else { \
DEBUG_PORT->OUTSET = DEBUG_PIN7; \
DEBUG_PORT->OUTCLR = DEBUG_PIN7; \
} \
} while (0)
#define DEBUG_RADIO_XTAL(flag) \
do { \
if (flag) { \
DEBUG_PORT->OUTCLR = DEBUG_PIN8; \
DEBUG_PORT->OUTSET = DEBUG_PIN8; \
} else { \
DEBUG_PORT->OUTSET = DEBUG_PIN8; \
DEBUG_PORT->OUTCLR = DEBUG_PIN8; \
} \
} while (0)
#define DEBUG_RADIO_ACTIVE(flag) \
do { \
if (flag) { \
DEBUG_PORT->OUTCLR = DEBUG_PIN9; \
DEBUG_PORT->OUTSET = DEBUG_PIN9; \
} else { \
DEBUG_PORT->OUTSET = DEBUG_PIN9; \
DEBUG_PORT->OUTCLR = DEBUG_PIN9; \
} \
} while (0)
#define DEBUG_RADIO_CLOSE(flag) \
do { \
if (flag) { \
DEBUG_PORT->OUTCLR = 0x00000000; \
DEBUG_PORT->OUTSET = 0x00000000; \
} else { \
DEBUG_PORT->OUTCLR = DEBUG_CLOSE_MASK; \
} \
} while (0)
#define DEBUG_RADIO_PREPARE_A(flag) \
do { \
if (flag) { \
DEBUG_PORT->OUTCLR = DEBUG_PIN3; \
DEBUG_PORT->OUTSET = DEBUG_PIN3; \
} else { \
DEBUG_PORT->OUTCLR = DEBUG_PIN3; \
DEBUG_PORT->OUTSET = DEBUG_PIN3; \
} \
} while (0)
#define DEBUG_RADIO_START_A(flag) \
do { \
if (flag) { \
DEBUG_PORT->OUTCLR = DEBUG_PIN3; \
DEBUG_PORT->OUTSET = DEBUG_PIN3; \
} else { \
DEBUG_PORT->OUTCLR = DEBUG_PIN3; \
DEBUG_PORT->OUTSET = DEBUG_PIN3; \
} \
} while (0)
#define DEBUG_RADIO_CLOSE_A(flag) \
do { \
if (flag) { \
DEBUG_PORT->OUTCLR = 0x00000000; \
DEBUG_PORT->OUTSET = 0x00000000; \
} else { \
DEBUG_PORT->OUTCLR = DEBUG_PIN3; \
} \
} while (0)
#define DEBUG_RADIO_PREPARE_S(flag) \
do { \
if (flag) { \
DEBUG_PORT->OUTCLR = DEBUG_PIN4; \
DEBUG_PORT->OUTSET = DEBUG_PIN4; \
} else { \
DEBUG_PORT->OUTCLR = DEBUG_PIN4; \
DEBUG_PORT->OUTSET = DEBUG_PIN4; \
} \
} while (0)
#define DEBUG_RADIO_START_S(flag) \
do { \
if (flag) { \
DEBUG_PORT->OUTCLR = DEBUG_PIN4; \
DEBUG_PORT->OUTSET = DEBUG_PIN4; \
} else { \
DEBUG_PORT->OUTCLR = DEBUG_PIN4; \
DEBUG_PORT->OUTSET = DEBUG_PIN4; \
} \
} while (0)
#define DEBUG_RADIO_CLOSE_S(flag) \
do { \
if (flag) { \
DEBUG_PORT->OUTCLR = 0x00000000; \
DEBUG_PORT->OUTSET = 0x00000000; \
} else { \
DEBUG_PORT->OUTCLR = DEBUG_PIN4; \
} \
} while (0)
#define DEBUG_RADIO_PREPARE_O(flag) \
do { \
if (flag) { \
DEBUG_PORT->OUTCLR = DEBUG_PIN5; \
DEBUG_PORT->OUTSET = DEBUG_PIN5; \
} else { \
DEBUG_PORT->OUTCLR = DEBUG_PIN5; \
DEBUG_PORT->OUTSET = DEBUG_PIN5; \
} \
} while (0)
#define DEBUG_RADIO_START_O(flag) \
do { \
if (flag) { \
DEBUG_PORT->OUTCLR = DEBUG_PIN5; \
DEBUG_PORT->OUTSET = DEBUG_PIN5; \
} else { \
DEBUG_PORT->OUTCLR = DEBUG_PIN5; \
DEBUG_PORT->OUTSET = DEBUG_PIN5; \
} \
} while (0)
#define DEBUG_RADIO_CLOSE_O(flag) \
do { \
if (flag) { \
DEBUG_PORT->OUTCLR = 0x00000000; \
DEBUG_PORT->OUTSET = 0x00000000; \
} else { \
DEBUG_PORT->OUTCLR = DEBUG_PIN5; \
} \
} while (0)
#define DEBUG_RADIO_PREPARE_M(flag) \
do { \
if (flag) { \
DEBUG_PORT->OUTCLR = DEBUG_PIN6; \
DEBUG_PORT->OUTSET = DEBUG_PIN6; \
} else { \
DEBUG_PORT->OUTCLR = DEBUG_PIN6; \
DEBUG_PORT->OUTSET = DEBUG_PIN6; \
} \
} while (0)
#define DEBUG_RADIO_START_M(flag) \
do { \
if (flag) { \
DEBUG_PORT->OUTCLR = DEBUG_PIN6; \
DEBUG_PORT->OUTSET = DEBUG_PIN6; \
} else { \
DEBUG_PORT->OUTCLR = DEBUG_PIN6; \
DEBUG_PORT->OUTSET = DEBUG_PIN6; \
} \
} while (0)
#define DEBUG_RADIO_CLOSE_M(flag) \
do { \
if (flag) { \
DEBUG_PORT->OUTCLR = 0x00000000; \
DEBUG_PORT->OUTSET = 0x00000000; \
} else { \
DEBUG_PORT->OUTCLR = DEBUG_PIN6; \
} \
} while (0)
#else
#define DEBUG_INIT()
#define DEBUG_CPU_SLEEP(flag)
#define DEBUG_TICKER_ISR(flag)
#define DEBUG_TICKER_TASK(flag)
#define DEBUG_TICKER_JOB(flag)
#define DEBUG_RADIO_ISR(flag)
#define DEBUG_RADIO_HCTO(flag)
#define DEBUG_RADIO_XTAL(flag)
#define DEBUG_RADIO_ACTIVE(flag)
#define DEBUG_RADIO_CLOSE(flag)
#define DEBUG_RADIO_PREPARE_A(flag)
#define DEBUG_RADIO_START_A(flag)
#define DEBUG_RADIO_CLOSE_A(flag)
#define DEBUG_RADIO_PREPARE_S(flag)
#define DEBUG_RADIO_START_S(flag)
#define DEBUG_RADIO_CLOSE_S(flag)
#define DEBUG_RADIO_PREPARE_O(flag)
#define DEBUG_RADIO_START_O(flag)
#define DEBUG_RADIO_CLOSE_O(flag)
#define DEBUG_RADIO_PREPARE_M(flag)
#define DEBUG_RADIO_START_M(flag)
#define DEBUG_RADIO_CLOSE_M(flag)
#endif /* CONFIG_BT_CTLR_DEBUG_PINS */

View file

@ -29,9 +29,9 @@ void mayfly_enable_cb(u8_t caller_id, u8_t callee_id, u8_t enable)
LL_ASSERT(callee_id == MAYFLY_CALL_ID_JOB);
if (enable) {
irq_enable(SWI4_IRQn);
irq_enable(SWI5_IRQn);
} else {
irq_disable(SWI4_IRQn);
irq_disable(SWI5_IRQn);
}
}
@ -44,7 +44,7 @@ u32_t mayfly_is_enabled(u8_t caller_id, u8_t callee_id)
return irq_is_enabled(RTC0_IRQn);
case MAYFLY_CALL_ID_JOB:
return irq_is_enabled(SWI4_IRQn);
return irq_is_enabled(SWI5_IRQn);
default:
LL_ASSERT(0);
@ -56,16 +56,16 @@ u32_t mayfly_is_enabled(u8_t caller_id, u8_t callee_id)
u32_t mayfly_prio_is_equal(u8_t caller_id, u8_t callee_id)
{
#if (RADIO_TICKER_USER_ID_WORKER_PRIO == RADIO_TICKER_USER_ID_JOB_PRIO)
return (caller_id == callee_id) ||
#if defined(CONFIG_BT_LL_SW)
#if (CONFIG_BT_CTLR_WORKER_PRIO == CONFIG_BT_CTLR_JOB_PRIO)
((caller_id == MAYFLY_CALL_ID_WORKER) &&
(callee_id == MAYFLY_CALL_ID_JOB)) ||
((caller_id == MAYFLY_CALL_ID_JOB) &&
(callee_id == MAYFLY_CALL_ID_WORKER));
#else
/* TODO: check Kconfig set priorities */
return caller_id == callee_id;
(callee_id == MAYFLY_CALL_ID_WORKER)) ||
#endif
#endif
0;
}
void mayfly_pend(u8_t caller_id, u8_t callee_id)
@ -78,7 +78,7 @@ void mayfly_pend(u8_t caller_id, u8_t callee_id)
break;
case MAYFLY_CALL_ID_JOB:
NVIC_SetPendingIRQ(SWI4_IRQn);
NVIC_SetPendingIRQ(SWI5_IRQn);
break;
default:

View file

@ -29,18 +29,22 @@
#error "Platform not defined."
#endif
static radio_isr_fp sfp_radio_isr;
static radio_isr_cb_t isr_cb;
static void *isr_cb_param;
void isr_radio(void)
{
if (sfp_radio_isr) {
sfp_radio_isr();
if (radio_has_disabled()) {
isr_cb(isr_cb_param);
}
}
void radio_isr_set(radio_isr_fp fp_radio_isr)
void radio_isr_set(radio_isr_cb_t cb, void *param)
{
sfp_radio_isr = fp_radio_isr; /* atomic assignment of 32-bit word */
irq_disable(RADIO_IRQn);
isr_cb_param = param;
isr_cb = cb;
nrf_radio_int_enable(0 |
/* RADIO_INTENSET_READY_Msk |
@ -768,6 +772,11 @@ u32_t radio_tmr_start_now(u8_t trx)
return start;
}
u32_t radio_tmr_start_get(void)
{
return nrf_rtc_cc_get(NRF_RTC0, 2);
}
void radio_tmr_stop(void)
{
nrf_timer_task_trigger(EVENT_TIMER, NRF_TIMER_TASK_STOP);

View file

@ -0,0 +1,99 @@
/*
* Copyright (c) 2016 Nordic Semiconductor ASA
* Copyright (c) 2016 Vinayak Kariappa Chettimada
*
* SPDX-License-Identifier: Apache-2.0
*/
typedef void (*radio_isr_cb_t) (void *param);
void isr_radio(void);
void radio_isr_set(radio_isr_cb_t cb, void *param);
void radio_setup(void);
void radio_reset(void);
void radio_phy_set(u8_t phy, u8_t flags);
void radio_tx_power_set(u32_t power);
void radio_tx_power_max_set(void);
void radio_freq_chan_set(u32_t chan);
void radio_whiten_iv_set(u32_t iv);
void radio_aa_set(u8_t *aa);
void radio_pkt_configure(u8_t bits_len, u8_t max_len, u8_t flags);
void radio_pkt_rx_set(void *rx_packet);
void radio_pkt_tx_set(void *tx_packet);
u32_t radio_tx_ready_delay_get(u8_t phy, u8_t flags);
u32_t radio_tx_chain_delay_get(u8_t phy, u8_t flags);
u32_t radio_rx_ready_delay_get(u8_t phy, u8_t flags);
u32_t radio_rx_chain_delay_get(u8_t phy, u8_t flags);
void radio_rx_enable(void);
void radio_tx_enable(void);
void radio_disable(void);
void radio_status_reset(void);
u32_t radio_is_ready(void);
u32_t radio_is_done(void);
u32_t radio_has_disabled(void);
u32_t radio_is_idle(void);
void radio_crc_configure(u32_t polynomial, u32_t iv);
u32_t radio_crc_is_valid(void);
void *radio_pkt_empty_get(void);
void *radio_pkt_scratch_get(void);
void radio_switch_complete_and_rx(u8_t phy_rx);
void radio_switch_complete_and_tx(u8_t phy_rx, u8_t flags_rx, u8_t phy_tx,
u8_t flags_tx);
void radio_switch_complete_and_disable(void);
void radio_rssi_measure(void);
u32_t radio_rssi_get(void);
void radio_rssi_status_reset(void);
u32_t radio_rssi_is_ready(void);
void radio_filter_configure(u8_t bitmask_enable, u8_t bitmask_addr_type,
u8_t *bdaddr);
void radio_filter_disable(void);
void radio_filter_status_reset(void);
u32_t radio_filter_has_match(void);
u32_t radio_filter_match_get(void);
void radio_bc_configure(u32_t n);
void radio_bc_status_reset(void);
u32_t radio_bc_has_match(void);
void radio_tmr_status_reset(void);
void radio_tmr_tifs_set(u32_t tifs);
u32_t radio_tmr_start(u8_t trx, u32_t ticks_start, u32_t remainder);
void radio_tmr_start_us(u8_t trx, u32_t us);
u32_t radio_tmr_start_now(u8_t trx);
u32_t radio_tmr_start_get(void);
void radio_tmr_stop(void);
void radio_tmr_hcto_configure(u32_t hcto);
void radio_tmr_aa_capture(void);
u32_t radio_tmr_aa_get(void);
void radio_tmr_aa_save(u32_t aa);
u32_t radio_tmr_aa_restore(void);
u32_t radio_tmr_ready_get(void);
void radio_tmr_end_capture(void);
u32_t radio_tmr_end_get(void);
u32_t radio_tmr_tifs_base_get(void);
void radio_tmr_sample(void);
u32_t radio_tmr_sample_get(void);
void radio_gpio_pa_setup(void);
void radio_gpio_lna_setup(void);
void radio_gpio_lna_on(void);
void radio_gpio_lna_off(void);
void radio_gpio_pa_lna_enable(u32_t trx_us);
void radio_gpio_pa_lna_disable(void);
void *radio_ccm_rx_pkt_set(struct ccm *ccm, u8_t phy, void *pkt);
void *radio_ccm_tx_pkt_set(struct ccm *ccm, void *pkt);
u32_t radio_ccm_is_done(void);
u32_t radio_ccm_mic_is_valid(void);
void radio_ar_configure(u32_t nirk, void *irk);
u32_t radio_ar_match_get(void);
void radio_ar_status_reset(void);
u32_t radio_ar_has_match(void);

View file

@ -33,3 +33,4 @@
#endif
#include "radio_nrf5_ppi.h"
#include "radio_nrf5_txp.h"

View file

@ -59,22 +59,22 @@
/* TXEN->TXIDLE + TXIDLE->TX (with fast Radio ramp-up mode)
* in microseconds for LE CODED PHY [S2].
*/
#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S2_FAST_NS 43100 /* 40.1 + 3.0 */
#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S2_FAST_NS 42300 /* 40.1 + 2.2 */
#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S2_FAST_US \
HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF52840_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_NRF52840_TXEN_TXIDLE_TX_S2_DEFAULT_NS 133000 /* 130 + 3.0 */
#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S2_DEFAULT_NS 132200 /* 130 + 2.2 */
#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S2_DEFAULT_US \
HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF52840_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 + 3.0 */
#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S2_DEFAULT_NO_HW_TIFS_NS 132500
/* 129.5 + 2.2 */
#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S2_DEFAULT_NO_HW_TIFS_NS 131700
#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S2_DEFAULT_NO_HW_TIFS_US \
HAL_RADIO_NS2US_ROUND( \
HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S2_DEFAULT_NO_HW_TIFS_NS)
@ -82,21 +82,21 @@
/* TXEN->TXIDLE + TXIDLE->TX (with fast Radio ramp-up mode)
* in microseconds for LE CODED PHY [S8].
*/
#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S8_FAST_NS 43100 /* 40.1 + 3.0 */
#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S8_FAST_NS 42300 /* 40.1 + 2.2 */
#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S8_FAST_US \
HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF52840_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_NRF52840_TXEN_TXIDLE_TX_S8_DEFAULT_NS 122600 /*119.6 + 3.0 */
#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S8_DEFAULT_NS 121800 /*119.6 + 2.2*/
#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S8_DEFAULT_US \
HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF52840_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 + 3.0 */
#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S8_DEFAULT_NO_HW_TIFS_NS 132500
/* 129.5 + 2.2 */
#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S8_DEFAULT_NO_HW_TIFS_NS 131700
#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S8_DEFAULT_NO_HW_TIFS_US \
HAL_RADIO_NS2US_ROUND( \
HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S8_DEFAULT_NO_HW_TIFS_NS)
@ -208,8 +208,8 @@
#define HAL_RADIO_NRF52840_RX_CHAIN_DELAY_2M_NS 5000 /* 5.0 */
#define HAL_RADIO_NRF52840_RX_CHAIN_DELAY_S2_US 20 /* ceil(19.6) */
#define HAL_RADIO_NRF52840_RX_CHAIN_DELAY_S2_NS 19600 /* 19.6 */
#define HAL_RADIO_NRF52840_RX_CHAIN_DELAY_S8_US 30 /* ceil(29.6 - 0.3) */
#define HAL_RADIO_NRF52840_RX_CHAIN_DELAY_S8_NS 29300 /* 29.6 - 0.3*/
#define HAL_RADIO_NRF52840_RX_CHAIN_DELAY_S8_US 30 /* ceil(29.6) */
#define HAL_RADIO_NRF52840_RX_CHAIN_DELAY_S8_NS 29600 /* 29.6 */
#if defined(CONFIG_BT_CTLR_RADIO_ENABLE_FAST)
#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_1M_US \

View file

@ -5,13 +5,21 @@
* SPDX-License-Identifier: Apache-2.0
*/
#define HAL_TICKER_CNTR_CLK_FREQ_HZ 32768U
/* Macro definining the minimum counter compare offset */
#define HAL_TICKER_CNTR_CMP_OFFSET_MIN 3
/* Macro definining the max. counter update latency in ticks */
#define HAL_TICKER_CNTR_SET_LATENCY 0
/* Macro to translate microseconds to tick units.
* NOTE: This returns the floor value.
*/
#define HAL_TICKER_US_TO_TICKS(x) \
( \
((u32_t)(((u64_t) (x) * 1000000000UL) / 30517578125UL)) \
& 0x00FFFFFF \
& HAL_TICKER_CNTR_MASK \
)
/* Macro returning remainder in nanoseconds */
@ -26,7 +34,16 @@
/* Macro to translate tick units to microseconds. */
#define HAL_TICKER_TICKS_TO_US(x) \
((u32_t)(((u64_t) (x) * 30517578125UL) / 1000000000UL))
((u32_t)(((u64_t)(x) * 30517578125UL) / 1000000000UL))
/* Macro defines the h/w supported most significant bit */
#define HAL_TICKER_MSBIT 23
#define HAL_TICKER_CNTR_MSBIT 23
/* Macro defining the HW supported counter bits */
#define HAL_TICKER_CNTR_MASK 0x00FFFFFF
/* Macro defining the remainder resolution/range
* ~ 1000000 * HAL_TICKER_TICKS_TO_US(1)
*/
#define HAL_TICKER_REMAINDER_RANGE \
HAL_TICKER_TICKS_TO_US(1000000)

View file

@ -0,0 +1,8 @@
/*
* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "hal/nrf5/radio/radio.h"
#include "hal/nrf5/radio/radio_nrf5_txp.h"

View file

@ -0,0 +1,7 @@
/*
* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "hal/nrf5/ticker.h"

View file

@ -11,8 +11,28 @@
#define PDU_AC_PAYLOAD_SIZE_MAX 37
#define PDU_AC_SIZE_MAX (offsetof(struct pdu_adv, payload) + \
PDU_AC_PAYLOAD_SIZE_MAX)
#define PDU_DC_PAYLOAD_SIZE_MIN 27
#define PDU_EM_SIZE_MAX offsetof(struct pdu_data, lldata)
/* Extra bytes for enqueued node_rx metadata: rssi (always), resolving
* index, directed adv report, and mesh channel and instant.
*/
#define PDU_AC_SIZE_RSSI 1
#if defined(CONFIG_BT_CTLR_PRIVACY)
#define PDU_AC_SIZE_PRIV 1
#else
#define PDU_AC_SIZE_PRIV 0
#endif /* CONFIG_BT_CTLR_PRIVACY */
#if defined(CONFIG_BT_CTLR_EXT_SCAN_FP)
#define PDU_AC_SIZE_SCFP 1
#else
#define PDU_AC_SIZE_SCFP 0
#endif /* CONFIG_BT_CTLR_EXT_SCAN_FP */
#define PDU_AC_SIZE_EXTRA (PDU_AC_SIZE_RSSI + \
PDU_AC_SIZE_PRIV + \
PDU_AC_SIZE_SCFP)
struct pdu_adv_adv_ind {
u8_t addr[BDADDR_SIZE];
u8_t data[31];

View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
struct node_rx_cc {
u8_t status;
u8_t role;
u8_t peer_addr_type;
u8_t peer_addr[BDADDR_SIZE];
#if defined(CONFIG_BT_CTLR_PRIVACY)
u8_t peer_rpa[BDADDR_SIZE];
u8_t own_addr_type;
u8_t own_addr[BDADDR_SIZE];
#endif /* CONFIG_BT_CTLR_PRIVACY */
u16_t interval;
u16_t latency;
u16_t timeout;
u8_t sca;
};
struct node_rx_cu {
u8_t status;
u16_t interval;
u16_t latency;
u16_t timeout;
};
struct node_rx_cs {
u8_t csa;
};
struct node_rx_pu {
u8_t status;
u8_t tx;
u8_t rx;
};

View file

@ -5,6 +5,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdbool.h>
#include <zephyr/types.h>
#include <soc.h>
@ -21,7 +22,6 @@
* Defines
****************************************************************************/
#define DOUBLE_BUFFER_SIZE 2
#define COUNTER_CMP_OFFSET_MIN 3
/*****************************************************************************
* Types
@ -66,10 +66,10 @@ struct ticker_user_op_start {
};
struct ticker_user_op_update {
u16_t ticks_drift_plus;
u16_t ticks_drift_minus;
u16_t ticks_slot_plus;
u16_t ticks_slot_minus;
u32_t ticks_drift_plus;
u32_t ticks_drift_minus;
u32_t ticks_slot_plus;
u32_t ticks_slot_minus;
u16_t lazy;
u8_t force;
};
@ -124,7 +124,8 @@ struct ticker_instance {
/*****************************************************************************
* Global instances
****************************************************************************/
static struct ticker_instance _instance[2];
#define TICKER_INSTANCE_MAX 1
static struct ticker_instance _instance[TICKER_INSTANCE_MAX];
/*****************************************************************************
* Static Functions
@ -384,7 +385,7 @@ void ticker_worker(void *param)
ticks_at_expire = (instance->ticks_current +
ticks_expired -
ticker->ticks_to_expire_minus) &
0x00FFFFFF;
HAL_TICKER_CNTR_MASK;
DEBUG_TICKER_TASK(1);
ticker->timeout_func(ticks_at_expire,
@ -420,7 +421,7 @@ static void ticks_to_expire_prep(struct ticker_node *ticker,
u32_t ticks_to_expire_minus = ticker->ticks_to_expire_minus;
/* Calculate ticks to expire for this new node */
if (!((ticks_at_start - ticks_current) & BIT(HAL_TICKER_MSBIT))) {
if (!((ticks_at_start - ticks_current) & BIT(HAL_TICKER_CNTR_MSBIT))) {
ticks_to_expire += ticker_ticks_diff_get(ticks_at_start,
ticks_current);
} else {
@ -452,27 +453,35 @@ static void ticks_to_expire_prep(struct ticker_node *ticker,
static u8_t ticker_remainder_inc(struct ticker_node *ticker)
{
#ifdef HAL_TICKER_REMAINDER_RANGE
ticker->remainder_current += ticker->remainder_periodic;
if ((ticker->remainder_current < BIT(31)) &&
(ticker->remainder_current > (30517578UL / 2))) {
ticker->remainder_current -= 30517578UL;
(ticker->remainder_current > (HAL_TICKER_REMAINDER_RANGE >> 1))) {
ticker->remainder_current -= HAL_TICKER_REMAINDER_RANGE;
return 1;
}
return 0;
#else
return 0;
#endif
}
static u8_t ticker_remainder_dec(struct ticker_node *ticker)
{
#ifdef HAL_TICKER_REMAINDER_RANGE
u8_t decrement = 0U;
if ((ticker->remainder_current >= BIT(31)) ||
(ticker->remainder_current <= (30517578UL / 2))) {
(ticker->remainder_current <= (HAL_TICKER_REMAINDER_RANGE >> 1))) {
decrement++;
ticker->remainder_current += 30517578UL;
ticker->remainder_current += HAL_TICKER_REMAINDER_RANGE;
}
ticker->remainder_current -= ticker->remainder_periodic;
return decrement;
#else
return 0;
#endif
}
static void ticker_job_op_cb(struct ticker_user_op *user_op, u32_t status)
@ -1030,15 +1039,17 @@ static inline void ticker_job_compare_update(struct ticker_instance *instance,
ctr = cntr_cnt_get();
cc = instance->ticks_current;
ticks_elapsed = ticker_ticks_diff_get(ctr, cc) +
COUNTER_CMP_OFFSET_MIN;
HAL_TICKER_CNTR_CMP_OFFSET_MIN +
HAL_TICKER_CNTR_SET_LATENCY;
cc += max(ticks_elapsed, ticks_to_expire);
cc &= 0x00FFFFFF;
cc &= HAL_TICKER_CNTR_MASK;
instance->trigger_set_cb(cc);
ctr_post = cntr_cnt_get();
} while ((ticker_ticks_diff_get(ctr_post, ctr) +
COUNTER_CMP_OFFSET_MIN) > ticker_ticks_diff_get(cc, ctr));
HAL_TICKER_CNTR_CMP_OFFSET_MIN) >
ticker_ticks_diff_get(cc, ctr));
}
void ticker_job(void *param)
@ -1079,7 +1090,7 @@ void ticker_job(void *param)
instance->ticks_elapsed[instance->ticks_elapsed_first];
instance->ticks_current += ticks_elapsed;
instance->ticks_current &= 0x00FFFFFF;
instance->ticks_current &= HAL_TICKER_CNTR_MASK;
flag_elapsed = 1U;
} else {
@ -1164,7 +1175,8 @@ u32_t ticker_init(u8_t instance_index, u8_t count_node, void *node,
if ((sizeof(struct ticker_node) != TICKER_NODE_T_SIZE) ||
(sizeof(struct ticker_user) != TICKER_USER_T_SIZE) ||
(sizeof(struct ticker_user_op) != TICKER_USER_OP_T_SIZE)) {
(sizeof(struct ticker_user_op) != TICKER_USER_OP_T_SIZE) ||
(instance_index >= TICKER_INSTANCE_MAX)) {
return TICKER_STATUS_FAILURE;
}
@ -1267,8 +1279,8 @@ u32_t ticker_start(u8_t instance_index, u8_t user_id, u8_t ticker_id,
}
u32_t ticker_update(u8_t instance_index, u8_t user_id, u8_t ticker_id,
u16_t ticks_drift_plus, u16_t ticks_drift_minus,
u16_t ticks_slot_plus, u16_t ticks_slot_minus, u16_t lazy,
u32_t ticks_drift_plus, u32_t ticks_drift_minus,
u32_t ticks_slot_plus, u32_t ticks_slot_minus, u16_t lazy,
u8_t force, ticker_op_func fp_op_func, void *op_context)
{
struct ticker_instance *instance = &_instance[instance_index];
@ -1429,5 +1441,5 @@ u32_t ticker_ticks_now_get(void)
u32_t ticker_ticks_diff_get(u32_t ticks_now, u32_t ticks_old)
{
return ((ticks_now - ticks_old) & 0x00FFFFFF);
return ((ticks_now - ticks_old) & HAL_TICKER_CNTR_MASK);
}

View file

@ -92,8 +92,8 @@ u32_t ticker_start(u8_t instance_index, u8_t user_id, u8_t ticker_id,
ticker_timeout_func fp_timeout_func, void *context,
ticker_op_func fp_op_func, void *op_context);
u32_t ticker_update(u8_t instance_index, u8_t user_id, u8_t ticker_id,
u16_t ticks_drift_plus, u16_t ticks_drift_minus,
u16_t ticks_slot_plus, u16_t ticks_slot_minus, u16_t lazy,
u32_t ticks_drift_plus, u32_t ticks_drift_minus,
u32_t ticks_slot_plus, u32_t ticks_slot_minus, u16_t lazy,
u8_t force, ticker_op_func fp_op_func, void *op_context);
u32_t ticker_stop(u8_t instance_index, u8_t user_id, u8_t ticker_id,
ticker_op_func fp_op_func, void *op_context);

View file

@ -5,7 +5,9 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <stddef.h>
#include <zephyr/types.h>
#include <misc/printk.h>
#include "memq.h"
#include "mayfly.h"
@ -19,6 +21,11 @@ static struct {
} mft[MAYFLY_CALLEE_COUNT][MAYFLY_CALLER_COUNT];
static memq_link_t mfl[MAYFLY_CALLEE_COUNT][MAYFLY_CALLER_COUNT];
static u8_t mfp[MAYFLY_CALLEE_COUNT];
#if defined(CONFIG_MAYFLY_UT)
static u8_t _state;
#endif /* CONFIG_MAYFLY_UT */
void mayfly_init(void)
{
@ -78,10 +85,7 @@ u32_t mayfly_enqueue(u8_t caller_id, u8_t callee_id, u8_t chain,
/* mark as ready in queue */
m->_req = ack + 1;
/* pend the callee for execution */
mayfly_pend(caller_id, callee_id);
return 0;
goto mayfly_enqueue_pend;
}
/* already ready */
@ -104,18 +108,74 @@ u32_t mayfly_enqueue(u8_t caller_id, u8_t callee_id, u8_t chain,
m->_req = ack + 1;
memq_enqueue(m->_link, m, &mft[callee_id][caller_id].tail);
mayfly_enqueue_pend:
/* set mayfly callee pending */
mfp[callee_id] = 1;
/* pend the callee for execution */
mayfly_pend(caller_id, callee_id);
return 0;
}
static void dequeue(u8_t callee_id, u8_t caller_id, memq_link_t *link,
struct mayfly *m)
{
u8_t req;
req = m->_req;
if (((req - m->_ack) & 0x03) != 1) {
u8_t ack;
#if defined(CONFIG_MAYFLY_UT)
u32_t mayfly_ut_run_test(void);
void mayfly_ut_mfy(void *param);
if (_state && m->fp == mayfly_ut_mfy) {
static u8_t single;
if (!single) {
single = 1;
mayfly_ut_run_test();
}
}
#endif /* CONFIG_MAYFLY_UT */
/* dequeue mayfly struct */
memq_dequeue(mft[callee_id][caller_id].tail,
&mft[callee_id][caller_id].head,
0);
/* release link into dequeued mayfly struct */
m->_link = link;
/* reset mayfly state to idle */
ack = m->_ack;
m->_ack = req;
/* re-insert, if re-pended by interrupt */
if (((m->_req - ack) & 0x03) == 1) {
#if defined(CONFIG_MAYFLY_UT)
printk("%s: RACE\n", __func__);
#endif /* CONFIG_MAYFLY_UT */
m->_ack = ack;
memq_enqueue(link, m, &mft[callee_id][callee_id].tail);
}
}
}
void mayfly_run(u8_t callee_id)
{
u8_t disable = 0U;
u8_t enable = 0U;
u8_t caller_id;
if (!mfp[callee_id]) {
return;
}
mfp[callee_id] = 1;
/* iterate through each caller queue to this callee_id */
caller_id = MAYFLY_CALLER_COUNT;
while (caller_id--) {
@ -128,12 +188,18 @@ void mayfly_run(u8_t callee_id)
(void **)&m);
while (link) {
u8_t state;
u8_t req;
#if defined(CONFIG_MAYFLY_UT)
_state = 0;
#endif /* CONFIG_MAYFLY_UT */
/* execute work if ready */
req = m->_req;
state = (req - m->_ack) & 0x03;
state = (m->_req - m->_ack) & 0x03;
if (state == 1) {
#if defined(CONFIG_MAYFLY_UT)
_state = 1;
#endif /* CONFIG_MAYFLY_UT */
/* mark mayfly as ran */
m->_ack--;
@ -142,18 +208,7 @@ void mayfly_run(u8_t callee_id)
}
/* dequeue if not re-pended */
req = m->_req;
if (((req - m->_ack) & 0x03) != 1) {
memq_dequeue(mft[callee_id][caller_id].tail,
&mft[callee_id][caller_id].head,
0);
/* release link into dequeued mayfly struct */
m->_link = link;
/* reset mayfly state to idle */
m->_ack = req;
}
dequeue(callee_id, caller_id, link, m);
/* fetch next mayfly in callee queue, if any */
link = memq_peek(mft[callee_id][caller_id].head,
@ -197,3 +252,82 @@ void mayfly_run(u8_t callee_id)
mayfly_enable_cb(callee_id, callee_id, 0);
}
}
#if defined(CONFIG_MAYFLY_UT)
#define MAYFLY_CALL_ID_CALLER MAYFLY_CALL_ID_0
#define MAYFLY_CALL_ID_CALLEE MAYFLY_CALL_ID_2
void mayfly_ut_mfy(void *param)
{
printk("%s: ran.\n", __func__);
(*((u32_t *)param))++;
}
void mayfly_ut_test(void *param)
{
static u32_t *count;
static memq_link_t link;
static struct mayfly mfy = {0, 0, &link, NULL, mayfly_ut_mfy};
u32_t err;
printk("%s: req= %u, ack= %u\n", __func__, mfy._req, mfy._ack);
if (param) {
count = param;
}
mfy.param = count;
err = mayfly_enqueue(MAYFLY_CALL_ID_CALLER, MAYFLY_CALL_ID_CALLEE, 1,
&mfy);
if (err) {
printk("%s: FAILED (%u).\n", __func__, err);
} else {
printk("%s: SUCCESS.\n", __func__);
}
}
u32_t mayfly_ut_run_test(void)
{
static memq_link_t link;
static struct mayfly mfy = {0, 0, &link, NULL, mayfly_ut_test};
u32_t err;
printk("%s: req= %u, ack= %u\n", __func__, mfy._req, mfy._ack);
err = mayfly_enqueue(MAYFLY_CALL_ID_CALLEE, MAYFLY_CALL_ID_CALLER, 0,
&mfy);
if (err) {
printk("%s: FAILED.\n", __func__);
return err;
}
printk("%s: SUCCESS.\n", __func__);
return 0;
}
u32_t mayfly_ut(void)
{
static u32_t count;
static memq_link_t link;
static struct mayfly mfy = {0, 0, &link, &count, mayfly_ut_test};
u32_t err;
printk("%s: req= %u, ack= %u\n", __func__, mfy._req, mfy._ack);
err = mayfly_enqueue(MAYFLY_CALL_ID_PROGRAM, MAYFLY_CALL_ID_CALLER, 0,
&mfy);
if (err) {
printk("%s: FAILED.\n", __func__);
return err;
}
printk("%s: count = %u.\n", __func__, count);
printk("%s: SUCCESS.\n", __func__);
return 0;
}
#endif /* CONFIG_MAYFLY_UT */

View file

@ -20,6 +20,21 @@ memq_link_t *memq_init(memq_link_t *link, memq_link_t **head, memq_link_t **tail
return link;
}
memq_link_t *memq_deinit(memq_link_t **head, memq_link_t **tail)
{
memq_link_t *link;
/* if head and tail are not equal, then queue is not empty */
if (*head != *tail) {
return NULL;
}
link = *head;
*head = *tail = NULL;
return link;
}
memq_link_t *memq_enqueue(memq_link_t *link, void *mem, memq_link_t **tail)
{
/* make the current tail link's next point to new link */

View file

@ -12,8 +12,19 @@ struct _memq_link {
typedef struct _memq_link memq_link_t;
#define MEMQ_DECLARE(name) \
struct { \
memq_link_t *head; \
memq_link_t *tail; \
} memq_##name
memq_link_t *memq_init(memq_link_t *link, memq_link_t **head,
memq_link_t **tail);
#define MEMQ_INIT(name, link) \
memq_init(link, &memq_##name.head, &memq_##name.tail)
memq_link_t *memq_deinit(memq_link_t **head, memq_link_t **tail);
memq_link_t *memq_enqueue(memq_link_t *link, void *mem, memq_link_t **tail);
memq_link_t *memq_peek(memq_link_t *head, memq_link_t *tail, void **mem);
memq_link_t *memq_dequeue(memq_link_t *tail, memq_link_t **head, void **mem);

View file

@ -16,12 +16,9 @@
#include <shell/shell.h>
#if defined(CONFIG_SOC_COMPATIBLE_NRF)
#include "../controller/hal/nrf5/ticker.h"
#endif /* CONFIG_SOC_COMPATIBLE_NRF */
#include "../controller/util/memq.h"
#include "../controller/util/mayfly.h"
#include "../controller/hal/ticker.h"
#include "../controller/ticker/ticker.h"
#if defined(CONFIG_BT_MAX_CONN)