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() 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) #if defined(CONFIG_SOC_FLASH_NRF_RADIO_SYNC)
#include <misc/__assert.h> #include <misc/__assert.h>
#include <bluetooth/hci.h> #include <bluetooth/hci.h>
#include "controller/hal/nrf5/ticker.h" #include "controller/hal/ticker.h"
#include "controller/ticker/ticker.h" #include "controller/ticker/ticker.h"
#include "controller/include/ll.h" #include "controller/include/ll.h"

View file

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

View file

@ -52,12 +52,6 @@ config BT_CTLR_RX_PRIO
int int
default 6 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 config BT_CTLR_HCI_VS_BUILD_INFO
string "Zephyr HCI VS Build Info string" string "Zephyr HCI VS Build Info string"
default "" default ""
@ -69,7 +63,6 @@ config BT_CTLR_HCI_VS_BUILD_INFO
character is required at the beginning to separate it from the character is required at the beginning to separate it from the
already included information. already included information.
if BT_LL_SW
config BT_CTLR_DUP_FILTER_LEN config BT_CTLR_DUP_FILTER_LEN
int "Number of addresses in the scan duplicate filter" int "Number of addresses in the scan duplicate filter"
depends on BT_OBSERVER depends on BT_OBSERVER
@ -205,13 +198,29 @@ config BT_CTLR_LE_ENC
config BT_CTLR_CONN_PARAM_REQ config BT_CTLR_CONN_PARAM_REQ
bool "Connection Parameter Request" bool "Connection Parameter Request"
select BT_CTLR_EXT_REJ_IND
default y default y
help help
Enable support for Bluetooth v4.1 Connection Parameter Request feature Enable support for Bluetooth v4.1 Connection Parameter Request feature
in the Controller. 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 config BT_CTLR_LE_PING
bool "LE Ping" bool "LE Ping"
depends on BT_CTLR_LE_ENC
default y default y
help help
Enable support for Bluetooth v4.1 LE Ping feature in the Controller. 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" bool "LE Controller-based Privacy"
depends on !SOC_SERIES_NRF51X depends on !SOC_SERIES_NRF51X
default y default y
select BT_CTLR_FILTER
select BT_RPA select BT_RPA
help help
Enable support for Bluetooth v4.2 LE Controller-based Privacy feature Enable support for Bluetooth v4.2 LE Controller-based Privacy feature
@ -263,6 +273,7 @@ config BT_CTLR_PHY
# Procedure in the Controller. # Procedure in the Controller.
bool bool
depends on BT_PHY_UPDATE depends on BT_PHY_UPDATE
select BT_CTLR_EXT_REJ_IND
default y if SOC_COMPATIBLE_NRF52X default y if SOC_COMPATIBLE_NRF52X
endif # BT_CONN endif # BT_CONN
@ -309,6 +320,13 @@ config BT_CTLR_ADVANCED_FEATURES
menu "Advanced features" menu "Advanced features"
visible if BT_CTLR_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 config BT_CTLR_DATA_LENGTH_CLEAR
bool "Data Length Support (Cleartext only)" bool "Data Length Support (Cleartext only)"
depends on BT_CTLR_DATA_LENGTH && SOC_SERIES_NRF51X 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 Enable support for Nordic Semiconductor proprietary 2Mbps PHY in the
Controller. Encrypted connections are not supported. Controller. Encrypted connections are not supported.
endif # BT_CTLR_PHY
config BT_CTLR_PHY_CODED config BT_CTLR_PHY_CODED
bool "Coded PHY Support" bool "Coded PHY Support"
depends on SOC_NRF52840 depends on (BT_CTLR_PHY || BT_CTLR_ADV_EXT) && SOC_NRF52840
default y default y
help help
Enable support for Bluetooth 5.0 Coded PHY in the Controller. Enable support for Bluetooth 5.0 Coded PHY in the Controller.
endif # BT_CTLR_PHY if BT_LL_SW
config BT_CTLR_WORKER_PRIO config BT_CTLR_WORKER_PRIO
int "Radio and Ticker's Worker IRQ priority" 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 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. be greater than or equal to the Ticker's Worker IRQ priority value.
endif # BT_LL_SW
config BT_CTLR_XTAL_ADVANCED config BT_CTLR_XTAL_ADVANCED
bool "Advanced event preparation" bool "Advanced event preparation"
default y default y
@ -477,11 +499,13 @@ endif # BT_CONN
config BT_CTLR_ADV_INDICATION config BT_CTLR_ADV_INDICATION
bool "Advertisement indications" bool "Advertisement indications"
depends on BT_BROADCASTER
help help
Generate events indicating on air advertisement events. Generate events indicating on air advertisement events.
config BT_CTLR_SCAN_REQ_NOTIFY config BT_CTLR_SCAN_REQ_NOTIFY
bool "Scan Request Notifications" bool "Scan Request Notifications"
depends on BT_BROADCASTER
help help
Generate events notifying the on air scan requests received. Generate events notifying the on air scan requests received.
@ -491,6 +515,12 @@ config BT_CTLR_SCAN_REQ_RSSI
help help
Measure RSSI of the on air scan requests received. 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 endmenu
comment "BLE Controller hardware configuration" 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 when debugging with a logic analyzer or profiling certain sections of
the code. the code.
endif # BT_LL_SW
endif # BT_CTLR 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) #define LL_ASSERT(cond) BT_ASSERT(cond)
#endif #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) 2018 Nordic Semiconductor ASA
* Copyright (c) 2016 Vinayak Kariappa Chettimada
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
typedef void (*radio_isr_fp) (void); #include "hal/radio_vendor_hal.h"
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);

View file

@ -5,11 +5,7 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include <stdbool.h> #include "hal/ticker_vendor_hal.h"
#if defined(CONFIG_SOC_COMPATIBLE_NRF)
#include "hal/nrf5/ticker.h"
#endif /* CONFIG_SOC_FAMILY_NRF */
u8_t hal_ticker_instance0_caller_id_get(u8_t user_id); 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, 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 "common/log.h"
#include "util/util.h" #include "util/util.h"
#include "util/memq.h"
#include "hal/ccm.h" #include "hal/ccm.h"
#if defined(CONFIG_SOC_FAMILY_NRF)
#include "hal/radio.h" #include "hal/radio.h"
#endif /* CONFIG_SOC_FAMILY_NRF */
#include "ll_sw/pdu.h" #include "ll_sw/pdu.h"
#include "ll_sw/ctrl.h" #include "ll_sw/lll.h"
#include "ll.h" #include "ll.h"
#include "hci_internal.h" #include "hci_internal.h"
#include "hal/debug.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_SEM_DEFINE(sem_prio_recv, 0, UINT_MAX);
static K_FIFO_DEFINE(recv_fifo); 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) s8_t class)
{ {
struct net_buf *buf = NULL; 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) #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); radio_rx_fc_set(node_rx->hdr.handle, 0);
}
#endif /* CONFIG_BT_LL_SW */ #endif /* CONFIG_BT_LL_SW */
node_rx->hdr.onion.next = 0; node_rx->hdr.next = NULL;
ll_rx_mem_release((void **)&node_rx); ll_rx_mem_release((void **)&node_rx);
return buf; 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); s8_t class = hci_get_class(node_rx);
struct net_buf *buf = NULL; struct net_buf *buf = NULL;
@ -170,8 +178,7 @@ static inline struct net_buf *process_node(struct radio_pdu_node_rx *node_rx)
/* fallthrough */ /* fallthrough */
case HCI_CLASS_ACL_DATA: case HCI_CLASS_ACL_DATA:
if (pend || !hbuf_count) { if (pend || !hbuf_count) {
sys_slist_append(&hbuf_pend, sys_slist_append(&hbuf_pend, (void *)node_rx);
&node_rx->hdr.onion.node);
BT_DBG("FC: Queuing item: %d", class); BT_DBG("FC: Queuing item: %d", class);
return NULL; 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) #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 */ /* 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; s32_t hbuf_total = hci_hbuf_total;
struct net_buf *buf = NULL; struct net_buf *buf = NULL;
sys_snode_t *node = NULL;
s8_t class; s8_t class;
int reset; 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); hbuf_count = hbuf_total - (hci_hbuf_sent - hci_hbuf_acked);
/* host acked ACL packets, try to dequeue from hbuf */ /* host acked ACL packets, try to dequeue from hbuf */
node = sys_slist_peek_head(&hbuf_pend); node_rx = (void *)sys_slist_peek_head(&hbuf_pend);
if (!node) { if (!node_rx) {
return NULL; return NULL;
} }
/* Return early if this iteration already has a node to process */ /* Return early if this iteration already has a node to process */
node_rx = NODE_RX(node);
class = hci_get_class(node_rx); class = hci_get_class(node_rx);
if (n) { if (n) {
if (class == HCI_CLASS_EVT_CONNECTION || 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); (void) sys_slist_get(&hbuf_pend);
} else { } else {
/* no buffers, HCI will signal */ /* no buffers, HCI will signal */
node = NULL; node_rx = NULL;
} }
break; break;
case HCI_CLASS_EVT_DISCARDABLE: case HCI_CLASS_EVT_DISCARDABLE:
@ -254,14 +259,13 @@ static inline struct net_buf *process_hbuf(struct radio_pdu_node_rx *n)
break; break;
} }
if (node) { if (node_rx) {
buf = encode_node(node_rx, class); buf = encode_node(node_rx, class);
/* Update host buffers after encoding */ /* Update host buffers after encoding */
hbuf_count = hbuf_total - (hci_hbuf_sent - hci_hbuf_acked); hbuf_count = hbuf_total - (hci_hbuf_sent - hci_hbuf_acked);
/* next node */ /* next node */
node = sys_slist_peek_head(&hbuf_pend); node_rx = (void *)sys_slist_peek_head(&hbuf_pend);
if (node) { if (node_rx) {
node_rx = NODE_RX(node);
class = hci_get_class(node_rx); class = hci_get_class(node_rx);
if (class == HCI_CLASS_EVT_CONNECTION || if (class == HCI_CLASS_EVT_CONNECTION ||
@ -294,7 +298,7 @@ static void recv_thread(void *p1, void *p2, void *p3)
#endif #endif
while (1) { while (1) {
struct radio_pdu_node_rx *node_rx = NULL; struct node_rx_pdu *node_rx = NULL;
struct net_buf *buf = NULL; struct net_buf *buf = NULL;
BT_DBG("blocking"); 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); void hci_init(struct k_poll_signal *signal_host_buf);
struct net_buf *hci_cmd_handle(struct net_buf *cmd, void **node_rx); 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); void hci_evt_encode(struct node_rx_pdu *node_rx, struct net_buf *buf);
s8_t hci_get_class(struct radio_pdu_node_rx *node_rx); s8_t hci_get_class(struct node_rx_pdu *node_rx);
#if defined(CONFIG_BT_CONN) #if defined(CONFIG_BT_CONN)
int hci_acl_handle(struct net_buf *acl, struct net_buf **evt); 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); void hci_num_cmplt_encode(struct net_buf *buf, u16_t handle, u8_t num);
#endif #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 * Copyright (c) 2016 Vinayak Kariappa Chettimada
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#define LL_VERSION_NUMBER BT_HCI_VERSION_5_0
int ll_init(struct k_sem *sem_rx); int ll_init(struct k_sem *sem_rx);
void ll_reset(void); void ll_reset(void);
u8_t *ll_addr_get(u8_t addr_type, u8_t *p_bdaddr); 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) #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 adv_type, u8_t own_addr_type,
u8_t direct_addr_type, u8_t const *const direct_addr, 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 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 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 */ #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 own_addr_type, u8_t direct_addr_type,
u8_t const *const direct_addr, u8_t chan_map, u8_t const *const direct_addr, u8_t chan_map,
u8_t filter_policy); 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 */ #endif /* !CONFIG_BT_CTLR_ADV_EXT */
void ll_adv_data_set(u8_t len, u8_t const *const p_data); #if defined(CONFIG_BT_CTLR_ADV_EXT)
void ll_scan_data_set(u8_t len, u8_t const *const p_data); u8_t ll_adv_enable(u16_t handle, u8_t enable);
u32_t ll_adv_enable(u8_t enable); #else /* !CONFIG_BT_CTLR_ADV_EXT */
u32_t ll_scan_params_set(u8_t type, u16_t interval, u16_t window, u8_t ll_adv_enable(u8_t enable);
u8_t own_addr_type, u8_t filter_policy); #endif /* !CONFIG_BT_CTLR_ADV_EXT */
u32_t ll_scan_enable(u8_t enable);
u32_t ll_wl_size_get(void); u8_t ll_scan_params_set(u8_t type, u16_t interval, u16_t window,
u32_t ll_wl_clear(void); u8_t own_addr_type, u8_t filter_policy);
u32_t ll_wl_add(bt_addr_le_t *addr); u8_t ll_scan_enable(u8_t enable);
u32_t ll_wl_remove(bt_addr_le_t *addr);
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); 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); u8_t ll_rl_size_get(void);
u32_t ll_rl_clear(void); u8_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_add(bt_addr_le_t *id_addr, const u8_t pirk[16],
const u8_t lirk[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); 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);
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);
u32_t ll_rl_enable(u8_t enable); u8_t ll_rl_enable(u8_t enable);
void ll_rl_timeout_set(u16_t timeout); 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 filter_policy, u8_t peer_addr_type,
u8_t *p_peer_addr, u8_t own_addr_type, u8_t *p_peer_addr, u8_t own_addr_type,
u16_t interval, u16_t latency, u16_t interval, u16_t latency, u16_t timeout);
u16_t timeout); u8_t ll_connect_disable(void **rx);
u32_t ll_connect_disable(void **node_rx); u8_t ll_conn_update(u16_t handle, u8_t cmd, u8_t status, u16_t interval_min,
u32_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); u16_t interval_max, u16_t latency, u16_t timeout);
u32_t ll_chm_update(u8_t *chm); u8_t ll_chm_update(u8_t *chm);
u32_t ll_chm_get(u16_t handle, u8_t *chm); u8_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_enc_req_send(u16_t handle, u8_t *rand, u8_t *ediv,
u8_t *ltk); 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); u8_t const *const ltk);
u32_t ll_feature_req_send(u16_t handle); u8_t ll_feature_req_send(u16_t handle);
u32_t ll_version_ind_send(u16_t handle); u8_t ll_version_ind_send(u16_t handle);
u32_t ll_terminate_ind_send(u16_t handle, u8_t reason); u8_t ll_terminate_ind_send(u16_t handle, u8_t reason);
u32_t ll_rssi_get(u16_t handle, u8_t *rssi); u8_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_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); void ll_tx_pwr_get(s8_t *min, s8_t *max);
u32_t ll_apto_get(u16_t handle, u16_t *apto); u8_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_set(u16_t handle, u16_t apto);
u32_t ll_length_req_send(u16_t handle, u16_t tx_octets, u16_t tx_time); 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); 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 */ /* Downstream - Data */
void *ll_tx_mem_acquire(void); void *ll_tx_mem_acquire(void);
void ll_tx_mem_release(void *node_tx); 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 */ /* Upstream - Num. Completes, Events and Data */
u8_t ll_rx_get(void **node_rx, u16_t *handle); 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 * Copyright (c) 2016 Vinayak Kariappa Chettimada
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
@ -26,71 +26,6 @@
#define RADIO_PACKET_TX_DATA_SIZE CONFIG_BT_CTLR_TX_BUFFER_SIZE #define RADIO_PACKET_TX_DATA_SIZE CONFIG_BT_CTLR_TX_BUFFER_SIZE
#endif #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) * Timer Resources (Controller defined)
****************************************************************************/ ****************************************************************************/
@ -115,46 +50,16 @@
#define RADIO_TICKER_USER_WORKER_OPS (7 + 1) #define RADIO_TICKER_USER_WORKER_OPS (7 + 1)
#define RADIO_TICKER_USER_JOB_OPS (2 + 1) #define RADIO_TICKER_USER_JOB_OPS (2 + 1)
#define RADIO_TICKER_USER_APP_OPS (1 + 1) #define RADIO_TICKER_USER_APP_OPS (1 + 1)
#define RADIO_TICKER_USER_OPS (RADIO_TICKER_USER_WORKER_OPS \ #define RADIO_TICKER_USER_OPS (RADIO_TICKER_USER_WORKER_OPS + \
+ RADIO_TICKER_USER_JOB_OPS \ RADIO_TICKER_USER_JOB_OPS + \
+ RADIO_TICKER_USER_APP_OPS \ RADIO_TICKER_USER_APP_OPS)
)
#define RADIO_TICKER_NODES (RADIO_TICKER_ID_FIRST_CONNECTION \ #define RADIO_TICKER_NODES (RADIO_TICKER_ID_FIRST_CONNECTION + \
+ RADIO_CONNECTION_CONTEXT_MAX \ RADIO_CONNECTION_CONTEXT_MAX)
)
/***************************************************************************** /*****************************************************************************
* Controller Interface Defines * 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) #if defined(CONFIG_BT_CTLR_WORKER_PRIO)
#define RADIO_TICKER_USER_ID_WORKER_PRIO CONFIG_BT_CTLR_WORKER_PRIO #define RADIO_TICKER_USER_ID_WORKER_PRIO CONFIG_BT_CTLR_WORKER_PRIO
#else #else
@ -170,45 +75,32 @@
/***************************************************************************** /*****************************************************************************
* Controller Reference Defines (compile time override-able) * 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 */ /* Implementation default L2CAP MTU */
#ifndef RADIO_L2CAP_MTU_MAX #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 #endif
/* Maximise L2CAP MTU to LL data PDU size */ /* 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 #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 #endif
/* Maximum LL PDU Receive pool size. */ /* Maximum LL PDU Receive pool size. */
#ifndef RADIO_PACKET_COUNT_RX_MAX #ifndef RADIO_PACKET_COUNT_RX_MAX
#define RADIO_PACKET_COUNT_RX ((RADIO_L2CAP_MTU_MAX + \ #define RADIO_PACKET_COUNT_RX ((RADIO_L2CAP_MTU_MAX + \
RADIO_LL_LENGTH_OCTETS_RX_MAX \ LL_LENGTH_OCTETS_RX_MAX + 3) / \
+ 3) \ LL_LENGTH_OCTETS_RX_MAX)
/ \
RADIO_LL_LENGTH_OCTETS_RX_MAX \
)
#define RADIO_PACKET_COUNT_RX_MAX (RADIO_PACKET_COUNT_RX + \ #define RADIO_PACKET_COUNT_RX_MAX (RADIO_PACKET_COUNT_RX + \
((RADIO_CONNECTION_CONTEXT_MAX - 1) * \ ((RADIO_CONNECTION_CONTEXT_MAX - 1) * \
(RADIO_PACKET_COUNT_RX - 1)) \ (RADIO_PACKET_COUNT_RX - 1)))
)
#endif /* RADIO_PACKET_COUNT_RX_MAX */ #endif /* RADIO_PACKET_COUNT_RX_MAX */
/* Maximum LL PDU Transmit pool size and application tx count. */ /* Maximum LL PDU Transmit pool size and application tx count. */
#ifndef RADIO_PACKET_COUNT_TX_MAX #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 + \ #define RADIO_PACKET_COUNT_TX_MAX (RADIO_PACKET_COUNT_RX_MAX + \
RADIO_PACKET_COUNT_APP_TX_MAX \ RADIO_PACKET_COUNT_APP_TX_MAX)
)
#else #else
#define RADIO_PACKET_COUNT_APP_TX_MAX (RADIO_PACKET_COUNT_TX_MAX) #define RADIO_PACKET_COUNT_APP_TX_MAX (RADIO_PACKET_COUNT_TX_MAX)
#endif #endif
@ -233,48 +125,6 @@ struct radio_pdu_node_tx {
u8_t pdu_data[1]; 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 { struct radio_le_conn_cmplt {
u8_t status; u8_t status;
u8_t role; u8_t role;
@ -289,24 +139,24 @@ struct radio_le_conn_cmplt {
u16_t latency; u16_t latency;
u16_t timeout; u16_t timeout;
u8_t mca; u8_t mca;
} __packed; };
struct radio_le_conn_update_cmplt { struct radio_le_conn_update_cmplt {
u8_t status; u8_t status;
u16_t interval; u16_t interval;
u16_t latency; u16_t latency;
u16_t timeout; u16_t timeout;
} __packed; };
struct radio_le_chan_sel_algo { struct radio_le_chan_sel_algo {
u8_t chan_sel_algo; u8_t chan_sel_algo;
} __packed; };
struct radio_le_phy_upd_cmplt { struct radio_le_phy_upd_cmplt {
u8_t status; u8_t status;
u8_t tx; u8_t tx;
u8_t rx; u8_t rx;
} __packed; };
struct radio_pdu_node_rx_hdr { struct radio_pdu_node_rx_hdr {
union { union {
@ -314,9 +164,9 @@ struct radio_pdu_node_rx_hdr {
void *next; /* used also by k_fifo once pulled */ void *next; /* used also by k_fifo once pulled */
void *link; void *link;
u8_t packet_release_last; u8_t packet_release_last;
} onion; };
enum radio_pdu_node_rx_type type; enum node_rx_type type;
u16_t handle; 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); u8_t rl_idx);
#endif /* !CONFIG_BT_CTLR_ADV_EXT */ #endif /* !CONFIG_BT_CTLR_ADV_EXT */
u32_t radio_adv_disable(void); u8_t radio_adv_disable(void);
u32_t ll_adv_is_enabled(void); u32_t ll_adv_is_enabled(u16_t handle);
u32_t radio_adv_filter_pol_get(void); u32_t radio_adv_filter_pol_get(void);
/* Downstream - Scanner */ /* Downstream - Scanner */
u32_t radio_scan_enable(u8_t type, u8_t init_addr_type, u8_t *init_addr, 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, u16_t interval, u16_t window, u8_t filter_policy,
u8_t rpa_gen, u8_t rl_idx); u8_t rpa_gen, u8_t rl_idx);
u32_t radio_scan_disable(bool scanner); u8_t radio_scan_disable(bool scanner);
u32_t ll_scan_is_enabled(void); u32_t ll_scan_is_enabled(u16_t handle);
u32_t radio_scan_filter_pol_get(void); u32_t radio_scan_filter_pol_get(void);
u32_t radio_connect_enable(u8_t adv_addr_type, u8_t *adv_addr, 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; 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 */ /* Minimum Rx Data allocation size */
#define PACKET_RX_DATA_SIZE_MIN \ #define PACKET_RX_DATA_SIZE_MIN \
MROUND(offsetof(struct radio_pdu_node_rx, pdu_data) + \ MROUND(offsetof(struct radio_pdu_node_rx, pdu_data) + \
@ -333,7 +321,7 @@ struct pdu_data_q_tx {
pdu_data) + \ pdu_data) + \
max((PDU_AC_SIZE_MAX + PDU_AC_SIZE_EXTRA), \ max((PDU_AC_SIZE_MAX + PDU_AC_SIZE_EXTRA), \
(offsetof(struct pdu_data, lldata) + \ (offsetof(struct pdu_data, lldata) + \
RADIO_LL_LENGTH_OCTETS_RX_MAX))) * \ LL_LENGTH_OCTETS_RX_MAX))) * \
(RADIO_PACKET_COUNT_RX_MAX + 3)) (RADIO_PACKET_COUNT_RX_MAX + 3))
#define LL_MEM_RX_LINK_POOL (sizeof(void *) * 2 * ((RADIO_PACKET_COUNT_RX_MAX +\ #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 "ticker/ticker.h"
#include "pdu.h" #include "pdu.h"
#include "lll.h"
#include "ctrl.h" #include "ctrl.h"
#include "ctrl_internal.h" #include "ctrl_internal.h"
#include "ll.h" #include "ll.h"
#include "ll_feat.h"
#include "ll_filter.h" #include "ll_filter.h"
/* Global singletons */ /* Global singletons */
@ -81,40 +83,39 @@ void radio_event_callback(void)
ISR_DIRECT_DECLARE(radio_nrf5_isr) ISR_DIRECT_DECLARE(radio_nrf5_isr)
{ {
DEBUG_RADIO_ISR(1);
isr_radio(); isr_radio();
ISR_DIRECT_PM(); ISR_DIRECT_PM();
DEBUG_RADIO_ISR(0);
return 1; return 1;
} }
static void rtc0_nrf5_isr(void *arg) static void rtc0_nrf5_isr(void *arg)
{ {
u32_t compare0, compare1; DEBUG_TICKER_ISR(1);
/* store interested events */
compare0 = NRF_RTC0->EVENTS_COMPARE[0];
compare1 = NRF_RTC0->EVENTS_COMPARE[1];
/* On compare0 run ticker worker instance0 */ /* On compare0 run ticker worker instance0 */
if (compare0) { if (NRF_RTC0->EVENTS_COMPARE[0]) {
NRF_RTC0->EVENTS_COMPARE[0] = 0; NRF_RTC0->EVENTS_COMPARE[0] = 0;
ticker_trigger(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); 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); mayfly_run(MAYFLY_CALL_ID_1);
DEBUG_TICKER_JOB(0);
} }
int ll_init(struct k_sem *sem_rx) 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_CONNECTION_CONTEXT_MAX,
RADIO_PACKET_COUNT_RX_MAX, RADIO_PACKET_COUNT_RX_MAX,
RADIO_PACKET_COUNT_TX_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)); RADIO_PACKET_TX_DATA_SIZE, &_radio[0], sizeof(_radio));
if (err) { if (err) {
BT_ERR("Required RAM size: %d, supplied: %u.", 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); radio_nrf5_isr, 0);
IRQ_CONNECT(NRF5_IRQ_RTC0_IRQn, CONFIG_BT_CTLR_WORKER_PRIO, IRQ_CONNECT(NRF5_IRQ_RTC0_IRQn, CONFIG_BT_CTLR_WORKER_PRIO,
rtc0_nrf5_isr, NULL, 0); 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); NULL, 0);
irq_enable(NRF5_IRQ_RADIO_IRQn); irq_enable(NRF5_IRQ_RADIO_IRQn);
irq_enable(NRF5_IRQ_RTC0_IRQn); irq_enable(NRF5_IRQ_RTC0_IRQn);
irq_enable(NRF5_IRQ_SWI4_IRQn); irq_enable(NRF5_IRQ_SWI5_IRQn);
return 0; return 0;
} }

View file

@ -10,12 +10,17 @@
#include <zephyr/types.h> #include <zephyr/types.h>
#include <bluetooth/hci.h> #include <bluetooth/hci.h>
#include <bluetooth/controller.h> #include <bluetooth/controller.h>
#include <misc/slist.h>
#include "util/util.h" #include "util/util.h"
#include "util/memq.h"
#include "ll_sw/pdu.h" #include "pdu.h"
#include "ll_sw/ctrl.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 pub_addr[BDADDR_SIZE];
static u8_t rnd_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) u32_t ll_addr_set(u8_t addr_type, u8_t const *const bdaddr)
{ {
if (ll_adv_is_enabled() || if (IS_ENABLED(CONFIG_BT_BROADCASTER) &&
(ll_scan_is_enabled() & (BIT(1) | BIT(2)))) { 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; 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 * Copyright (c) 2016 Vinayak Kariappa Chettimada
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
@ -11,8 +11,10 @@
#include <bluetooth/hci.h> #include <bluetooth/hci.h>
#include "util/util.h" #include "util/util.h"
#include "util/memq.h"
#include "pdu.h" #include "pdu.h"
#include "lll.h"
#include "ctrl.h" #include "ctrl.h"
#include "ll.h" #include "ll.h"
@ -29,7 +31,7 @@ struct ll_adv_set *ll_adv_set_get(void)
} }
#if defined(CONFIG_BT_CTLR_ADV_EXT) #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 adv_type, u8_t own_addr_type,
u8_t direct_addr_type, u8_t const *const direct_addr, 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 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_DIRECT_IND,
PDU_ADV_TYPE_EXT_IND}; PDU_ADV_TYPE_EXT_IND};
#else /* !CONFIG_BT_CTLR_ADV_EXT */ #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 own_addr_type, u8_t direct_addr_type,
u8_t const *const direct_addr, u8_t chan_map, u8_t const *const direct_addr, u8_t chan_map,
u8_t filter_policy) 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 radio_adv_data *radio_adv_data;
struct pdu_adv *pdu; struct pdu_adv *pdu;
if (ll_adv_is_enabled()) { if (ll_adv_is_enabled(0)) {
return BT_HCI_ERR_CMD_DISALLOWED; 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) #if defined(CONFIG_BT_CTLR_ADV_EXT)
} else if (pdu->type == PDU_ADV_TYPE_EXT_IND) { } else if (pdu->type == PDU_ADV_TYPE_EXT_IND) {
struct pdu_adv_com_ext_adv *p; struct pdu_adv_com_ext_adv *p;
struct ext_adv_hdr *h; struct ext_adv_hdr _h, *h;
u8_t *ptr; u8_t *_ptr, *ptr;
u8_t len; u8_t len;
p = (void *)&pdu->adv_ext_ind; p = (void *)&pdu->adv_ext_ind;
h = (void *)p->ext_hdr_adi_adv_data; h = (void *)p->ext_hdr_adi_adv_data;
ptr = (u8_t *)h + sizeof(*h); ptr = (u8_t *)h + sizeof(*h);
_ptr = ptr;
/* No ACAD and no AdvData */ /* No ACAD and no AdvData */
p->ext_hdr_len = 0; p->ext_hdr_len = 0;
p->adv_mode = evt_prop & 0x03; p->adv_mode = evt_prop & 0x03;
/* Zero-init header flags */ /* Zero-init header flags */
*(u8_t *)&_h = *(u8_t *)h;
*(u8_t *)h = 0; *(u8_t *)h = 0;
/* AdvA flag */ /* AdvA flag */
if (!(evt_prop & BIT(5)) && !p->adv_mode && (phy_p != BIT(2))) { if (_h.adv_addr) {
/* TODO: optional on 1M */ _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; h->adv_addr = 1;
/* NOTE: AdvA is filled at enable */ /* 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: 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 */ /* Tx Power flag */
if (evt_prop & BIT(6)) { if (evt_prop & BIT(6) &&
(!_h.aux_ptr || (phy_p != BIT(2)))) {
h->tx_pwr = 1; h->tx_pwr = 1;
ptr++; 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 */ /* 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 */ /* Tx Power */
if (h->tx_pwr) { if (h->tx_pwr) {
@ -215,11 +233,32 @@ u32_t ll_adv_params_set(u16_t interval, u8_t adv_type,
*ptr = _tx_pwr; *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 */ /* 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; 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 radio_adv_data *radio_adv_data;
struct pdu_adv *prev; 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 /* TODO: remember data, to be used if type is changed using
* parameter set function ll_adv_params_set afterwards. * parameter set function ll_adv_params_set afterwards.
*/ */
return; return 0;
} }
/* use the last index in double buffer, */ /* 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. */ /* commit the update so controller picks it. */
radio_adv_data->last = last; 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 radio_adv_data *radio_scan_data;
struct pdu_adv *prev; 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. */ /* commit the update so controller picks it. */
radio_scan_data->last = last; 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_scan_data;
struct radio_adv_data *radio_adv_data; struct radio_adv_data *radio_adv_data;
@ -341,7 +396,7 @@ u32_t ll_adv_enable(u8_t enable)
if (!enable) { if (!enable) {
return radio_adv_disable(); return radio_adv_disable();
} else if (ll_adv_is_enabled()) { } else if (ll_adv_is_enabled(0)) {
return 0; return 0;
} }
@ -411,6 +466,7 @@ u32_t ll_adv_enable(u8_t enable)
BDADDR_SIZE); BDADDR_SIZE);
} }
} }
#if defined(CONFIG_BT_CTLR_ADV_EXT) #if defined(CONFIG_BT_CTLR_ADV_EXT)
status = radio_adv_enable(ll_adv.phy_p, ll_adv.interval, status = radio_adv_enable(ll_adv.phy_p, ll_adv.interval,
ll_adv.chan_map, ll_adv.filter_policy, 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/util.h"
#include "util/mem.h" #include "util/mem.h"
#include "util/memq.h"
#include "pdu.h" #include "pdu.h"
#include "lll.h"
#include "ctrl.h" #include "ctrl.h"
#include "ll.h" #include "ll.h"
#include "ll_adv.h" #include "ll_adv.h"
@ -288,12 +290,12 @@ struct ll_filter *ctrl_filter_get(bool whitelist)
#endif #endif
} }
u32_t ll_wl_size_get(void) u8_t ll_wl_size_get(void)
{ {
return WL_SIZE; 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)) { if (radio_adv_filter_pol_get() || (radio_scan_filter_pol_get() & 0x1)) {
return BT_HCI_ERR_CMD_DISALLOWED; return BT_HCI_ERR_CMD_DISALLOWED;
@ -309,7 +311,7 @@ u32_t ll_wl_clear(void)
return 0; 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)) { if (radio_adv_filter_pol_get() || (radio_scan_filter_pol_get() & 0x1)) {
return BT_HCI_ERR_CMD_DISALLOWED; 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 */ #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)) { if (radio_adv_filter_pol_get() || (radio_scan_filter_pol_get() & 0x1)) {
return BT_HCI_ERR_CMD_DISALLOWED; return BT_HCI_ERR_CMD_DISALLOWED;
@ -396,7 +398,7 @@ void ll_filters_adv_update(u8_t adv_fp)
/* Clear before populating rl filter */ /* Clear before populating rl filter */
filter_clear(&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 */ /* rl not in use, update resolving list LUT */
filter_rl_update(); filter_rl_update();
} }
@ -416,7 +418,7 @@ void ll_filters_scan_update(u8_t scan_fp)
/* Clear before populating rl filter */ /* Clear before populating rl filter */
filter_clear(&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 */ /* rl not in use, update resolving list LUT */
filter_rl_update(); 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) void ll_rl_rpa_update(bool timeout)
@ -667,7 +669,7 @@ void ll_rl_rpa_update(bool timeout)
if (timeout) { if (timeout) {
#if defined(CONFIG_BT_BROADCASTER) #if defined(CONFIG_BT_BROADCASTER)
if (ll_adv_is_enabled()) { if (ll_adv_is_enabled(0)) {
rpa_adv_refresh(); rpa_adv_refresh();
} }
#endif #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; return CONFIG_BT_CTLR_RL_SIZE;
} }
u32_t ll_rl_clear(void) u8_t ll_rl_clear(void)
{ {
if (!rl_access_check(false)) { if (!rl_access_check(false)) {
return BT_HCI_ERR_CMD_DISALLOWED; return BT_HCI_ERR_CMD_DISALLOWED;
@ -724,7 +726,7 @@ u32_t ll_rl_clear(void)
return 0; 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]) const u8_t lirk[16])
{ {
u8_t i, j; 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; 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; 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; 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; 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; 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; 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)) { if (!rl_access_check(false)) {
return BT_HCI_ERR_CMD_DISALLOWED; return BT_HCI_ERR_CMD_DISALLOWED;
@ -893,7 +895,7 @@ void ll_rl_timeout_set(u16_t timeout)
rpa_timeout_ms = timeout * 1000; 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; u8_t i;

View file

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

View file

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

View file

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

View file

@ -11,7 +11,7 @@
* controller implementation. */ * controller implementation. */
#include <toolchain.h> #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 */ /* 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 * SPDX-License-Identifier: Apache-2.0
*/ */
#if defined(CONFIG_SOC_COMPATIBLE_NRF) #include "hal/nrf5/debug.h"
#include "nrf5/radio/radio_nrf5_txp.h"
#endif

View file

@ -24,10 +24,8 @@ static u8_t _refcount;
void cntr_init(void) void cntr_init(void)
{ {
NRF_RTC->PRESCALER = 0; NRF_RTC->PRESCALER = 0;
nrf_rtc_event_enable(NRF_RTC, RTC_EVTENSET_COMPARE0_Msk | nrf_rtc_event_enable(NRF_RTC, RTC_EVTENSET_COMPARE0_Msk);
RTC_EVTENSET_COMPARE1_Msk); nrf_rtc_int_enable(NRF_RTC, RTC_INTENSET_COMPARE0_Msk);
nrf_rtc_int_enable(NRF_RTC, RTC_INTENSET_COMPARE0_Msk |
RTC_INTENSET_COMPARE1_Msk);
} }
u32_t cntr_start(void) 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); LL_ASSERT(callee_id == MAYFLY_CALL_ID_JOB);
if (enable) { if (enable) {
irq_enable(SWI4_IRQn); irq_enable(SWI5_IRQn);
} else { } 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); return irq_is_enabled(RTC0_IRQn);
case MAYFLY_CALL_ID_JOB: case MAYFLY_CALL_ID_JOB:
return irq_is_enabled(SWI4_IRQn); return irq_is_enabled(SWI5_IRQn);
default: default:
LL_ASSERT(0); 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) 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) || 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) && ((caller_id == MAYFLY_CALL_ID_WORKER) &&
(callee_id == MAYFLY_CALL_ID_JOB)) || (callee_id == MAYFLY_CALL_ID_JOB)) ||
((caller_id == MAYFLY_CALL_ID_JOB) && ((caller_id == MAYFLY_CALL_ID_JOB) &&
(callee_id == MAYFLY_CALL_ID_WORKER)); (callee_id == MAYFLY_CALL_ID_WORKER)) ||
#else
/* TODO: check Kconfig set priorities */
return caller_id == callee_id;
#endif #endif
#endif
0;
} }
void mayfly_pend(u8_t caller_id, u8_t callee_id) 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; break;
case MAYFLY_CALL_ID_JOB: case MAYFLY_CALL_ID_JOB:
NVIC_SetPendingIRQ(SWI4_IRQn); NVIC_SetPendingIRQ(SWI5_IRQn);
break; break;
default: default:

View file

@ -29,18 +29,22 @@
#error "Platform not defined." #error "Platform not defined."
#endif #endif
static radio_isr_fp sfp_radio_isr; static radio_isr_cb_t isr_cb;
static void *isr_cb_param;
void isr_radio(void) void isr_radio(void)
{ {
if (sfp_radio_isr) { if (radio_has_disabled()) {
sfp_radio_isr(); 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 | nrf_radio_int_enable(0 |
/* RADIO_INTENSET_READY_Msk | /* RADIO_INTENSET_READY_Msk |
@ -768,6 +772,11 @@ u32_t radio_tmr_start_now(u8_t trx)
return start; return start;
} }
u32_t radio_tmr_start_get(void)
{
return nrf_rtc_cc_get(NRF_RTC0, 2);
}
void radio_tmr_stop(void) void radio_tmr_stop(void)
{ {
nrf_timer_task_trigger(EVENT_TIMER, NRF_TIMER_TASK_STOP); 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 #endif
#include "radio_nrf5_ppi.h" #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) /* TXEN->TXIDLE + TXIDLE->TX (with fast Radio ramp-up mode)
* in microseconds for LE CODED PHY [S2]. * 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 \ #define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S2_FAST_US \
HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S2_FAST_NS) HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S2_FAST_NS)
/* TXEN->TXIDLE + TXIDLE->TX (with default Radio ramp-up mode) /* TXEN->TXIDLE + TXIDLE->TX (with default Radio ramp-up mode)
* in microseconds for LE 2M PHY [S2]. * 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 \ #define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S2_DEFAULT_US \
HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S2_DEFAULT_NS) HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S2_DEFAULT_NS)
/* TXEN->TXIDLE + TXIDLE->TX (with default Radio ramp-up mode and /* TXEN->TXIDLE + TXIDLE->TX (with default Radio ramp-up mode and
* no HW TIFS auto-switch) in microseconds for LE 2M PHY [S2]. * no HW TIFS auto-switch) in microseconds for LE 2M PHY [S2].
*/ */
/* 129.5 + 3.0 */ /* 129.5 + 2.2 */
#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S2_DEFAULT_NO_HW_TIFS_NS 132500 #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 \ #define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S2_DEFAULT_NO_HW_TIFS_US \
HAL_RADIO_NS2US_ROUND( \ HAL_RADIO_NS2US_ROUND( \
HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S2_DEFAULT_NO_HW_TIFS_NS) 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) /* TXEN->TXIDLE + TXIDLE->TX (with fast Radio ramp-up mode)
* in microseconds for LE CODED PHY [S8]. * 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 \ #define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S8_FAST_US \
HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S8_FAST_NS) HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S8_FAST_NS)
/* TXEN->TXIDLE + TXIDLE->TX (with default Radio ramp-up mode) /* TXEN->TXIDLE + TXIDLE->TX (with default Radio ramp-up mode)
* in microseconds for LE 2M PHY [S8]. * 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 \ #define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S8_DEFAULT_US \
HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S8_DEFAULT_NS) HAL_RADIO_NS2US_ROUND(HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S8_DEFAULT_NS)
/* TXEN->TXIDLE + TXIDLE->TX (with default Radio ramp-up mode and /* TXEN->TXIDLE + TXIDLE->TX (with default Radio ramp-up mode and
* no HW TIFS auto-switch) in microseconds for LE 2M PHY [S8]. * no HW TIFS auto-switch) in microseconds for LE 2M PHY [S8].
*/ */
/* 129.5 + 3.0 */ /* 129.5 + 2.2 */
#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S8_DEFAULT_NO_HW_TIFS_NS 132500 #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 \ #define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S8_DEFAULT_NO_HW_TIFS_US \
HAL_RADIO_NS2US_ROUND( \ HAL_RADIO_NS2US_ROUND( \
HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_S8_DEFAULT_NO_HW_TIFS_NS) 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_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_US 20 /* ceil(19.6) */
#define HAL_RADIO_NRF52840_RX_CHAIN_DELAY_S2_NS 19600 /* 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_US 30 /* ceil(29.6) */
#define HAL_RADIO_NRF52840_RX_CHAIN_DELAY_S8_NS 29300 /* 29.6 - 0.3*/ #define HAL_RADIO_NRF52840_RX_CHAIN_DELAY_S8_NS 29600 /* 29.6 */
#if defined(CONFIG_BT_CTLR_RADIO_ENABLE_FAST) #if defined(CONFIG_BT_CTLR_RADIO_ENABLE_FAST)
#define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_1M_US \ #define HAL_RADIO_NRF52840_TXEN_TXIDLE_TX_1M_US \

View file

@ -5,13 +5,21 @@
* SPDX-License-Identifier: Apache-2.0 * 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. /* Macro to translate microseconds to tick units.
* NOTE: This returns the floor value. * NOTE: This returns the floor value.
*/ */
#define HAL_TICKER_US_TO_TICKS(x) \ #define HAL_TICKER_US_TO_TICKS(x) \
( \ ( \
((u32_t)(((u64_t) (x) * 1000000000UL) / 30517578125UL)) \ ((u32_t)(((u64_t) (x) * 1000000000UL) / 30517578125UL)) \
& 0x00FFFFFF \ & HAL_TICKER_CNTR_MASK \
) )
/* Macro returning remainder in nanoseconds */ /* Macro returning remainder in nanoseconds */
@ -29,4 +37,13 @@
((u32_t)(((u64_t)(x) * 30517578125UL) / 1000000000UL)) ((u32_t)(((u64_t)(x) * 30517578125UL) / 1000000000UL))
/* Macro defines the h/w supported most significant bit */ /* 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_PAYLOAD_SIZE_MAX 37
#define PDU_AC_SIZE_MAX (offsetof(struct pdu_adv, payload) + \ #define PDU_AC_SIZE_MAX (offsetof(struct pdu_adv, payload) + \
PDU_AC_PAYLOAD_SIZE_MAX) PDU_AC_PAYLOAD_SIZE_MAX)
#define PDU_DC_PAYLOAD_SIZE_MIN 27
#define PDU_EM_SIZE_MAX offsetof(struct pdu_data, lldata) #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 { struct pdu_adv_adv_ind {
u8_t addr[BDADDR_SIZE]; u8_t addr[BDADDR_SIZE];
u8_t data[31]; 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 * SPDX-License-Identifier: Apache-2.0
*/ */
#include <stdbool.h>
#include <zephyr/types.h> #include <zephyr/types.h>
#include <soc.h> #include <soc.h>
@ -21,7 +22,6 @@
* Defines * Defines
****************************************************************************/ ****************************************************************************/
#define DOUBLE_BUFFER_SIZE 2 #define DOUBLE_BUFFER_SIZE 2
#define COUNTER_CMP_OFFSET_MIN 3
/***************************************************************************** /*****************************************************************************
* Types * Types
@ -66,10 +66,10 @@ struct ticker_user_op_start {
}; };
struct ticker_user_op_update { struct ticker_user_op_update {
u16_t ticks_drift_plus; u32_t ticks_drift_plus;
u16_t ticks_drift_minus; u32_t ticks_drift_minus;
u16_t ticks_slot_plus; u32_t ticks_slot_plus;
u16_t ticks_slot_minus; u32_t ticks_slot_minus;
u16_t lazy; u16_t lazy;
u8_t force; u8_t force;
}; };
@ -124,7 +124,8 @@ struct ticker_instance {
/***************************************************************************** /*****************************************************************************
* Global instances * Global instances
****************************************************************************/ ****************************************************************************/
static struct ticker_instance _instance[2]; #define TICKER_INSTANCE_MAX 1
static struct ticker_instance _instance[TICKER_INSTANCE_MAX];
/***************************************************************************** /*****************************************************************************
* Static Functions * Static Functions
@ -384,7 +385,7 @@ void ticker_worker(void *param)
ticks_at_expire = (instance->ticks_current + ticks_at_expire = (instance->ticks_current +
ticks_expired - ticks_expired -
ticker->ticks_to_expire_minus) & ticker->ticks_to_expire_minus) &
0x00FFFFFF; HAL_TICKER_CNTR_MASK;
DEBUG_TICKER_TASK(1); DEBUG_TICKER_TASK(1);
ticker->timeout_func(ticks_at_expire, 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; u32_t ticks_to_expire_minus = ticker->ticks_to_expire_minus;
/* Calculate ticks to expire for this new node */ /* 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_to_expire += ticker_ticks_diff_get(ticks_at_start,
ticks_current); ticks_current);
} else { } 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) static u8_t ticker_remainder_inc(struct ticker_node *ticker)
{ {
#ifdef HAL_TICKER_REMAINDER_RANGE
ticker->remainder_current += ticker->remainder_periodic; ticker->remainder_current += ticker->remainder_periodic;
if ((ticker->remainder_current < BIT(31)) && if ((ticker->remainder_current < BIT(31)) &&
(ticker->remainder_current > (30517578UL / 2))) { (ticker->remainder_current > (HAL_TICKER_REMAINDER_RANGE >> 1))) {
ticker->remainder_current -= 30517578UL; ticker->remainder_current -= HAL_TICKER_REMAINDER_RANGE;
return 1; return 1;
} }
return 0; return 0;
#else
return 0;
#endif
} }
static u8_t ticker_remainder_dec(struct ticker_node *ticker) static u8_t ticker_remainder_dec(struct ticker_node *ticker)
{ {
#ifdef HAL_TICKER_REMAINDER_RANGE
u8_t decrement = 0U; u8_t decrement = 0U;
if ((ticker->remainder_current >= BIT(31)) || if ((ticker->remainder_current >= BIT(31)) ||
(ticker->remainder_current <= (30517578UL / 2))) { (ticker->remainder_current <= (HAL_TICKER_REMAINDER_RANGE >> 1))) {
decrement++; decrement++;
ticker->remainder_current += 30517578UL; ticker->remainder_current += HAL_TICKER_REMAINDER_RANGE;
} }
ticker->remainder_current -= ticker->remainder_periodic; ticker->remainder_current -= ticker->remainder_periodic;
return decrement; return decrement;
#else
return 0;
#endif
} }
static void ticker_job_op_cb(struct ticker_user_op *user_op, u32_t status) 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(); ctr = cntr_cnt_get();
cc = instance->ticks_current; cc = instance->ticks_current;
ticks_elapsed = ticker_ticks_diff_get(ctr, cc) + 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 += max(ticks_elapsed, ticks_to_expire);
cc &= 0x00FFFFFF; cc &= HAL_TICKER_CNTR_MASK;
instance->trigger_set_cb(cc); instance->trigger_set_cb(cc);
ctr_post = cntr_cnt_get(); ctr_post = cntr_cnt_get();
} while ((ticker_ticks_diff_get(ctr_post, ctr) + } 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) void ticker_job(void *param)
@ -1079,7 +1090,7 @@ void ticker_job(void *param)
instance->ticks_elapsed[instance->ticks_elapsed_first]; instance->ticks_elapsed[instance->ticks_elapsed_first];
instance->ticks_current += ticks_elapsed; instance->ticks_current += ticks_elapsed;
instance->ticks_current &= 0x00FFFFFF; instance->ticks_current &= HAL_TICKER_CNTR_MASK;
flag_elapsed = 1U; flag_elapsed = 1U;
} else { } 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) || if ((sizeof(struct ticker_node) != TICKER_NODE_T_SIZE) ||
(sizeof(struct ticker_user) != TICKER_USER_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; 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, 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, u32_t ticks_drift_plus, u32_t ticks_drift_minus,
u16_t ticks_slot_plus, u16_t ticks_slot_minus, u16_t lazy, 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) u8_t force, ticker_op_func fp_op_func, void *op_context)
{ {
struct ticker_instance *instance = &_instance[instance_index]; 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) 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_timeout_func fp_timeout_func, void *context,
ticker_op_func fp_op_func, void *op_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, 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, u32_t ticks_drift_plus, u32_t ticks_drift_minus,
u16_t ticks_slot_plus, u16_t ticks_slot_minus, u16_t lazy, 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); 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, 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); ticker_op_func fp_op_func, void *op_context);

View file

@ -5,7 +5,9 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
#include <stddef.h>
#include <zephyr/types.h> #include <zephyr/types.h>
#include <misc/printk.h>
#include "memq.h" #include "memq.h"
#include "mayfly.h" #include "mayfly.h"
@ -19,6 +21,11 @@ static struct {
} mft[MAYFLY_CALLEE_COUNT][MAYFLY_CALLER_COUNT]; } mft[MAYFLY_CALLEE_COUNT][MAYFLY_CALLER_COUNT];
static memq_link_t mfl[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) 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 */ /* mark as ready in queue */
m->_req = ack + 1; m->_req = ack + 1;
/* pend the callee for execution */ goto mayfly_enqueue_pend;
mayfly_pend(caller_id, callee_id);
return 0;
} }
/* already ready */ /* 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; m->_req = ack + 1;
memq_enqueue(m->_link, m, &mft[callee_id][caller_id].tail); 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 */ /* pend the callee for execution */
mayfly_pend(caller_id, callee_id); mayfly_pend(caller_id, callee_id);
return 0; 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) void mayfly_run(u8_t callee_id)
{ {
u8_t disable = 0U; u8_t disable = 0U;
u8_t enable = 0U; u8_t enable = 0U;
u8_t caller_id; u8_t caller_id;
if (!mfp[callee_id]) {
return;
}
mfp[callee_id] = 1;
/* iterate through each caller queue to this callee_id */ /* iterate through each caller queue to this callee_id */
caller_id = MAYFLY_CALLER_COUNT; caller_id = MAYFLY_CALLER_COUNT;
while (caller_id--) { while (caller_id--) {
@ -128,12 +188,18 @@ void mayfly_run(u8_t callee_id)
(void **)&m); (void **)&m);
while (link) { while (link) {
u8_t state; u8_t state;
u8_t req;
#if defined(CONFIG_MAYFLY_UT)
_state = 0;
#endif /* CONFIG_MAYFLY_UT */
/* execute work if ready */ /* execute work if ready */
req = m->_req; state = (m->_req - m->_ack) & 0x03;
state = (req - m->_ack) & 0x03;
if (state == 1) { if (state == 1) {
#if defined(CONFIG_MAYFLY_UT)
_state = 1;
#endif /* CONFIG_MAYFLY_UT */
/* mark mayfly as ran */ /* mark mayfly as ran */
m->_ack--; m->_ack--;
@ -142,18 +208,7 @@ void mayfly_run(u8_t callee_id)
} }
/* dequeue if not re-pended */ /* dequeue if not re-pended */
req = m->_req; dequeue(callee_id, caller_id, link, m);
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;
}
/* fetch next mayfly in callee queue, if any */ /* fetch next mayfly in callee queue, if any */
link = memq_peek(mft[callee_id][caller_id].head, 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); 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; 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) 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 */ /* 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; 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 *memq_init(memq_link_t *link, memq_link_t **head,
memq_link_t **tail); 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_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_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); 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> #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/memq.h"
#include "../controller/util/mayfly.h" #include "../controller/util/mayfly.h"
#include "../controller/hal/ticker.h"
#include "../controller/ticker/ticker.h" #include "../controller/ticker/ticker.h"
#if defined(CONFIG_BT_MAX_CONN) #if defined(CONFIG_BT_MAX_CONN)