Compare commits

...

28 Commits

Author SHA1 Message Date
Anas Nashif
ab35052b89 Zephyr 1.9.1
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2017-10-11 22:37:44 -04:00
Anas Nashif
b19f73de1d ci: compliance script should use python3
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2017-10-06 11:49:38 -04:00
Anas Nashif
be823dcffb ci: build commits, not only PR
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2017-10-06 11:49:38 -04:00
Anas Nashif
d7070b77eb doc: update release notes with ARC details
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2017-10-06 09:36:48 -04:00
Anas Nashif
d3831de32d doc: update release notes index with 1.9
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2017-10-06 09:36:48 -04:00
Jukka Rissanen
92ce3bc2d6 net: dns: Do not resolve IPv6 address if IPv6 is disabled
If IPv6 is disabled, then it is useless to try to resolve
IPv6 address because "struct sockaddr" does not have enough
space to store IPv6 address.

Fixes #1487

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2017-10-06 09:36:48 -04:00
Carles Cufi
b407d02637 Bluetooth: controller: Common config for VS extensions
Since the Zephyr HCI VS extensions apply to both the Host (using them
for additional functionality) and the Controller (implement the commands
and events), it make sense to make this a common setting in order for it
to be configurable in a way that applies to both.

Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
2017-10-03 19:30:03 -04:00
Carles Cufi
416945ae75 Bluetooth: controller: Disable PA/LNA for nRF51x
The PA/LNA feature is not functional on nRF51x series due to added
interrupt latency. Disable this feature unconditionally for those ICs to
avoid unexpected behavior.

Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
2017-10-03 19:30:03 -04:00
Vinayak Kariappa Chettimada
89689e0286 Bluetooth: controller: Fix HCI Reset hang
Issuing HCI reset command while having connections sometimes
hung the controller.

ll_reset supplied invalid stop ticker id to role_disable
when trying to stop all connections. Connection role does
not utilize stop ticker. The invalid ticker id supplied
referenced memory outside the pool of tickers and based on
what the content is in RAM there, the controller would hang
trying to stop connections.

Fixed by not calling the ticker_stop interface with invalid
ticker ids.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Vinayak Kariappa Chettimada
91f4c387ae Bluetooth: controller: GPIO PA/LNA feature
Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Carles Cufi
d2c4dbe6d7 Bluetooth: controller: Add PA/LNA GPIO Kconfig option
Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Carles Cufi
ec53508b06 Bluetooth: controller: Implement Read Build Info cmd
Implement the Read Build Information VS command. This returns a UTF-8
encoded string, which is extendable by the user via a new Kconfig
option.

Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Carles Cufi
7f65aa8f78 Bluetooth: controller: Implement Write BD_ADDR VS cmd
Implement the Zephyr VS command that allows a Host to write a public
Bluetooth Address to the Controller in order to allow Hosts to provide
their own public Bluetooth addresses.

Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Vinayak Kariappa Chettimada
705fb8ec26 Bluetooth: controller: Move tIFS s/w switch PPI index up by one
Move the use of tIFS software switching PPI index set up by
one position to make place for use of PA/LNA implementation.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Vinayak Kariappa Chettimada
d42bd89957 Bluetooth: controller: Use single PPI channel for AA capture
Earlier design captured AA twice in the first Rx in a slave
connection event and retained one of the capture until end
of event to calculate drift.

Design updated to use single capture of AA and save the
first AA capture in a slave connection event in RAM instead.

This frees up a PPI channel in the controller design.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Vinayak Kariappa Chettimada
eebdb3b693 Bluetooth: controller: Internal document purpose of end capture
Document internal the purposes of various Tx/Rx PDU end
capture setup.

Also, removed any redundant capture of packet end.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Vinayak Kariappa Chettimada
4d01527866 Bluetooth: controller: Minor refactor radio_tmr_start
Minor refactor of radio_tmr_start to reduced duplicate
assignments common in if-then-else control path.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Vinayak Kariappa Chettimada
60b37e46ca Bluetooth: controller: Map debug pins to P3 pin head on nRF5x DK
Updated debug pin mapping so that the outputs are on P3 pin
head on all nRF5x Development Kits.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Vinayak Kariappa Chettimada
7ee9fb5ced Bluetooth: controller: Add radio setup HAL interface
Added a new interface to perform setup of radio hardware.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Vinayak Kariappa Chettimada
2d08b180b5 Bluetooth: controller: Fix NRF_CCM config for 2M PHY
Fixed the configuration of NRF_CCM for 2M PHY connections.
Now faster 2M data rate mode will be used when a connection
is in 2M PHY.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Vinayak Kariappa Chettimada
8136c0913f Bluetooth: controller: Use correct NRF_AAR enable define
Use correct NRF_AAR enable macro defines from Nordic MDK.
Old code funtionally worked fine even though not setting
the correct enable value.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Vinayak Kariappa Chettimada
59d10ea93a Bluetooth: controller: Remove unreachable workaround code
A workaround code for nRF52840 under nRF51 conditional
compilation is removed.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Vinayak Kariappa Chettimada
c86b716481 Bluetooth: controller: Fix conn param req procedure timeout
Fixed a bug in the implementation of Connection Parameter
Request Procedure when initiated in master role caused the
connection to terminate with reason LL response timeout.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Carles Cufi
ef7a6c485f Bluetooth: controller: Fix handling of Read Static Addrs cmd
The status in the Command Complete event was uninitialized, leading to
incorrect contents of the event parsed by the Host. Correctly initialize
the status to success.

Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Vinayak Kariappa Chettimada
66817cbac9 Bluetooth: controller: Fix hang on directed adv timeout
During testing it was discovered that directed advertising
timeout is missing implementation to handle the timeout
happening while next event is already in preparation.
The consequence was that after the event ticker expired,
the counter is shutdown, stalling the setup PPI from
starting the erroneous advertising, leaving the controller
in an invalid hung state.

This has been fixed by correctly handling the cases, stop
between prepare and event, and stop inside radio advertising
event. The fix takes care of putting the radio active
callback and HF clock in the correct states.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Carles Cufi
543acefc43 samples: bluetooth: hci: Fix TX memory leak
Whenever a buffer is sent to the driver via bt_raw using bt_send() the
buffer might not be consumed if an error is returned. In that case
unreference the buffer to avoid leaking the already allocated net_buf.

Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Carles Cufi
f913f9b9f0 Bluetooth: controller: Issue Data Buffer Overflow event
Whenever the HCI ACL flow control is violated by the Host, a Data Buffer
Overflow event is now issued by the Controller (if enabled) to notify
the Host of the buffer overrun.

Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
2017-09-30 09:57:38 -04:00
Ricardo Salveti
3a4fb6e24e pwm: stm32: Fix check for APB prescale
RCC_HCLK_DIV1 translates to 0x0 while apb_psc uses the value defined
by CONFIG_CLOCK_STM32_APB1/2_PRESCALER (range from 1 to 16).

Manually check if the defined prescaler is 1 or not and use that to
calculate the correct timer clock.

Signed-off-by: Ricardo Salveti <ricardo.salveti@linaro.org>
2017-09-13 10:44:23 -05:00
23 changed files with 1204 additions and 255 deletions

View File

@@ -23,13 +23,16 @@ build:
- ${SHIPPABLE_BUILD_DIR}/ccache
pre_ci_boot:
image_name: zephyrprojectrtos/ci
image_tag: master.27
image_tag: v0.1
pull: true
options: "-e HOME=/home/buildslave --privileged=true --tty --net=bridge --user buildslave"
ci:
- export CCACHE_DIR=${SHIPPABLE_BUILD_DIR}/ccache/.ccache
- git rebase origin/${PULL_REQUEST_BASE_BRANCH}
- >
if [ "$IS_PULL_REQUEST" = "true" ]; then
git rebase origin/${PULL_REQUEST_BASE_BRANCH};
fi
- source zephyr-env.sh
- ccache -c -s --max-size=2000M
- make host-tools
@@ -54,19 +57,20 @@ build:
./scripts/ci/check-compliance.py --commits ${COMMIT_RANGE} || true;
fi;
- >
sudo pip3 install sh;
./scripts/ci/get_modified_tests.py --commits origin/${PULL_REQUEST_BASE_BRANCH}..HEAD > modified_tests.args;
./scripts/ci/get_modified_boards.py --commits origin/${PULL_REQUEST_BASE_BRANCH}..HEAD > modified_boards.args;
if [ "$IS_PULL_REQUEST" = "true" ]; then
./scripts/ci/get_modified_tests.py --commits origin/${PULL_REQUEST_BASE_BRANCH}..HEAD > modified_tests.args;
./scripts/ci/get_modified_boards.py --commits origin/${PULL_REQUEST_BASE_BRANCH}..HEAD > modified_boards.args;
if [ -s modified_boards.args ]; then
./scripts/sanitycheck --subset ${MATRIX_BUILD}/${MATRIX_BUILDS_EXTRA} +modified_boards.args || ./scripts/sanitycheck +modified_boards.args --only-failed;
cp ./scripts/sanity_chk/last_sanity.xml modified_boards.xml;
fi;
if [ -s modified_tests.args ]; then
./scripts/sanitycheck --subset ${MATRIX_BUILD}/${MATRIX_BUILDS_EXTRA} +modified_tests.args || ./scripts/sanitycheck +modified_tests.args --only-failed
cp ./scripts/sanity_chk/last_sanity.xml modified_tests.xml;
fi;
rm -f modified_tests.args modified_boards.args;
if [ -s modified_boards.args ]; then
./scripts/sanitycheck --subset ${MATRIX_BUILD}/${MATRIX_BUILDS_EXTRA} +modified_boards.args || ./scripts/sanitycheck +modified_boards.args --only-failed;
cp ./scripts/sanity_chk/last_sanity.xml modified_boards.xml;
fi;
if [ -s modified_tests.args ]; then
./scripts/sanitycheck --subset ${MATRIX_BUILD}/${MATRIX_BUILDS_EXTRA} +modified_tests.args || ./scripts/sanitycheck +modified_tests.args --only-failed;
cp ./scripts/sanity_chk/last_sanity.xml modified_tests.xml;
fi;
rm -f modified_tests.args modified_boards.args;
fi
- >
if [ "$MATRIX_BUILD" != "3" ]; then
./scripts/sanitycheck ${PLATFORMS} --subset ${MATRIX_BUILD}/${MATRIX_BUILDS} ${COVERAGE} ${SANITYCHECK_OPTIONS} || ./scripts/sanitycheck ${PLATFORMS} ${COVERAGE} ${SANITYCHECK_OPTIONS_RETRY} || ./scripts/sanitycheck ${PLATFORMS} ${COVERAGE} ${SANITYCHECK_OPTIONS_RETRY}

View File

@@ -1,6 +1,6 @@
VERSION_MAJOR = 1
VERSION_MINOR = 9
PATCHLEVEL = 0
PATCHLEVEL = 1
VERSION_RESERVED = 0
EXTRAVERSION =
NAME = Zephyr Kernel

View File

@@ -39,9 +39,11 @@ Architectures
* xtensa: Added ESP32 support
* Stack sentinel: This places a sentinel value at the lowest 4 bytes of a stack
memory region and checks it at various intervals, including when servicing
interrupts or context switching. This is implemented on all arches except
ARC, which supports stack bounds checking directly in hardware.
* x86: enable MMU for application memory
interrupts or context switching.
* x86: Enable MMU for application memory
* ARC: Added initial MPU support, including stack sentinel checking for ARC
configurations not featuring hardware stack bounds checking
* ARC: Nested interrupt support for normal, non-FIRQ interrupts
Boards
******
@@ -55,6 +57,9 @@ Boards
* arm: Removed TI CC3200 LaunchXL board
* arm: Added VBLUno51 and VBLUno52 boards
* xtensa: Added ESP32 board support
* ARC: Added support for EMSK EM7D v2.2 version (incl. MPU)
* ARC: Board configuration restructuring, peripheral configs moved from soc to
board level
Drivers and Sensors
*******************
@@ -338,3 +343,4 @@ JIRA Related Items
* :jira:`ZEP-2576` - samples/net/sockets/echo, echo_async : fails to send the TCP packets
* :jira:`ZEP-2581` - CC3220 executable binary format support
* :jira:`ZEP-2584` - Update mbedTLS to 2.6.0
* :jira:`ZEP-713` - Implement preemptible regular IRQs on ARC

View File

@@ -17,7 +17,7 @@ notes pages listed below), or use Git clone and checkout commands, such as:
git clone https://github.com/zephyrproject-rtos/zephyr
cd zephyr
git checkout tags/v1.8.0
git checkout tags/v1.9.0
The project's technical documentation is also tagged to correspond with a
@@ -29,6 +29,7 @@ Zephyr Kernel Releases
.. toctree::
:maxdepth: 1
release-notes-1.9
release-notes-1.8
release-notes-1.7
release-notes-1.6

View File

@@ -38,7 +38,13 @@ static u32_t __get_tim_clk(u32_t bus_clk,
apb_psc = CONFIG_CLOCK_STM32_APB2_PRESCALER;
}
if (apb_psc == RCC_HCLK_DIV1) {
/*
* If the APB prescaler equals 1, the timer clock frequencies
* are set to the same frequency as that of the APB domain.
* Otherwise, they are set to twice (×2) the frequency of the
* APB domain.
*/
if (apb_psc == 1) {
tim_clk = bus_clk;
} else {
tim_clk = 2 * bus_clk;

View File

@@ -1438,6 +1438,15 @@ struct bt_hci_evt_link_key_notify {
u8_t key_type;
} __packed;
/* Overflow link types */
#define BT_OVERFLOW_LINK_SYNCH 0x00
#define BT_OVERFLOW_LINK_ACL 0x01
#define BT_HCI_EVT_DATA_BUF_OVERFLOW 0x1a
struct bt_hci_evt_data_buf_overflow {
u8_t link_type;
} __packed;
#define BT_HCI_EVT_INQUIRY_RESULT_WITH_RSSI 0x22
struct bt_hci_evt_inquiry_result_with_rssi {
bt_addr_t addr;

View File

@@ -225,7 +225,12 @@ static void bt_tx_thread(void *p1, void *p2, void *p3)
SYS_LOG_DBG("buf %p type %u len %u",
buf, bt_buf_get_type(buf), buf->len);
bt_send(buf);
ret = bt_send(buf);
if (ret) {
SYS_LOG_ERR("Unable to send (ret %d)", ret);
net_buf_unref(buf);
}
STACK_ANALYZE("tx_stack", bt_tx_thread_stack);
/* Make sure other threads get a chance to run */

View File

@@ -232,11 +232,16 @@ static void tx_thread(void *p1, void *p2, void *p3)
{
while (1) {
struct net_buf *buf;
int err;
/* Wait until a buffer is available */
buf = net_buf_get(&tx_queue, K_FOREVER);
/* Pass buffer to the stack */
bt_send(buf);
err = bt_send(buf);
if (err) {
SYS_LOG_ERR("Unable to send (err %d)", err);
net_buf_unref(buf);
}
/* Give other threads a chance to run if tx_queue keeps getting
* new data all the time.

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import sys
import subprocess
import re

View File

@@ -8,6 +8,13 @@
if BT_HCI
config BT_HCI_VS_EXT
bool "Zephyr HCI Vendor-Specific Extensions"
default y
help
Enable support for the Zephyr HCI Vendor-Specific Extensions in the
Host and/or Controller.
config BT_RPA
# Virtual/hidden option
bool

View File

@@ -30,12 +30,16 @@ endchoice
comment "BLE Controller configuration"
config BT_CTLR_HCI_VS_EXT
bool "Zephyr HCI Vendor-Specific Extensions"
default y
config BT_CTLR_HCI_VS_BUILD_INFO
string "Zephyr HCI VS Build Info string"
default ""
depends on BT_HCI_VS_EXT
help
Enable support for the Zephyr HCI Vendor-Specific Extensions in the
Controller.
User-defined string that will be returned by the Zephyr VS Read Build
Information command after the Zephyr version and build time. When
setting this to a value different from an empty string, a space
character is required at the beginning to separate it from the
already included information.
config BT_CTLR_DUP_FILTER_LEN
prompt "Number of addresses in the scan duplicate filter"
@@ -386,6 +390,78 @@ config BT_CTLR_SCAN_REQ_RSSI
endmenu
comment "BLE Controller hardware configuration"
menuconfig BT_CTLR_GPIO_PA
bool "Power Amplifier GPIO interface"
depends on !SOC_SERIES_NRF51X
help
Enable GPIO interface to a Power Amplifier. This allows hardware
designs using PA to let the Controller toggle their state based on
radio activity.
if BT_CTLR_GPIO_PA
config BT_CTLR_GPIO_PA_PIN
prompt "Power Amplifier GPIO pin number"
int
help
GPIO Pin number connected to a Power Amplifier.
config BT_CTLR_GPIO_PA_POL_INV
bool "Inverted polarity for the PA pin"
help
Enable inverted polarity (active low) for the PA pin.
config BT_CTLR_GPIO_PA_OFFSET
prompt "Time from PA ON to Tx ready"
int
default 5
range 0 10
help
Time before Tx ready to turn on PA.
endif # BT_CTLR_GPIO_PA
menuconfig BT_CTLR_GPIO_LNA
bool "Low Noise Amplifier GPIO interface"
depends on !SOC_SERIES_NRF51X
help
Enable GPIO interface to a Low Noise Amplifier. This allows hardware
designs using LNAs to let the Controller toggle their state based on
radio activity.
if BT_CTLR_GPIO_LNA
config BT_CTLR_GPIO_LNA_PIN
prompt "Low Noise Amplifier GPIO pin number"
int
help
GPIO Pin number connected to a Low Noise Amplifier.
config BT_CTLR_GPIO_LNA_POL_INV
bool "Inverted polarity for the LNA pin"
help
Enable inverted polarity (active low) for the LNA pin.
config BT_CTLR_GPIO_LNA_OFFSET
prompt "Time from LNA ON to Rx ready"
int
default 5
range 0 10
help
Time before Rx ready to turn on LNA.
endif # BT_CTLR_GPIO_LNA
config BT_CTLR_PA_LNA_GPIOTE_CHAN
# Hidden "nRF5 GPIO PA/LNA GPIOTE Channel"
depends on SOC_FAMILY_NRF5 && (BT_CTLR_GPIO_PA || BT_CTLR_GPIO_LNA)
int
default 3
help
Select the nRF5 GPIOTE channel to use for PA/LNA GPIO feature.
comment "BLE Controller debug configuration"
config BT_CTLR_ASSERT_HANDLER
@@ -408,6 +484,7 @@ config BT_CTLR_PROFILE_ISR
config BT_CTLR_DEBUG_PINS
bool "Bluetooth Controller Debug Pins"
depends on BOARD_NRF51_PCA10028 || BOARD_NRF52_PCA10040 || BOARD_NRF52840_PCA10056
help
Turn on debug GPIO toggling for the BLE Controller. This is useful
when debugging with a logic analyzer or profiling certain sections of

View File

@@ -8,157 +8,202 @@
#ifndef _DEBUG_H_
#define _DEBUG_H_
#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)
#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.
*/
#ifdef CONFIG_BT_CTLR_DEBUG_PINS
#define DEBUG_INIT() do { \
NRF_GPIO->DIRSET = 0x03FF0000; \
NRF_GPIO->OUTCLR = 0x03FF0000; } \
DEBUG_PORT->DIRSET = DEBUG_PIN_MASK; \
DEBUG_PORT->OUTCLR = DEBUG_PIN_MASK; } \
while (0)
#define DEBUG_CPU_SLEEP(flag) do { \
if (flag) { \
NRF_GPIO->OUTSET = BIT(16); \
NRF_GPIO->OUTCLR = BIT(16); } \
DEBUG_PORT->OUTSET = DEBUG_PIN0; \
DEBUG_PORT->OUTCLR = DEBUG_PIN0; } \
else { \
NRF_GPIO->OUTCLR = BIT(16); \
NRF_GPIO->OUTSET = BIT(16); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN0; \
DEBUG_PORT->OUTSET = DEBUG_PIN0; } \
} while (0)
#define DEBUG_TICKER_ISR(flag) do { \
if (flag) { \
NRF_GPIO->OUTCLR = BIT(17); \
NRF_GPIO->OUTSET = BIT(17); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN1; \
DEBUG_PORT->OUTSET = DEBUG_PIN1; } \
else { \
NRF_GPIO->OUTSET = BIT(17); \
NRF_GPIO->OUTCLR = BIT(17); } \
DEBUG_PORT->OUTSET = DEBUG_PIN1; \
DEBUG_PORT->OUTCLR = DEBUG_PIN1; } \
} while (0)
#define DEBUG_TICKER_TASK(flag) do { \
if (flag) { \
NRF_GPIO->OUTCLR = BIT(17); \
NRF_GPIO->OUTSET = BIT(17); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN1; \
DEBUG_PORT->OUTSET = DEBUG_PIN1; } \
else { \
NRF_GPIO->OUTSET = BIT(17); \
NRF_GPIO->OUTCLR = BIT(17); } \
DEBUG_PORT->OUTSET = DEBUG_PIN1; \
DEBUG_PORT->OUTCLR = DEBUG_PIN1; } \
} while (0)
#define DEBUG_TICKER_JOB(flag) do { \
if (flag) { \
NRF_GPIO->OUTCLR = BIT(18); \
NRF_GPIO->OUTSET = BIT(18); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN2; \
DEBUG_PORT->OUTSET = DEBUG_PIN2; } \
else { \
NRF_GPIO->OUTSET = BIT(18); \
NRF_GPIO->OUTCLR = BIT(18); } \
DEBUG_PORT->OUTSET = DEBUG_PIN2; \
DEBUG_PORT->OUTCLR = DEBUG_PIN2; } \
} while (0)
#define DEBUG_RADIO_ISR(flag) do { \
if (flag) { \
NRF_GPIO->OUTCLR = BIT(23); \
NRF_GPIO->OUTSET = BIT(23); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN7; \
DEBUG_PORT->OUTSET = DEBUG_PIN7; } \
else { \
NRF_GPIO->OUTSET = BIT(23); \
NRF_GPIO->OUTCLR = BIT(23); } \
DEBUG_PORT->OUTSET = DEBUG_PIN7; \
DEBUG_PORT->OUTCLR = DEBUG_PIN7; } \
} while (0)
#define DEBUG_RADIO_XTAL(flag) do { \
if (flag) { \
NRF_GPIO->OUTCLR = BIT(24); \
NRF_GPIO->OUTSET = BIT(24); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN8; \
DEBUG_PORT->OUTSET = DEBUG_PIN8; } \
else { \
NRF_GPIO->OUTSET = BIT(24); \
NRF_GPIO->OUTCLR = BIT(24); } \
DEBUG_PORT->OUTSET = DEBUG_PIN8; \
DEBUG_PORT->OUTCLR = DEBUG_PIN8; } \
} while (0)
#define DEBUG_RADIO_ACTIVE(flag) do { \
if (flag) { \
NRF_GPIO->OUTCLR = BIT(25); \
NRF_GPIO->OUTSET = BIT(25); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN9; \
DEBUG_PORT->OUTSET = DEBUG_PIN9; } \
else { \
NRF_GPIO->OUTSET = BIT(25); \
NRF_GPIO->OUTCLR = BIT(25); } \
DEBUG_PORT->OUTSET = DEBUG_PIN9; \
DEBUG_PORT->OUTCLR = DEBUG_PIN9; } \
} while (0)
#define DEBUG_RADIO_CLOSE(flag) do { \
if (flag) { \
NRF_GPIO->OUTCLR = 0x00000000; \
NRF_GPIO->OUTSET = 0x00000000; } \
DEBUG_PORT->OUTCLR = 0x00000000; \
DEBUG_PORT->OUTSET = 0x00000000; } \
else { \
NRF_GPIO->OUTCLR = 0x00780000; } \
DEBUG_PORT->OUTCLR = DEBUG_CLOSE_MASK; } \
} while (0)
#define DEBUG_RADIO_PREPARE_A(flag) do { \
if (flag) { \
NRF_GPIO->OUTCLR = BIT(19); \
NRF_GPIO->OUTSET = BIT(19); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN3; \
DEBUG_PORT->OUTSET = DEBUG_PIN3; } \
else { \
NRF_GPIO->OUTCLR = BIT(19); \
NRF_GPIO->OUTSET = BIT(19); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN3; \
DEBUG_PORT->OUTSET = DEBUG_PIN3; } \
} while (0)
#define DEBUG_RADIO_START_A(flag) do { \
if (flag) { \
NRF_GPIO->OUTCLR = BIT(19); \
NRF_GPIO->OUTSET = BIT(19); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN3; \
DEBUG_PORT->OUTSET = DEBUG_PIN3; } \
else { \
NRF_GPIO->OUTCLR = BIT(19); \
NRF_GPIO->OUTSET = BIT(19); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN3; \
DEBUG_PORT->OUTSET = DEBUG_PIN3; } \
} while (0)
#define DEBUG_RADIO_PREPARE_S(flag) do { \
if (flag) { \
NRF_GPIO->OUTCLR = BIT(20); \
NRF_GPIO->OUTSET = BIT(20); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN4; \
DEBUG_PORT->OUTSET = DEBUG_PIN4; } \
else { \
NRF_GPIO->OUTCLR = BIT(20); \
NRF_GPIO->OUTSET = BIT(20); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN4; \
DEBUG_PORT->OUTSET = DEBUG_PIN4; } \
} while (0)
#define DEBUG_RADIO_START_S(flag) do { \
if (flag) { \
NRF_GPIO->OUTCLR = BIT(20); \
NRF_GPIO->OUTSET = BIT(20); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN4; \
DEBUG_PORT->OUTSET = DEBUG_PIN4; } \
else { \
NRF_GPIO->OUTCLR = BIT(20); \
NRF_GPIO->OUTSET = BIT(20); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN4; \
DEBUG_PORT->OUTSET = DEBUG_PIN4; } \
} while (0)
#define DEBUG_RADIO_PREPARE_O(flag) do { \
if (flag) { \
NRF_GPIO->OUTCLR = BIT(21); \
NRF_GPIO->OUTSET = BIT(21); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN5; \
DEBUG_PORT->OUTSET = DEBUG_PIN5; } \
else { \
NRF_GPIO->OUTCLR = BIT(21); \
NRF_GPIO->OUTSET = BIT(21); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN5; \
DEBUG_PORT->OUTSET = DEBUG_PIN5; } \
} while (0)
#define DEBUG_RADIO_START_O(flag) do { \
if (flag) { \
NRF_GPIO->OUTCLR = BIT(21); \
NRF_GPIO->OUTSET = BIT(21); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN5; \
DEBUG_PORT->OUTSET = DEBUG_PIN5; } \
else { \
NRF_GPIO->OUTCLR = BIT(21); \
NRF_GPIO->OUTSET = BIT(21); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN5; \
DEBUG_PORT->OUTSET = DEBUG_PIN5; } \
} while (0)
#define DEBUG_RADIO_PREPARE_M(flag) do { \
if (flag) { \
NRF_GPIO->OUTCLR = BIT(22); \
NRF_GPIO->OUTSET = BIT(22); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN6; \
DEBUG_PORT->OUTSET = DEBUG_PIN6; } \
else { \
NRF_GPIO->OUTCLR = BIT(22); \
NRF_GPIO->OUTSET = BIT(22); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN6; \
DEBUG_PORT->OUTSET = DEBUG_PIN6; } \
} while (0)
#define DEBUG_RADIO_START_M(flag) do { \
if (flag) { \
NRF_GPIO->OUTCLR = BIT(22); \
NRF_GPIO->OUTSET = BIT(22); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN6; \
DEBUG_PORT->OUTSET = DEBUG_PIN6; } \
else { \
NRF_GPIO->OUTCLR = BIT(22); \
NRF_GPIO->OUTSET = BIT(22); } \
DEBUG_PORT->OUTCLR = DEBUG_PIN6; \
DEBUG_PORT->OUTSET = DEBUG_PIN6; } \
} while (0)
#else

View File

@@ -48,6 +48,63 @@ void radio_isr_set(radio_isr_fp fp_radio_isr)
irq_enable(RADIO_IRQn);
}
void radio_setup(void)
{
#if defined(CONFIG_BT_CTLR_GPIO_PA_PIN)
NRF_GPIO->DIRSET = BIT(CONFIG_BT_CTLR_GPIO_PA_PIN);
#if defined(CONFIG_BT_CTLR_GPIO_PA_POL_INV)
NRF_GPIO->OUTSET = BIT(CONFIG_BT_CTLR_GPIO_PA_PIN);
#else
NRF_GPIO->OUTCLR = BIT(CONFIG_BT_CTLR_GPIO_PA_PIN);
#endif
#endif /* CONFIG_BT_CTLR_GPIO_PA_PIN */
#if defined(CONFIG_BT_CTLR_GPIO_LNA_PIN)
NRF_GPIO->DIRSET = BIT(CONFIG_BT_CTLR_GPIO_LNA_PIN);
radio_gpio_lna_off();
#endif /* CONFIG_BT_CTLR_GPIO_LNA_PIN */
#if defined(CONFIG_SOC_SERIES_NRF52X)
struct {
u32_t volatile reserved_0[0x5a0 >> 2];
u32_t volatile bridge_type;
u32_t volatile reserved_1[((0xe00 - 0x5a0) >> 2) - 1];
struct {
u32_t volatile CPU0;
u32_t volatile SPIS1;
u32_t volatile RADIO;
u32_t volatile ECB;
u32_t volatile CCM;
u32_t volatile AAR;
u32_t volatile SAADC;
u32_t volatile UARTE;
u32_t volatile SERIAL0;
u32_t volatile SERIAL2;
u32_t volatile NFCT;
u32_t volatile I2S;
u32_t volatile PDM;
u32_t volatile PWM;
} RAMPRI;
} volatile *NRF_AMLI = (void volatile *)0x40000000UL;
NRF_AMLI->RAMPRI.CPU0 = 0xFFFFFFFFUL;
NRF_AMLI->RAMPRI.SPIS1 = 0xFFFFFFFFUL;
NRF_AMLI->RAMPRI.RADIO = 0x00000000UL;
NRF_AMLI->RAMPRI.ECB = 0xFFFFFFFFUL;
NRF_AMLI->RAMPRI.CCM = 0x00000000UL;
NRF_AMLI->RAMPRI.AAR = 0xFFFFFFFFUL;
NRF_AMLI->RAMPRI.SAADC = 0xFFFFFFFFUL;
NRF_AMLI->RAMPRI.UARTE = 0xFFFFFFFFUL;
NRF_AMLI->RAMPRI.SERIAL0 = 0xFFFFFFFFUL;
NRF_AMLI->RAMPRI.SERIAL2 = 0xFFFFFFFFUL;
NRF_AMLI->RAMPRI.NFCT = 0xFFFFFFFFUL;
NRF_AMLI->RAMPRI.I2S = 0xFFFFFFFFUL;
NRF_AMLI->RAMPRI.PDM = 0xFFFFFFFFUL;
NRF_AMLI->RAMPRI.PWM = 0xFFFFFFFFUL;
#endif /* CONFIG_SOC_SERIES_NRF52X */
}
void radio_reset(void)
{
irq_disable(RADIO_IRQn);
@@ -78,11 +135,6 @@ void radio_phy_set(u8_t phy, u8_t flags)
#if defined(CONFIG_SOC_SERIES_NRF51X)
case BIT(1):
mode = RADIO_MODE_MODE_Nrf_2Mbit;
#if defined(CONFIG_SOC_NRF52840)
/* Workaround: nRF52840 Engineering A Errata ID 164 */
*(volatile u32_t *)0x4000173c &= ~0x80000000;
#endif /* CONFIG_SOC_NRF52840 */
break;
#elif defined(CONFIG_SOC_SERIES_NRF52X)
@@ -377,7 +429,7 @@ void radio_tx_enable(void)
void radio_disable(void)
{
#if !defined(CONFIG_BT_CTLR_TIFS_HW)
NRF_PPI->CHENCLR = PPI_CHEN_CH8_Msk | PPI_CHEN_CH11_Msk;
NRF_PPI->CHENCLR = PPI_CHEN_CH9_Msk | PPI_CHEN_CH12_Msk;
NRF_PPI->TASKS_CHG[0].DIS = 1;
NRF_PPI->TASKS_CHG[1].DIS = 1;
#endif /* !CONFIG_BT_CTLR_TIFS_HW */
@@ -452,13 +504,13 @@ static u8_t sw_tifs_toggle;
static void sw_switch(u8_t dir, u8_t phy_curr, u8_t flags_curr, u8_t phy_next,
u8_t flags_next)
{
u8_t ppi = 12 + sw_tifs_toggle;
u8_t ppi = 13 + sw_tifs_toggle;
u32_t delay;
NRF_TIMER1->EVENTS_COMPARE[sw_tifs_toggle] = 0;
NRF_PPI->CH[11].EEP = (u32_t)&(NRF_RADIO->EVENTS_END);
NRF_PPI->CH[11].TEP = (u32_t)&(NRF_PPI->TASKS_CHG[sw_tifs_toggle].EN);
NRF_PPI->CH[12].EEP = (u32_t)&(NRF_RADIO->EVENTS_END);
NRF_PPI->CH[12].TEP = (u32_t)&(NRF_PPI->TASKS_CHG[sw_tifs_toggle].EN);
NRF_PPI->CH[ppi].EEP = (u32_t)
&(NRF_TIMER1->EVENTS_COMPARE[sw_tifs_toggle]);
@@ -481,7 +533,7 @@ static void sw_switch(u8_t dir, u8_t phy_curr, u8_t flags_curr, u8_t phy_next,
NRF_TIMER1->CC[sw_tifs_toggle] = 1;
}
NRF_PPI->CHENSET = PPI_CHEN_CH8_Msk | PPI_CHEN_CH11_Msk;
NRF_PPI->CHENSET = PPI_CHEN_CH9_Msk | PPI_CHEN_CH12_Msk;
sw_tifs_toggle += 1;
sw_tifs_toggle &= 1;
@@ -521,7 +573,7 @@ void radio_switch_complete_and_disable(void)
(RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk);
#if !defined(CONFIG_BT_CTLR_TIFS_HW)
NRF_PPI->CHENCLR = PPI_CHEN_CH8_Msk | PPI_CHEN_CH11_Msk;
NRF_PPI->CHENCLR = PPI_CHEN_CH9_Msk | PPI_CHEN_CH12_Msk;
#endif /* !CONFIG_BT_CTLR_TIFS_HW */
}
@@ -607,7 +659,7 @@ void radio_tmr_status_reset(void)
NRF_PPI->CHENCLR =
(PPI_CHEN_CH0_Msk | PPI_CHEN_CH1_Msk | PPI_CHEN_CH2_Msk |
PPI_CHEN_CH3_Msk | PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk |
PPI_CHEN_CH6_Msk | PPI_CHEN_CH7_Msk);
PPI_CHEN_CH6_Msk);
}
void radio_tmr_tifs_set(u32_t tifs)
@@ -643,19 +695,10 @@ u32_t radio_tmr_start(u8_t trx, u32_t ticks_start, u32_t remainder)
NRF_PPI->CH[1].TEP = (u32_t)&(NRF_TIMER0->TASKS_START);
NRF_PPI->CHENSET = PPI_CHEN_CH1_Msk;
if (trx) {
NRF_PPI->CH[0].EEP =
(u32_t)&(NRF_TIMER0->EVENTS_COMPARE[0]);
NRF_PPI->CH[0].TEP =
(u32_t)&(NRF_RADIO->TASKS_TXEN);
NRF_PPI->CHENSET = PPI_CHEN_CH0_Msk;
} else {
NRF_PPI->CH[0].EEP =
(u32_t)&(NRF_TIMER0->EVENTS_COMPARE[0]);
NRF_PPI->CH[0].TEP =
(u32_t)&(NRF_RADIO->TASKS_RXEN);
NRF_PPI->CHENSET = PPI_CHEN_CH0_Msk;
}
NRF_PPI->CH[0].EEP = (u32_t)&(NRF_TIMER0->EVENTS_COMPARE[0]);
NRF_PPI->CH[0].TEP = (trx) ? (u32_t)&(NRF_RADIO->TASKS_TXEN) :
(u32_t)&(NRF_RADIO->TASKS_RXEN);
NRF_PPI->CHENSET = PPI_CHEN_CH0_Msk;
#if !defined(CONFIG_BT_CTLR_TIFS_HW)
NRF_TIMER1->TASKS_CLEAR = 1;
@@ -664,19 +707,17 @@ u32_t radio_tmr_start(u8_t trx, u32_t ticks_start, u32_t remainder)
NRF_TIMER1->BITMODE = 0; /* 16 bit */
NRF_TIMER1->TASKS_START = 1;
NRF_PPI->CH[8].EEP = (u32_t)&(NRF_RADIO->EVENTS_END);
NRF_PPI->CH[8].TEP = (u32_t)&(NRF_TIMER1->TASKS_CLEAR);
NRF_PPI->CH[9].EEP = (u32_t)&(NRF_RADIO->EVENTS_END);
NRF_PPI->CH[9].TEP = (u32_t)&(NRF_TIMER1->TASKS_CLEAR);
NRF_PPI->CH[9].EEP = (u32_t)
&(NRF_TIMER1->EVENTS_COMPARE[0]);
NRF_PPI->CH[9].TEP = (u32_t)&(NRF_PPI->TASKS_CHG[0].DIS);
NRF_PPI->CH[10].EEP = (u32_t)&(NRF_TIMER1->EVENTS_COMPARE[0]);
NRF_PPI->CH[10].TEP = (u32_t)&(NRF_PPI->TASKS_CHG[0].DIS);
NRF_PPI->CH[10].EEP = (u32_t)
&(NRF_TIMER1->EVENTS_COMPARE[1]);
NRF_PPI->CH[10].TEP = (u32_t)&(NRF_PPI->TASKS_CHG[1].DIS);
NRF_PPI->CH[11].EEP = (u32_t)&(NRF_TIMER1->EVENTS_COMPARE[1]);
NRF_PPI->CH[11].TEP = (u32_t)&(NRF_PPI->TASKS_CHG[1].DIS);
NRF_PPI->CHG[0] = PPI_CHG_CH9_Msk | PPI_CHG_CH12_Msk;
NRF_PPI->CHG[1] = PPI_CHG_CH10_Msk | PPI_CHG_CH13_Msk;
NRF_PPI->CHG[0] = PPI_CHG_CH10_Msk | PPI_CHG_CH13_Msk;
NRF_PPI->CHG[1] = PPI_CHG_CH11_Msk | PPI_CHG_CH14_Msk;
#endif /* !CONFIG_BT_CTLR_TIFS_HW */
return remainder;
@@ -684,21 +725,45 @@ 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)
{
if (trx) {
NRF_PPI->CH[0].EEP =
(u32_t)&(NRF_TIMER0->EVENTS_COMPARE[0]);
NRF_PPI->CH[0].TEP =
(u32_t)&(NRF_RADIO->TASKS_TXEN);
} else {
NRF_PPI->CH[0].EEP =
(u32_t)&(NRF_TIMER0->EVENTS_COMPARE[0]);
NRF_PPI->CH[0].TEP =
(u32_t)&(NRF_RADIO->TASKS_RXEN);
}
NRF_PPI->CHENSET = PPI_CHEN_CH0_Msk;
NRF_TIMER0->CC[0] = us;
NRF_TIMER0->EVENTS_COMPARE[0] = 0;
NRF_PPI->CH[0].EEP = (u32_t)&(NRF_TIMER0->EVENTS_COMPARE[0]);
NRF_PPI->CH[0].TEP = (trx) ? (u32_t)&(NRF_RADIO->TASKS_TXEN) :
(u32_t)&(NRF_RADIO->TASKS_RXEN);
NRF_PPI->CHENSET = PPI_CHEN_CH0_Msk;
}
u32_t radio_tmr_start_now(u8_t trx)
{
u32_t now, start;
/* Setup PPI for Radio start */
NRF_PPI->CH[0].EEP = (u32_t)&(NRF_TIMER0->EVENTS_COMPARE[0]);
NRF_PPI->CH[0].TEP = (trx) ? (u32_t)&(NRF_RADIO->TASKS_TXEN) :
(u32_t)&(NRF_RADIO->TASKS_RXEN);
NRF_PPI->CHENSET = PPI_CHEN_CH0_Msk;
/* Capture the current time */
NRF_TIMER0->TASKS_CAPTURE[1] = 1;
now = NRF_TIMER0->CC[1];
start = now;
/* Setup PPI while determining the latency in doing so */
do {
/* Set start to be, now plus the determined latency */
start = (now << 1) - start;
/* Setup compare event with min. 1 us offset */
NRF_TIMER0->CC[0] = start + 1;
NRF_TIMER0->EVENTS_COMPARE[0] = 0;
/* Capture the current time */
NRF_TIMER0->TASKS_CAPTURE[1] = 1;
now = NRF_TIMER0->CC[1];
} while (now > start);
return start;
}
void radio_tmr_stop(void)
@@ -714,14 +779,14 @@ void radio_tmr_stop(void)
void radio_tmr_hcto_configure(u32_t hcto)
{
NRF_TIMER0->CC[2] = hcto;
NRF_TIMER0->EVENTS_COMPARE[2] = 0;
NRF_TIMER0->CC[1] = hcto;
NRF_TIMER0->EVENTS_COMPARE[1] = 0;
NRF_PPI->CH[4].EEP = (u32_t)&(NRF_RADIO->EVENTS_ADDRESS);
NRF_PPI->CH[4].TEP = (u32_t)&(NRF_TIMER0->TASKS_CAPTURE[2]);
NRF_PPI->CH[5].EEP = (u32_t)&(NRF_TIMER0->EVENTS_COMPARE[2]);
NRF_PPI->CH[5].TEP = (u32_t)&(NRF_RADIO->TASKS_DISABLE);
NRF_PPI->CHENSET = (PPI_CHEN_CH4_Msk | PPI_CHEN_CH5_Msk);
NRF_PPI->CH[3].EEP = (u32_t)&(NRF_RADIO->EVENTS_ADDRESS);
NRF_PPI->CH[3].TEP = (u32_t)&(NRF_TIMER0->TASKS_CAPTURE[1]);
NRF_PPI->CH[4].EEP = (u32_t)&(NRF_TIMER0->EVENTS_COMPARE[1]);
NRF_PPI->CH[4].TEP = (u32_t)&(NRF_RADIO->TASKS_DISABLE);
NRF_PPI->CHENSET = (PPI_CHEN_CH3_Msk | PPI_CHEN_CH4_Msk);
}
void radio_tmr_aa_capture(void)
@@ -733,21 +798,34 @@ void radio_tmr_aa_capture(void)
NRF_PPI->CHENSET = (PPI_CHEN_CH2_Msk | PPI_CHEN_CH3_Msk);
}
u32_t radio_tmr_aa_get(void)
{
return NRF_TIMER0->CC[1];
}
static u32_t radio_tmr_aa;
void radio_tmr_aa_save(u32_t aa)
{
radio_tmr_aa = aa;
}
u32_t radio_tmr_aa_restore(void)
{
/* NOTE: we dont need to restore for now, but return the saved value. */
return radio_tmr_aa;
}
u32_t radio_tmr_ready_get(void)
{
return NRF_TIMER0->CC[0];
}
u32_t radio_tmr_aa_get(void)
{
return (NRF_TIMER0->CC[1] - NRF_TIMER0->CC[0]);
}
void radio_tmr_end_capture(void)
{
NRF_PPI->CH[7].EEP = (u32_t)&(NRF_RADIO->EVENTS_END);
NRF_PPI->CH[7].TEP = (u32_t)&(NRF_TIMER0->TASKS_CAPTURE[2]);
NRF_PPI->CHENSET = PPI_CHEN_CH7_Msk;
NRF_PPI->CH[5].EEP = (u32_t)&(NRF_RADIO->EVENTS_END);
NRF_PPI->CH[5].TEP = (u32_t)&(NRF_TIMER0->TASKS_CAPTURE[2]);
NRF_PPI->CHENSET = PPI_CHEN_CH5_Msk;
}
u32_t radio_tmr_end_get(void)
@@ -765,19 +843,122 @@ u32_t radio_tmr_sample_get(void)
return NRF_TIMER0->CC[3];
}
#if defined(CONFIG_BT_CTLR_GPIO_PA_PIN) || \
defined(CONFIG_BT_CTLR_GPIO_LNA_PIN)
#if defined(CONFIG_BT_CTLR_GPIO_PA_PIN)
void radio_gpio_pa_setup(void)
{
NRF_GPIOTE->CONFIG[CONFIG_BT_CTLR_PA_LNA_GPIOTE_CHAN] =
(GPIOTE_CONFIG_MODE_Task <<
GPIOTE_CONFIG_MODE_Pos) |
(CONFIG_BT_CTLR_GPIO_PA_PIN <<
GPIOTE_CONFIG_PSEL_Pos) |
(GPIOTE_CONFIG_POLARITY_Toggle <<
GPIOTE_CONFIG_POLARITY_Pos) |
#if defined(CONFIG_BT_CTLR_GPIO_PA_POL_INV)
(GPIOTE_CONFIG_OUTINIT_High <<
GPIOTE_CONFIG_OUTINIT_Pos);
#else
(GPIOTE_CONFIG_OUTINIT_Low <<
GPIOTE_CONFIG_OUTINIT_Pos);
#endif
}
#endif /* CONFIG_BT_CTLR_GPIO_PA_PIN */
#if defined(CONFIG_BT_CTLR_GPIO_LNA_PIN)
void radio_gpio_lna_setup(void)
{
NRF_GPIOTE->CONFIG[CONFIG_BT_CTLR_PA_LNA_GPIOTE_CHAN] =
(GPIOTE_CONFIG_MODE_Task <<
GPIOTE_CONFIG_MODE_Pos) |
(CONFIG_BT_CTLR_GPIO_LNA_PIN <<
GPIOTE_CONFIG_PSEL_Pos) |
(GPIOTE_CONFIG_POLARITY_Toggle <<
GPIOTE_CONFIG_POLARITY_Pos) |
#if defined(CONFIG_BT_CTLR_GPIO_LNA_POL_INV)
(GPIOTE_CONFIG_OUTINIT_High <<
GPIOTE_CONFIG_OUTINIT_Pos);
#else
(GPIOTE_CONFIG_OUTINIT_Low <<
GPIOTE_CONFIG_OUTINIT_Pos);
#endif
}
void radio_gpio_lna_on(void)
{
#if defined(CONFIG_BT_CTLR_GPIO_LNA_POL_INV)
NRF_GPIO->OUTCLR = BIT(CONFIG_BT_CTLR_GPIO_LNA_PIN);
#else
NRF_GPIO->OUTSET = BIT(CONFIG_BT_CTLR_GPIO_LNA_PIN);
#endif
}
void radio_gpio_lna_off(void)
{
#if defined(CONFIG_BT_CTLR_GPIO_LNA_POL_INV)
NRF_GPIO->OUTSET = BIT(CONFIG_BT_CTLR_GPIO_LNA_PIN);
#else
NRF_GPIO->OUTCLR = BIT(CONFIG_BT_CTLR_GPIO_LNA_PIN);
#endif
}
#endif /* CONFIG_BT_CTLR_GPIO_LNA_PIN */
void radio_gpio_pa_lna_enable(u32_t trx_us)
{
NRF_TIMER0->CC[2] = trx_us;
NRF_TIMER0->EVENTS_COMPARE[2] = 0;
NRF_PPI->CH[7].EEP = (u32_t)&(NRF_TIMER0->EVENTS_COMPARE[2]);
NRF_PPI->CH[7].TEP = (u32_t)
&(NRF_GPIOTE->TASKS_OUT[CONFIG_BT_CTLR_PA_LNA_GPIOTE_CHAN]);
NRF_PPI->CH[8].EEP = (u32_t)&(NRF_RADIO->EVENTS_DISABLED);
NRF_PPI->CH[8].TEP = (u32_t)
&(NRF_GPIOTE->TASKS_OUT[CONFIG_BT_CTLR_PA_LNA_GPIOTE_CHAN]);
NRF_PPI->CHENSET = PPI_CHEN_CH7_Msk | PPI_CHEN_CH8_Msk;
}
void radio_gpio_pa_lna_disable(void)
{
NRF_PPI->CHENCLR = PPI_CHEN_CH7_Msk | PPI_CHEN_CH8_Msk;
}
#endif /* CONFIG_BT_CTLR_GPIO_PA_PIN || CONFIG_BT_CTLR_GPIO_LNA_PIN */
static u8_t MALIGN(4) _ccm_scratch[(RADIO_PDU_LEN_MAX - 4) + 16];
void *radio_ccm_rx_pkt_set(struct ccm *ccm, void *pkt)
{
u32_t mode;
NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Disabled;
NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Enabled;
NRF_CCM->MODE =
#if !defined(CONFIG_SOC_SERIES_NRF51X)
((CCM_MODE_LENGTH_Extended << CCM_MODE_LENGTH_Pos) &
CCM_MODE_LENGTH_Msk) |
mode = (CCM_MODE_MODE_Decryption << CCM_MODE_MODE_Pos) &
CCM_MODE_MODE_Msk;
#if defined(CONFIG_SOC_SERIES_NRF52X)
/* Enable CCM support for 8-bit length field PDUs. */
mode |= (CCM_MODE_LENGTH_Extended << CCM_MODE_LENGTH_Pos) &
CCM_MODE_LENGTH_Msk;
/* Select CCM data rate based on current PHY in use. */
/* TODO: add cases for nRF52840's coded PHY */
switch ((NRF_RADIO->MODE & RADIO_MODE_MODE_Msk) >>
RADIO_MODE_MODE_Pos) {
default:
case RADIO_MODE_MODE_Ble_1Mbit:
mode |= (CCM_MODE_DATARATE_1Mbit <<
CCM_MODE_DATARATE_Pos) &
CCM_MODE_DATARATE_Msk;
break;
case RADIO_MODE_MODE_Ble_2Mbit:
mode |= (CCM_MODE_DATARATE_2Mbit <<
CCM_MODE_DATARATE_Pos) &
CCM_MODE_DATARATE_Msk;
break;
}
#endif
((CCM_MODE_MODE_Decryption << CCM_MODE_MODE_Pos) &
CCM_MODE_MODE_Msk);
NRF_CCM->MODE = mode;
NRF_CCM->CNFPTR = (u32_t)ccm;
NRF_CCM->INPTR = (u32_t)_pkt_scratch;
NRF_CCM->OUTPTR = (u32_t)pkt;
@@ -798,15 +979,24 @@ void *radio_ccm_rx_pkt_set(struct ccm *ccm, void *pkt)
void *radio_ccm_tx_pkt_set(struct ccm *ccm, void *pkt)
{
u32_t mode;
NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Disabled;
NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Enabled;
NRF_CCM->MODE =
#if !defined(CONFIG_SOC_SERIES_NRF51X)
((CCM_MODE_LENGTH_Extended << CCM_MODE_LENGTH_Pos) &
CCM_MODE_LENGTH_Msk) |
mode = (CCM_MODE_MODE_Encryption << CCM_MODE_MODE_Pos) &
CCM_MODE_MODE_Msk;
#if defined(CONFIG_SOC_SERIES_NRF52X)
/* Enable CCM support for 8-bit length field PDUs. */
mode |= (CCM_MODE_LENGTH_Extended << CCM_MODE_LENGTH_Pos) &
CCM_MODE_LENGTH_Msk;
/* NOTE: use fastest data rate as tx data needs to be prepared before
* radio Tx on any PHY.
*/
mode |= (CCM_MODE_DATARATE_2Mbit << CCM_MODE_DATARATE_Pos) &
CCM_MODE_DATARATE_Msk;
#endif
((CCM_MODE_MODE_Encryption << CCM_MODE_MODE_Pos) &
CCM_MODE_MODE_Msk);
NRF_CCM->MODE = mode;
NRF_CCM->CNFPTR = (u32_t)ccm;
NRF_CCM->INPTR = (u32_t)pkt;
NRF_CCM->OUTPTR = (u32_t)_pkt_scratch;
@@ -844,7 +1034,8 @@ static u8_t MALIGN(4) _aar_scratch[3];
void radio_ar_configure(u32_t nirk, void *irk)
{
NRF_AAR->ENABLE = 1;
NRF_AAR->ENABLE = (AAR_ENABLE_ENABLE_Enabled << AAR_ENABLE_ENABLE_Pos) &
AAR_ENABLE_ENABLE_Msk;
NRF_AAR->NIRK = nirk;
NRF_AAR->IRKPTR = (u32_t)irk;
NRF_AAR->ADDRPTR = (u32_t)NRF_RADIO->PACKETPTR - 1;

View File

@@ -13,6 +13,7 @@ typedef void (*radio_isr_fp) (void);
void isr_radio(void);
void radio_isr_set(radio_isr_fp fp_radio_isr);
void radio_setup(void);
void radio_reset(void);
void radio_phy_set(u8_t phy, u8_t flags);
void radio_tx_power_set(u32_t power);
@@ -67,16 +68,26 @@ 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_ready_get(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);
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, void *pkt);
void *radio_ccm_tx_pkt_set(struct ccm *ccm, void *pkt);
u32_t radio_ccm_is_done(void);

View File

@@ -1673,10 +1673,12 @@ static void vs_read_supported_commands(struct net_buf *buf,
/* Set Version Information, Supported Commands, Supported Features. */
rp->commands[0] |= BIT(0) | BIT(1) | BIT(2);
#if defined(CONFIG_BT_CTLR_HCI_VS_EXT)
#if defined(CONFIG_BT_HCI_VS_EXT)
/* Write BD_ADDR, Read Build Info */
rp->commands[0] |= BIT(5) | BIT(7);
/* Read Static Addresses, Read Key Hierarchy Roots */
rp->commands[1] |= BIT(0) | BIT(1);
#endif /* CONFIG_BT_CTLR_HCI_VS_EXT */
#endif /* CONFIG_BT_HCI_VS_EXT */
}
static void vs_read_supported_features(struct net_buf *buf,
@@ -1690,7 +1692,41 @@ static void vs_read_supported_features(struct net_buf *buf,
memset(&rp->features[0], 0x00, sizeof(rp->features));
}
#if defined(CONFIG_BT_CTLR_HCI_VS_EXT)
#if defined(CONFIG_BT_HCI_VS_EXT)
static void vs_write_bd_addr(struct net_buf *buf, struct net_buf **evt)
{
struct bt_hci_cp_vs_write_bd_addr *cmd = (void *)buf->data;
struct bt_hci_evt_cc_status *ccst;
ll_addr_set(0, &cmd->bdaddr.val[0]);
ccst = cmd_complete(evt, sizeof(*ccst));
ccst->status = 0x00;
}
static void vs_read_build_info(struct net_buf *buf, struct net_buf **evt)
{
struct bt_hci_rp_vs_read_build_info *rp;
#define BUILD_TIMESTAMP " " __DATE__ " " __TIME__
#define HCI_VS_BUILD_INFO "Zephyr OS v" \
KERNEL_VERSION_STRING BUILD_TIMESTAMP CONFIG_BT_CTLR_HCI_VS_BUILD_INFO
const char build_info[] = HCI_VS_BUILD_INFO;
#define BUILD_INFO_EVT_LEN (sizeof(struct bt_hci_evt_hdr) + \
sizeof(struct bt_hci_evt_cmd_complete) + \
sizeof(struct bt_hci_rp_vs_read_build_info) + \
sizeof(build_info))
BUILD_ASSERT(CONFIG_BT_RX_BUF_LEN >= BUILD_INFO_EVT_LEN);
rp = cmd_complete(evt, sizeof(*rp) + sizeof(build_info));
rp->status = 0x00;
memcpy(rp->info, build_info, sizeof(build_info));
}
static void vs_read_static_addrs(struct net_buf *buf, struct net_buf **evt)
{
struct bt_hci_rp_vs_read_static_addrs *rp;
@@ -1707,6 +1743,7 @@ static void vs_read_static_addrs(struct net_buf *buf, struct net_buf **evt)
struct bt_hci_vs_static_addr *addr;
rp = cmd_complete(evt, sizeof(*rp) + sizeof(*addr));
rp->status = 0x00;
rp->num_addrs = 1;
addr = &rp->a[0];
@@ -1776,7 +1813,7 @@ static void vs_read_key_hierarchy_roots(struct net_buf *buf,
#endif /* CONFIG_SOC_FAMILY_NRF5 */
}
#endif /* CONFIG_BT_CTLR_HCI_VS_EXT */
#endif /* CONFIG_BT_HCI_VS_EXT */
static int vendor_cmd_handle(u16_t ocf, struct net_buf *cmd,
struct net_buf **evt)
@@ -1794,7 +1831,15 @@ static int vendor_cmd_handle(u16_t ocf, struct net_buf *cmd,
vs_read_supported_features(cmd, evt);
break;
#if defined(CONFIG_BT_CTLR_HCI_VS_EXT)
#if defined(CONFIG_BT_HCI_VS_EXT)
case BT_OCF(BT_HCI_OP_VS_READ_BUILD_INFO):
vs_read_build_info(cmd, evt);
break;
case BT_OCF(BT_HCI_OP_VS_WRITE_BD_ADDR):
vs_write_bd_addr(cmd, evt);
break;
case BT_OCF(BT_HCI_OP_VS_READ_STATIC_ADDRS):
vs_read_static_addrs(cmd, evt);
break;
@@ -1802,7 +1847,7 @@ static int vendor_cmd_handle(u16_t ocf, struct net_buf *cmd,
case BT_OCF(BT_HCI_OP_VS_READ_KEY_HIERARCHY_ROOTS):
vs_read_key_hierarchy_roots(cmd, evt);
break;
#endif /* CONFIG_BT_CTLR_HCI_VS_EXT */
#endif /* CONFIG_BT_HCI_VS_EXT */
default:
return -EINVAL;
@@ -1811,6 +1856,21 @@ static int vendor_cmd_handle(u16_t ocf, struct net_buf *cmd,
return 0;
}
static void data_buf_overflow(struct net_buf **buf)
{
struct bt_hci_evt_data_buf_overflow *ep;
if (!(event_mask & BT_EVT_MASK_DATA_BUFFER_OVERFLOW)) {
return;
}
*buf = bt_buf_get_rx(BT_BUF_EVT, K_FOREVER);
evt_create(*buf, BT_HCI_EVT_DATA_BUF_OVERFLOW, sizeof(*ep));
ep = net_buf_add(*buf, sizeof(*ep));
ep->link_type = BT_OVERFLOW_LINK_ACL;
}
struct net_buf *hci_cmd_handle(struct net_buf *cmd)
{
struct bt_hci_evt_cc_status *ccst;
@@ -1869,7 +1929,7 @@ struct net_buf *hci_cmd_handle(struct net_buf *cmd)
return evt;
}
int hci_acl_handle(struct net_buf *buf)
int hci_acl_handle(struct net_buf *buf, struct net_buf **evt)
{
struct radio_pdu_node_tx *radio_pdu_node_tx;
struct bt_hci_acl_hdr *acl;
@@ -1878,6 +1938,8 @@ int hci_acl_handle(struct net_buf *buf)
u8_t flags;
u16_t len;
*evt = NULL;
if (buf->len < sizeof(*acl)) {
BT_ERR("No HCI ACL header");
return -EINVAL;
@@ -1900,6 +1962,7 @@ int hci_acl_handle(struct net_buf *buf)
radio_pdu_node_tx = radio_tx_mem_acquire();
if (!radio_pdu_node_tx) {
BT_ERR("Tx Buffer Overflow");
data_buf_overflow(evt);
return -ENOBUFS;
}

View File

@@ -347,6 +347,22 @@ static int cmd_handle(struct net_buf *buf)
return 0;
}
#if defined(CONFIG_BT_CONN)
static int acl_handle(struct net_buf *buf)
{
struct net_buf *evt;
int err;
err = hci_acl_handle(buf, &evt);
if (evt) {
BT_DBG("Replying with event of %u bytes", evt->len);
bt_recv_prio(evt);
}
return err;
}
#endif /* CONFIG_BT_CONN */
static int hci_driver_send(struct net_buf *buf)
{
u8_t type;
@@ -363,9 +379,9 @@ static int hci_driver_send(struct net_buf *buf)
switch (type) {
#if defined(CONFIG_BT_CONN)
case BT_BUF_ACL_OUT:
err = hci_acl_handle(buf);
err = acl_handle(buf);
break;
#endif
#endif /* CONFIG_BT_CONN */
case BT_BUF_CMD:
err = cmd_handle(buf);
break;

View File

@@ -39,7 +39,7 @@ struct net_buf *hci_cmd_handle(struct net_buf *cmd);
void hci_evt_encode(struct radio_pdu_node_rx *node_rx, struct net_buf *buf);
s8_t hci_get_class(struct radio_pdu_node_rx *node_rx);
#if defined(CONFIG_BT_CONN)
int hci_acl_handle(struct net_buf *acl);
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_num_cmplt_encode(struct net_buf *buf, u16_t handle, u8_t num);
#endif

View File

@@ -444,6 +444,8 @@ u32_t radio_init(void *hf_clock, u8_t sca, u8_t connection_count_max,
chan_sel_2_ut();
#endif /* RADIO_UNIT_TEST && CONFIG_BT_CTLR_CHAN_SEL_2 */
radio_setup();
return retcode;
}
@@ -603,6 +605,10 @@ static inline void isr_radio_state_tx(void)
radio_tmr_tifs_set(RADIO_TIFS);
#if defined(CONFIG_BT_CTLR_GPIO_LNA_PIN)
radio_gpio_lna_setup();
#endif /* CONFIG_BT_CTLR_GPIO_LNA_PIN */
switch (_radio.role) {
case ROLE_ADV:
radio_switch_complete_and_tx(0, 0, 0, 0);
@@ -624,12 +630,21 @@ static inline void isr_radio_state_tx(void)
hcto -= radio_tx_chain_delay_get(0, 0);
radio_tmr_hcto_configure(hcto);
/* capture end of CONNECT_IND PDU, used for calculating first
* slave event.
*/
radio_tmr_end_capture();
#if defined(CONFIG_BT_CTLR_SCAN_REQ_RSSI)
radio_rssi_measure();
#endif /* CONFIG_BT_CTLR_SCAN_REQ_RSSI */
#if defined(CONFIG_BT_CTLR_GPIO_LNA_PIN)
radio_gpio_pa_lna_enable(radio_tmr_end_get() + RADIO_TIFS - 4 -
radio_tx_chain_delay_get(0, 0) -
CONFIG_BT_CTLR_GPIO_LNA_OFFSET);
#endif /* CONFIG_BT_CTLR_GPIO_LNA_PIN */
break;
case ROLE_SCAN:
@@ -655,6 +670,11 @@ static inline void isr_radio_state_tx(void)
radio_tmr_hcto_configure(hcto);
radio_rssi_measure();
#if defined(CONFIG_BT_CTLR_GPIO_LNA_PIN)
radio_gpio_pa_lna_enable(radio_tmr_end_get() + RADIO_TIFS - 4 -
radio_tx_chain_delay_get(0, 0) -
CONFIG_BT_CTLR_GPIO_LNA_OFFSET);
#endif /* CONFIG_BT_CTLR_GPIO_LNA_PIN */
break;
case ROLE_MASTER:
@@ -687,7 +707,7 @@ static inline void isr_radio_state_tx(void)
hcto += radio_rx_chain_delay_get(_radio.conn_curr->phy_rx,
_radio.conn_curr->phy_flags);
hcto += addr_us_get(_radio.conn_curr->phy_rx);
hcto -= radio_tx_chain_delay_get(_radio.conn_curr->phy_rx,
hcto -= radio_tx_chain_delay_get(_radio.conn_curr->phy_tx,
_radio.conn_curr->phy_flags);
#else /* !CONFIG_BT_CTLR_PHY */
hcto += radio_rx_chain_delay_get(0, 0);
@@ -696,7 +716,25 @@ static inline void isr_radio_state_tx(void)
#endif /* !CONFIG_BT_CTLR_PHY */
radio_tmr_hcto_configure(hcto);
#if defined(CONFIG_BT_CTLR_GPIO_LNA_PIN)
#if defined(CONFIG_BT_CTLR_PHY)
radio_gpio_pa_lna_enable(radio_tmr_end_get() + RADIO_TIFS - 4 -
radio_tx_chain_delay_get(
_radio.conn_curr->phy_tx,
_radio.conn_curr->phy_flags) -
CONFIG_BT_CTLR_GPIO_LNA_OFFSET);
#else /* !CONFIG_BT_CTLR_PHY */
radio_gpio_pa_lna_enable(radio_tmr_end_get() + RADIO_TIFS - 4 -
radio_tx_chain_delay_get(0, 0) -
CONFIG_BT_CTLR_GPIO_LNA_OFFSET);
#endif /* !CONFIG_BT_CTLR_PHY */
#endif /* CONFIG_BT_CTLR_GPIO_LNA_PIN */
#if defined(CONFIG_BT_CTLR_PROFILE_ISR) || \
defined(CONFIG_BT_CTLR_GPIO_PA_PIN)
radio_tmr_end_capture();
#endif /* CONFIG_BT_CTLR_PROFILE_ISR */
/* Route the tx packet to respective connections */
/* TODO: use timebox for tx enqueue (instead of 1 packet
@@ -870,6 +908,13 @@ static inline u32_t isr_rx_adv(u8_t devmatch_ok, u8_t devmatch_id,
radio_pkt_tx_set(&_radio.advertiser.scan_data.
data[_radio.advertiser.scan_data.first][0]);
#if defined(CONFIG_BT_CTLR_GPIO_PA_PIN)
radio_gpio_pa_setup();
radio_gpio_pa_lna_enable(radio_tmr_end_get() + RADIO_TIFS -
radio_rx_chain_delay_get(0, 0) -
CONFIG_BT_CTLR_GPIO_PA_OFFSET);
#endif /* CONFIG_BT_CTLR_GPIO_PA_PIN */
/* assert if radio packet ptr is not set and radio started tx */
LL_ASSERT(!radio_is_ready());
@@ -1400,11 +1445,16 @@ static inline u32_t isr_rx_scan(u8_t devmatch_ok, u8_t devmatch_id,
radio_pkt_tx_set(pdu_adv_tx);
#if defined(CONFIG_BT_CTLR_GPIO_PA_PIN)
radio_gpio_pa_setup();
radio_gpio_pa_lna_enable(radio_tmr_end_get() + RADIO_TIFS -
radio_rx_chain_delay_get(0, 0) -
CONFIG_BT_CTLR_GPIO_PA_OFFSET);
#endif /* CONFIG_BT_CTLR_GPIO_PA_PIN */
/* assert if radio packet ptr is not set and radio started tx */
LL_ASSERT(!radio_is_ready());
radio_tmr_end_capture();
/* block CPU so that there is no CRC error on pdu tx,
* this is only needed if we want the CPU to sleep.
* while(!radio_has_disabled())
@@ -1602,8 +1652,17 @@ static inline u32_t isr_rx_scan(u8_t devmatch_ok, u8_t devmatch_id,
radio_tmr_tifs_set(RADIO_TIFS);
radio_switch_complete_and_rx(0);
radio_pkt_tx_set(pdu_adv_tx);
/* capture end of Tx-ed PDU, used to calculate HCTO. */
radio_tmr_end_capture();
#if defined(CONFIG_BT_CTLR_GPIO_PA_PIN)
radio_gpio_pa_setup();
radio_gpio_pa_lna_enable(radio_tmr_end_get() + RADIO_TIFS -
radio_rx_chain_delay_get(0, 0) -
CONFIG_BT_CTLR_GPIO_PA_OFFSET);
#endif /* CONFIG_BT_CTLR_GPIO_PA_PIN */
/* assert if radio packet ptr is not set and radio started tx */
LL_ASSERT(!radio_is_ready());
@@ -2760,6 +2819,9 @@ isr_rx_conn_pkt_ctrl(struct radio_pdu_node_rx *radio_pdu_node_rx,
break;
}
/* Stop procedure timeout */
_radio.conn_curr->procedure_expire = 0;
/* save parameters to be used to select offset
*/
conn->llcp_conn_param.interval = cpr->interval_min;
@@ -3234,14 +3296,16 @@ static inline void isr_rx_conn(u8_t crc_ok, u8_t trx_done,
u8_t crc_close = 0;
#if defined(CONFIG_BT_CTLR_PROFILE_ISR)
static u8_t s_lmax;
static u8_t s_lmin = (u8_t) -1;
static u8_t s_min = (u8_t) -1;
static u8_t s_lmax;
static u8_t s_lprv;
static u8_t s_max;
static u8_t s_min = (u8_t) -1;
static u8_t s_prv;
u32_t sample;
u8_t latency, elapsed, prv;
u32_t radio_tmr_end = 0;
u32_t sample;
u8_t chg = 0;
#endif /* CONFIG_BT_CTLR_PROFILE_ISR */
@@ -3346,6 +3410,7 @@ static inline void isr_rx_conn(u8_t crc_ok, u8_t trx_done,
radio_switch_complete_and_rx(0);
#endif /* !CONFIG_BT_CTLR_PHY */
/* capture end of Tx-ed PDU, used to calculate HCTO. */
radio_tmr_end_capture();
}
@@ -3356,11 +3421,40 @@ static inline void isr_rx_conn(u8_t crc_ok, u8_t trx_done,
/* setup the radio tx packet buffer */
tx_packet_set(_radio.conn_curr, pdu_data_tx);
#if defined(CONFIG_BT_CTLR_GPIO_PA_PIN)
#if defined(CONFIG_BT_CTLR_PROFILE_ISR)
/* PA enable is overwriting packet end used in ISR profiling, hence
* back it up for later use.
*/
radio_tmr_end = radio_tmr_end_get();
#endif /* CONFIG_BT_CTLR_PROFILE_ISR */
radio_gpio_pa_setup();
#if defined(CONFIG_BT_CTLR_PHY)
radio_gpio_pa_lna_enable(radio_tmr_end_get() + RADIO_TIFS -
radio_rx_chain_delay_get(
_radio.conn_curr->phy_rx,
_radio.conn_curr->phy_flags) -
CONFIG_BT_CTLR_GPIO_PA_OFFSET);
#else /* !CONFIG_BT_CTLR_PHY */
radio_gpio_pa_lna_enable(radio_tmr_end_get() + RADIO_TIFS -
radio_rx_chain_delay_get(0, 0) -
CONFIG_BT_CTLR_GPIO_PA_OFFSET);
#endif /* !CONFIG_BT_CTLR_PHY */
#endif /* CONFIG_BT_CTLR_GPIO_PA_PIN */
/* assert if radio packet ptr is not set and radio started tx */
LL_ASSERT(!radio_is_ready());
isr_rx_conn_exit:
/* Save the AA captured for the first Rx in connection event */
if (!radio_tmr_aa_restore()) {
radio_tmr_aa_save(radio_tmr_aa_get());
}
#if defined(CONFIG_BT_CTLR_PROFILE_ISR)
/* get the ISR latency sample */
sample = radio_tmr_sample_get();
@@ -3421,7 +3515,13 @@ isr_rx_conn_terminate_exit:
/* calculate the elapsed time in us since on-air radio packet end
* to ISR entry
*/
#if defined(CONFIG_BT_CTLR_GPIO_PA_PIN)
latency = sample - radio_tmr_end;
#else /* !CONFIG_BT_CTLR_GPIO_PA_PIN */
ARG_UNUSED(radio_tmr_end);
latency = sample - radio_tmr_end_get();
#endif /* !CONFIG_BT_CTLR_GPIO_PA_PIN */
/* check changes in min, avg and max of latency */
if (latency > s_lmax) {
@@ -3557,12 +3657,26 @@ static inline u32_t isr_close_adv(void)
if ((_radio.state == STATE_CLOSE) &&
(_radio.advertiser.chan_map_current != 0)) {
u32_t start_us;
dont_close = 1;
adv_setup();
radio_tx_enable();
#if defined(CONFIG_BT_CTLR_GPIO_PA_PIN)
start_us = radio_tmr_start_now(1);
radio_gpio_pa_setup();
radio_gpio_pa_lna_enable(start_us +
radio_tx_ready_delay_get(0, 0) -
CONFIG_BT_CTLR_GPIO_PA_OFFSET);
#else /* !CONFIG_BT_CTLR_GPIO_PA_PIN */
ARG_UNUSED(start_us);
radio_tx_enable();
#endif /* !CONFIG_BT_CTLR_GPIO_PA_PIN */
/* capture end of Tx-ed PDU, used to calculate HCTO. */
radio_tmr_end_capture();
} else {
struct pdu_adv *pdu_adv;
@@ -3610,6 +3724,8 @@ static inline u32_t isr_close_scan(void)
u32_t dont_close = 0;
if (_radio.state == STATE_CLOSE) {
u32_t start_us;
dont_close = 1;
radio_tmr_tifs_set(RADIO_TIFS);
@@ -3626,8 +3742,22 @@ static inline u32_t isr_close_scan(void)
#endif /* CONFIG_BT_CTLR_PRIVACY */
_radio.state = STATE_RX;
radio_rx_enable();
#if defined(CONFIG_BT_CTLR_GPIO_LNA_PIN)
start_us = radio_tmr_start_now(0);
radio_gpio_lna_setup();
radio_gpio_pa_lna_enable(start_us +
radio_rx_ready_delay_get(0) -
CONFIG_BT_CTLR_GPIO_LNA_OFFSET);
#else /* !CONFIG_BT_CTLR_GPIO_LNA_PIN */
ARG_UNUSED(start_us);
radio_rx_enable();
#endif /* !CONFIG_BT_CTLR_GPIO_LNA_PIN */
/* capture end of Rx-ed PDU, for initiator to calculate first
* master event.
*/
radio_tmr_end_capture();
} else {
radio_filter_disable();
@@ -3690,7 +3820,8 @@ static inline void isr_close_conn(void)
u32_t preamble_to_addr_us;
/* calculate the drift in ticks */
start_to_address_actual_us = radio_tmr_aa_get();
start_to_address_actual_us = radio_tmr_aa_restore() -
radio_tmr_ready_get();
window_widening_event_us =
_radio.conn_curr->slave.window_widening_event_us;
#if defined(CONFIG_BT_CTLR_PHY)
@@ -4050,6 +4181,11 @@ static void isr(void)
radio_ar_status_reset();
radio_rssi_status_reset();
#if defined(CONFIG_BT_CTLR_GPIO_PA_PIN) || \
defined(CONFIG_BT_CTLR_GPIO_LNA_PIN)
radio_gpio_pa_lna_disable();
#endif /* CONFIG_BT_CTLR_GPIO_PA_PIN || CONFIG_BT_CTLR_GPIO_LNA_PIN */
switch (_radio.state) {
case STATE_TX:
isr_radio_state_tx();
@@ -5647,6 +5783,8 @@ static void adv_setup(void)
static void event_adv(u32_t ticks_at_expire, u32_t remainder,
u16_t lazy, void *context)
{
u32_t remainder_us;
ARG_UNUSED(remainder);
ARG_UNUSED(lazy);
ARG_UNUSED(context);
@@ -5696,12 +5834,23 @@ static void event_adv(u32_t ticks_at_expire, u32_t remainder,
(u8_t *)wl->bdaddr);
}
radio_tmr_start(1,
ticks_at_expire +
TICKER_US_TO_TICKS(RADIO_TICKER_START_PART_US),
_radio.remainder_anchor);
remainder_us = radio_tmr_start(1,
ticks_at_expire +
TICKER_US_TO_TICKS(RADIO_TICKER_START_PART_US),
_radio.remainder_anchor);
/* capture end of Tx-ed PDU, used to calculate HCTO. */
radio_tmr_end_capture();
#if defined(CONFIG_BT_CTLR_GPIO_PA_PIN)
radio_gpio_pa_setup();
radio_gpio_pa_lna_enable(remainder_us +
radio_tx_ready_delay_get(0, 0) -
CONFIG_BT_CTLR_GPIO_PA_OFFSET);
#else /* !CONFIG_BT_CTLR_GPIO_PA_PIN */
ARG_UNUSED(remainder_us);
#endif /* !CONFIG_BT_CTLR_GPIO_PA_PIN */
#if (defined(CONFIG_BT_CTLR_XTAL_ADVANCED) && \
(RADIO_TICKER_PREEMPT_PART_US <= RADIO_TICKER_PREEMPT_PART_MIN_US))
/* check if preempt to start has changed */
@@ -5729,31 +5878,11 @@ static void event_adv(u32_t ticks_at_expire, u32_t remainder,
DEBUG_RADIO_START_A(0);
}
void event_adv_stop(u32_t ticks_at_expire, u32_t remainder, u16_t lazy,
void *context)
static void mayfly_adv_stop(void *param)
{
struct radio_le_conn_cmplt *radio_le_conn_cmplt;
struct radio_pdu_node_rx *radio_pdu_node_rx;
struct pdu_data *pdu_data_rx;
u32_t ticker_status;
ARG_UNUSED(ticks_at_expire);
ARG_UNUSED(remainder);
ARG_UNUSED(lazy);
ARG_UNUSED(context);
/* Abort an event, if any, to avoid Rx queue corruption used by Radio
* ISR.
*/
event_stop(0, 0, 0, (void *)STATE_ABORT);
/* Stop Direct Adv */
ticker_status =
ticker_stop(RADIO_TICKER_INSTANCE_ID_RADIO,
RADIO_TICKER_USER_ID_WORKER, RADIO_TICKER_ID_ADV,
ticker_success_assert, (void *)__LINE__);
LL_ASSERT((ticker_status == TICKER_STATUS_SUCCESS) ||
(ticker_status == TICKER_STATUS_BUSY));
/* Prepare the rx packet structure */
radio_pdu_node_rx = packet_rx_reserve_get(1);
@@ -5774,6 +5903,186 @@ void event_adv_stop(u32_t ticks_at_expire, u32_t remainder, u16_t lazy,
packet_rx_enqueue();
}
static inline void ticker_stop_adv_stop_active(void)
{
static void *s_link[2];
static struct mayfly s_mfy_radio_inactive = {0, 0, s_link, NULL,
mayfly_radio_inactive};
u32_t volatile ret_cb = TICKER_STATUS_BUSY;
u32_t ret;
/* Step 2: Is caller before Event? Stop Event */
ret = ticker_stop(RADIO_TICKER_INSTANCE_ID_RADIO,
RADIO_TICKER_USER_ID_JOB, RADIO_TICKER_ID_EVENT,
ticker_if_done, (void *)&ret_cb);
if (ret == TICKER_STATUS_BUSY) {
mayfly_enable(RADIO_TICKER_USER_ID_JOB,
RADIO_TICKER_USER_ID_JOB, 1);
while (ret_cb == TICKER_STATUS_BUSY) {
ticker_job_sched(RADIO_TICKER_INSTANCE_ID_RADIO,
RADIO_TICKER_USER_ID_JOB);
}
}
if (ret_cb == TICKER_STATUS_SUCCESS) {
static void *s_link[2];
static struct mayfly s_mfy_xtal_stop = {0, 0, s_link, NULL,
mayfly_xtal_stop};
u32_t volatile ret_cb = TICKER_STATUS_BUSY;
u32_t ret;
/* Reset the stored ticker id in prepare phase. */
LL_ASSERT(_radio.ticker_id_prepare);
_radio.ticker_id_prepare = 0;
/* Step 2.1: Is caller between Primary and Marker0?
* Stop the Marker0 event
*/
ret = ticker_stop(RADIO_TICKER_INSTANCE_ID_RADIO,
RADIO_TICKER_USER_ID_JOB,
RADIO_TICKER_ID_MARKER_0,
ticker_if_done, (void *)&ret_cb);
if (ret == TICKER_STATUS_BUSY) {
mayfly_enable(RADIO_TICKER_USER_ID_JOB,
RADIO_TICKER_USER_ID_JOB, 1);
while (ret_cb == TICKER_STATUS_BUSY) {
ticker_job_sched(RADIO_TICKER_INSTANCE_ID_RADIO,
RADIO_TICKER_USER_ID_JOB);
}
}
if (ret_cb == TICKER_STATUS_SUCCESS) {
/* Step 2.1.1: Check and deassert Radio Active or XTAL
* start
*/
if (_radio.advertiser.hdr.ticks_active_to_start >
(_radio.advertiser.hdr.ticks_xtal_to_start &
~BIT(31))) {
u32_t retval;
/* radio active asserted, handle deasserting
* here
*/
retval = mayfly_enqueue(
RADIO_TICKER_USER_ID_JOB,
RADIO_TICKER_USER_ID_WORKER, 0,
&s_mfy_radio_inactive);
LL_ASSERT(!retval);
} else {
u32_t retval;
/* XTAL started, handle XTAL stop here */
retval = mayfly_enqueue(
RADIO_TICKER_USER_ID_JOB,
RADIO_TICKER_USER_ID_WORKER, 0,
&s_mfy_xtal_stop);
LL_ASSERT(!retval);
}
} else if (ret_cb == TICKER_STATUS_FAILURE) {
u32_t retval;
/* Step 2.1.2: Deassert Radio Active and XTAL start */
/* radio active asserted, handle deasserting here */
retval = mayfly_enqueue(RADIO_TICKER_USER_ID_JOB,
RADIO_TICKER_USER_ID_WORKER, 0,
&s_mfy_radio_inactive);
LL_ASSERT(!retval);
/* XTAL started, handle XTAL stop here */
retval = mayfly_enqueue(RADIO_TICKER_USER_ID_JOB,
RADIO_TICKER_USER_ID_WORKER, 0,
&s_mfy_xtal_stop);
LL_ASSERT(!retval);
} else {
LL_ASSERT(0);
}
} else if (ret_cb == TICKER_STATUS_FAILURE) {
/* Step 3: Caller inside Event, handle graceful stop of Event
* (role dependent)
*/
if (_radio.role != ROLE_NONE) {
static void *s_link[2];
static struct mayfly s_mfy_radio_stop = {0, 0, s_link,
NULL, mayfly_radio_stop};
u32_t retval;
/* Radio state STOP is supplied in params */
s_mfy_radio_stop.param = (void *)STATE_STOP;
/* Stop Radio Tx/Rx */
retval = mayfly_enqueue(RADIO_TICKER_USER_ID_JOB,
RADIO_TICKER_USER_ID_WORKER, 0,
&s_mfy_radio_stop);
LL_ASSERT(!retval);
/* NOTE: Cannot wait here for the event to finish
* as we need to let radio ISR to execute if we are in
* the same priority.
*/
}
} else {
LL_ASSERT(0);
}
}
static void ticker_stop_adv_stop(u32_t status, void *params)
{
static void *s_link[2];
static struct mayfly s_mfy_adv_stop = {0, 0, s_link, NULL,
mayfly_adv_stop};
u32_t retval;
ARG_UNUSED(params);
/* Ignore if being stopped from app/thread prio */
if (status != TICKER_STATUS_SUCCESS) {
LL_ASSERT(_radio.ticker_id_stop == RADIO_TICKER_ID_ADV);
return;
}
/* Handle adv stop inside a prepare and/or event */
if ((_radio.ticker_id_prepare == RADIO_TICKER_ID_ADV) ||
(_radio.ticker_id_event == RADIO_TICKER_ID_ADV)) {
ticker_stop_adv_stop_active();
}
/* Generate the connection complete event in WORKER Prio */
retval = mayfly_enqueue(RADIO_TICKER_USER_ID_JOB,
RADIO_TICKER_USER_ID_WORKER, 0,
&s_mfy_adv_stop);
LL_ASSERT(!retval);
}
void event_adv_stop(u32_t ticks_at_expire, u32_t remainder, u16_t lazy,
void *context)
{
u32_t ticker_status;
ARG_UNUSED(ticks_at_expire);
ARG_UNUSED(remainder);
ARG_UNUSED(lazy);
ARG_UNUSED(context);
/* Abort an event, if any, to avoid Rx queue corruption used by Radio
* ISR.
*/
event_stop(0, 0, 0, (void *)STATE_ABORT);
/* Stop Direct Adv */
ticker_status =
ticker_stop(RADIO_TICKER_INSTANCE_ID_RADIO,
RADIO_TICKER_USER_ID_WORKER, RADIO_TICKER_ID_ADV,
ticker_stop_adv_stop, (void *)__LINE__);
LL_ASSERT((ticker_status == TICKER_STATUS_SUCCESS) ||
(ticker_status == TICKER_STATUS_BUSY));
}
static void event_scan_prepare(u32_t ticks_at_expire, u32_t remainder,
u16_t lazy, void *context)
{
@@ -5833,6 +6142,7 @@ static void event_scan(u32_t ticks_at_expire, u32_t remainder, u16_t lazy,
void *context)
{
u32_t ticker_status;
u32_t remainder_us;
ARG_UNUSED(remainder);
ARG_UNUSED(lazy);
@@ -5892,12 +6202,25 @@ static void event_scan(u32_t ticks_at_expire, u32_t remainder, u16_t lazy,
(u8_t *)wl->bdaddr);
}
radio_tmr_start(0,
ticks_at_expire +
TICKER_US_TO_TICKS(RADIO_TICKER_START_PART_US),
_radio.remainder_anchor);
remainder_us = radio_tmr_start(0,
ticks_at_expire +
TICKER_US_TO_TICKS(RADIO_TICKER_START_PART_US),
_radio.remainder_anchor);
/* capture end of Rx-ed PDU, for initiator to calculate first
* master event.
*/
radio_tmr_end_capture();
#if defined(CONFIG_BT_CTLR_GPIO_LNA_PIN)
radio_gpio_lna_setup();
radio_gpio_pa_lna_enable(remainder_us +
radio_rx_ready_delay_get(0) -
CONFIG_BT_CTLR_GPIO_LNA_OFFSET);
#else /* !CONFIG_BT_CTLR_GPIO_LNA_PIN */
ARG_UNUSED(remainder_us);
#endif /* !CONFIG_BT_CTLR_GPIO_LNA_PIN */
#if (defined(CONFIG_BT_CTLR_XTAL_ADVANCED) && \
(RADIO_TICKER_PREEMPT_PART_US <= RADIO_TICKER_PREEMPT_PART_MIN_US))
/* check if preempt to start has changed */
@@ -7645,7 +7968,10 @@ static void event_slave(u32_t ticks_at_expire, u32_t remainder, u16_t lazy,
radio_tmr_start(0, ticks_at_expire +
TICKER_US_TO_TICKS(RADIO_TICKER_START_PART_US),
_radio.remainder_anchor);
radio_tmr_aa_capture();
radio_tmr_aa_save(0);
hcto = remainder_us + RADIO_TICKER_JITTER_US +
(RADIO_TICKER_JITTER_US << 2) +
(conn->slave.window_widening_event_us << 1) +
@@ -7660,7 +7986,25 @@ static void event_slave(u32_t ticks_at_expire, u32_t remainder, u16_t lazy,
#endif /* !CONFIG_BT_CTLR_PHY */
radio_tmr_hcto_configure(hcto);
#if defined(CONFIG_BT_CTLR_GPIO_LNA_PIN)
radio_gpio_lna_setup();
#if defined(CONFIG_BT_CTLR_PHY)
radio_gpio_pa_lna_enable(remainder_us +
radio_rx_ready_delay_get(conn->phy_rx) -
CONFIG_BT_CTLR_GPIO_LNA_OFFSET);
#else /* !CONFIG_BT_CTLR_PHY */
radio_gpio_pa_lna_enable(remainder_us +
radio_rx_ready_delay_get(0) -
CONFIG_BT_CTLR_GPIO_LNA_OFFSET);
#endif /* !CONFIG_BT_CTLR_PHY */
#endif /* CONFIG_BT_CTLR_GPIO_LNA_PIN */
#if defined(CONFIG_BT_CTLR_PROFILE_ISR) || \
defined(CONFIG_BT_CTLR_GPIO_PA_PIN)
radio_tmr_end_capture();
#endif /* CONFIG_BT_CTLR_PROFILE_ISR */
#if defined(CONFIG_BT_CTLR_CONN_RSSI)
radio_rssi_measure();
@@ -7709,9 +8053,10 @@ static void event_master_prepare(u32_t ticks_at_expire, u32_t remainder,
static void event_master(u32_t ticks_at_expire, u32_t remainder, u16_t lazy,
void *context)
{
u8_t data_chan_use = 0;
struct pdu_data *pdu_data_tx;
struct connection *conn;
u8_t data_chan_use = 0;
u32_t remainder_us;
ARG_UNUSED(remainder);
ARG_UNUSED(lazy);
@@ -7784,10 +8129,31 @@ static void event_master(u32_t ticks_at_expire, u32_t remainder, u16_t lazy,
(conn->supervision_expire && (conn->supervision_expire <= 6)) ||
(conn->connect_expire && (conn->connect_expire <= 6))) {
#endif
radio_tmr_start(1, ticks_at_expire +
remainder_us = radio_tmr_start(1,
ticks_at_expire +
TICKER_US_TO_TICKS(RADIO_TICKER_START_PART_US),
_radio.remainder_anchor);
/* capture end of Tx-ed PDU, used to calculate HCTO. */
radio_tmr_end_capture();
#if defined(CONFIG_BT_CTLR_GPIO_PA_PIN)
radio_gpio_pa_setup();
#if defined(CONFIG_BT_CTLR_PHY)
radio_gpio_pa_lna_enable(remainder_us +
radio_tx_ready_delay_get(conn->phy_tx,
conn->phy_flags) -
CONFIG_BT_CTLR_GPIO_PA_OFFSET);
#else /* !CONFIG_BT_CTLR_PHY */
radio_gpio_pa_lna_enable(remainder_us +
radio_tx_ready_delay_get(0, 0) -
CONFIG_BT_CTLR_GPIO_PA_OFFSET);
#endif /* !CONFIG_BT_CTLR_PHY */
#else /* !CONFIG_BT_CTLR_GPIO_PA_PIN */
ARG_UNUSED(remainder_us);
#endif /* !CONFIG_BT_CTLR_GPIO_PA_PIN */
#if SILENT_CONNECTION
/* silent connection! */
} else {
@@ -7815,7 +8181,9 @@ static void event_master(u32_t ticks_at_expire, u32_t remainder, u16_t lazy,
radio_tmr_start(0, ticks_at_expire +
TICKER_US_TO_TICKS(RADIO_TICKER_START_PART_US),
_radio.remainder_anchor);
radio_tmr_aa_capture();
radio_tmr_aa_save(0);
hcto = remainder_us + RADIO_TIFS;
#if defined(CONFIG_BT_CTLR_PHY)
@@ -7832,6 +8200,20 @@ static void event_master(u32_t ticks_at_expire, u32_t remainder, u16_t lazy,
hcto += 256;
radio_tmr_hcto_configure(hcto);
#if defined(CONFIG_BT_CTLR_GPIO_LNA_PIN)
radio_gpio_lna_setup();
#if defined(CONFIG_BT_CTLR_PHY)
radio_gpio_pa_lna_enable(remainder_us +
radio_rx_ready_delay_get(conn->phy_rx) -
CONFIG_BT_CTLR_GPIO_LNA_OFFSET);
#else /* !CONFIG_BT_CTLR_PHY */
radio_gpio_pa_lna_enable(remainder_us +
radio_rx_ready_delay_get(0) -
CONFIG_BT_CTLR_GPIO_LNA_OFFSET);
#endif /* !CONFIG_BT_CTLR_PHY */
#endif /* CONFIG_BT_CTLR_GPIO_LNA_PIN */
}
#endif
@@ -8999,6 +9381,9 @@ static inline void role_active_disable(u8_t ticker_id_stop,
}
if (ret_cb == TICKER_STATUS_SUCCESS) {
/* If in reduced prepare, use the absolute value */
ticks_xtal_to_start &= ~BIT(31);
/* Step 2.1.1: Check and deassert Radio Active or XTAL
* start
*/
@@ -9043,29 +9428,37 @@ static inline void role_active_disable(u8_t ticker_id_stop,
LL_ASSERT(0);
}
} else if (ret_cb == TICKER_STATUS_FAILURE) {
u32_t volatile ret_cb = TICKER_STATUS_BUSY;
u32_t ret;
/* Step 3: Caller inside Event, handle graceful stop of Event
* (role dependent)
*/
/* Stop ticker "may" be in use for direct adv or scanner,
* hence stop may fail if ticker not used.
*
* Connection instances do not use a stop ticker, hence do not
* try to stop an invalid ticker id.
*/
ret = ticker_stop(RADIO_TICKER_INSTANCE_ID_RADIO,
RADIO_TICKER_USER_ID_APP, ticker_id_stop,
ticker_if_done, (void *)&ret_cb);
if (ticker_id_stop != TICKER_NULL) {
u32_t volatile ret_cb = TICKER_STATUS_BUSY;
u32_t ret;
if (ret == TICKER_STATUS_BUSY) {
mayfly_enable(RADIO_TICKER_USER_ID_APP,
RADIO_TICKER_USER_ID_JOB, 1);
ret = ticker_stop(RADIO_TICKER_INSTANCE_ID_RADIO,
RADIO_TICKER_USER_ID_APP,
ticker_id_stop, ticker_if_done,
(void *)&ret_cb);
LL_ASSERT(ret_cb != TICKER_STATUS_BUSY);
if (ret == TICKER_STATUS_BUSY) {
mayfly_enable(RADIO_TICKER_USER_ID_APP,
RADIO_TICKER_USER_ID_JOB, 1);
LL_ASSERT(ret_cb != TICKER_STATUS_BUSY);
}
LL_ASSERT((ret_cb == TICKER_STATUS_SUCCESS) ||
(ret_cb == TICKER_STATUS_FAILURE));
}
LL_ASSERT((ret_cb == TICKER_STATUS_SUCCESS) ||
(ret_cb == TICKER_STATUS_FAILURE));
/* Force Radio ISR execution and wait for role to stop */
if (_radio.role != ROLE_NONE) {
static void *s_link[2];
static struct mayfly s_mfy_radio_stop = {0, 0, s_link,

View File

@@ -9,8 +9,10 @@
#include <toolchain.h>
#include <zephyr/types.h>
#include <soc.h>
#include <clock_control.h>
#include "hal/cpu.h"
#include "hal/cntr.h"
#include "hal/ccm.h"
#include "hal/radio.h"
@@ -72,20 +74,25 @@ static const u8_t prbs9[] = {
/* TODO: fill correct prbs15 */
static const u8_t prbs15[255] = { 0x00, };
static u8_t tx_req;
static u8_t volatile tx_ack;
static void isr_tx(void)
{
u8_t trx_done;
u32_t l, i, s, t;
/* Read radio status and events */
trx_done = radio_is_done();
/* Clear radio status and events */
radio_status_reset();
radio_tmr_status_reset();
#if defined(CONFIG_BT_CTLR_GPIO_PA_PIN)
radio_gpio_pa_lna_disable();
#endif /* CONFIG_BT_CTLR_GPIO_PA_PIN */
/* Exit if radio disabled */
if (!trx_done) {
if (((tx_req - tx_ack) & 0x01) == 0) {
tx_ack = tx_req;
return;
}
@@ -108,7 +115,14 @@ static void isr_tx(void)
radio_tmr_aa_capture();
radio_tmr_end_capture();
/* TODO: check for probable stall timer capture being set */
/* TODO: check for probable stale timer capture being set */
#if defined(CONFIG_BT_CTLR_GPIO_PA_PIN)
radio_gpio_pa_setup();
radio_gpio_pa_lna_enable(t + radio_tx_ready_delay_get(test_phy,
test_phy_flags) -
CONFIG_BT_CTLR_GPIO_PA_OFFSET);
#endif /* CONFIG_BT_CTLR_GPIO_PA_PIN */
}
static void isr_rx(void)
@@ -171,6 +185,7 @@ static u32_t init(u8_t chan, u8_t phy, void (*isr)(void))
/* Setup Radio in Tx/Rx */
/* NOTE: No whitening in test mode. */
radio_phy_set(test_phy, test_phy_flags);
radio_tmr_tifs_set(150);
radio_tx_power_set(0);
radio_freq_chan_set((chan << 1) + 2);
radio_aa_set((u8_t *)&test_sync_word);
@@ -182,6 +197,7 @@ static u32_t init(u8_t chan, u8_t phy, void (*isr)(void))
u32_t ll_test_tx(u8_t chan, u8_t len, u8_t type, u8_t phy)
{
u32_t start_us;
u8_t *payload;
u8_t *pdu;
u32_t err;
@@ -195,6 +211,8 @@ u32_t ll_test_tx(u8_t chan, u8_t len, u8_t type, u8_t phy)
return err;
}
tx_req++;
pdu = radio_pkt_scratch_get();
payload = &pdu[2];
@@ -237,10 +255,20 @@ u32_t ll_test_tx(u8_t chan, u8_t len, u8_t type, u8_t phy)
radio_pkt_tx_set(pdu);
radio_switch_complete_and_disable();
radio_tmr_start(1, cntr_cnt_get() + CNTR_MIN_DELTA, 0);
start_us = radio_tmr_start(1, cntr_cnt_get() + CNTR_MIN_DELTA, 0);
radio_tmr_aa_capture();
radio_tmr_end_capture();
#if defined(CONFIG_BT_CTLR_GPIO_PA_PIN)
radio_gpio_pa_setup();
radio_gpio_pa_lna_enable(start_us +
radio_tx_ready_delay_get(test_phy,
test_phy_flags) -
CONFIG_BT_CTLR_GPIO_PA_OFFSET);
#else /* !CONFIG_BT_CTLR_GPIO_PA_PIN */
ARG_UNUSED(start_us);
#endif /* !CONFIG_BT_CTLR_GPIO_PA_PIN */
started = true;
return 0;
@@ -263,6 +291,10 @@ u32_t ll_test_rx(u8_t chan, u8_t phy, u8_t mod_idx)
radio_switch_complete_and_rx(test_phy);
radio_tmr_start(0, cntr_cnt_get() + CNTR_MIN_DELTA, 0);
#if defined(CONFIG_BT_CTLR_GPIO_LNA_PIN)
radio_gpio_lna_on();
#endif /* !CONFIG_BT_CTLR_GPIO_LNA_PIN */
started = true;
return 0;
@@ -271,6 +303,7 @@ u32_t ll_test_rx(u8_t chan, u8_t phy, u8_t mod_idx)
u32_t ll_test_end(u16_t *num_rx)
{
struct device *hf_clock;
u8_t ack;
if (!started) {
return 1;
@@ -280,8 +313,17 @@ u32_t ll_test_end(u16_t *num_rx)
*num_rx = test_num_rx;
test_num_rx = 0;
/* Disable Radio */
radio_disable();
/* Disable Radio, if in Rx test */
ack = tx_ack;
if (tx_req == ack) {
radio_disable();
} else {
/* Wait for Tx to complete */
tx_req = ack + 2;
while (tx_req != tx_ack) {
cpu_sleep();
}
}
/* Stop packet timer */
radio_tmr_stop();
@@ -293,6 +335,10 @@ u32_t ll_test_end(u16_t *num_rx)
/* Stop coarse timer */
cntr_stop();
#if defined(CONFIG_BT_CTLR_GPIO_LNA_PIN)
radio_gpio_lna_off();
#endif /* !CONFIG_BT_CTLR_GPIO_LNA_PIN */
started = false;
return 0;

View File

@@ -287,11 +287,20 @@ static int dns_read(struct dns_resolve_context *ctx,
info->ai_addr.sa_family = AF_INET;
info->ai_addrlen = sizeof(struct sockaddr_in);
} else if (ctx->queries[query_idx].query_type == DNS_QUERY_TYPE_AAAA) {
/* We cannot resolve IPv6 address if IPv6 is disabled. The reason
* being that "struct sockaddr" does not have enough space for
* IPv6 address in that case.
*/
#if defined(CONFIG_NET_IPV6)
address_size = DNS_IPV6_LEN;
addr = (u8_t *)&net_sin6(&info->ai_addr)->sin6_addr;
info->ai_family = AF_INET6;
info->ai_addr.sa_family = AF_INET6;
info->ai_addrlen = sizeof(struct sockaddr_in6);
#else
ret = DNS_EAI_FAMILY;
goto quit;
#endif
} else {
ret = DNS_EAI_FAMILY;
goto quit;
@@ -608,10 +617,10 @@ int dns_resolve_name(struct dns_resolve_context *ctx,
void *user_data,
s32_t timeout)
{
struct net_buf *dns_data;
struct net_buf *dns_data = NULL;
struct net_buf *dns_qname = NULL;
struct sockaddr addr;
int ret, i, j = 0;
int ret, i = -1, j = 0;
int failure = 0;
if (!ctx || !ctx->is_used || !query || !cb) {
@@ -638,11 +647,16 @@ int dns_resolve_name(struct dns_resolve_context *ctx,
info.ai_addr.sa_family = AF_INET;
info.ai_addrlen = sizeof(struct sockaddr_in);
} else if (type == DNS_QUERY_TYPE_AAAA) {
#if defined(CONFIG_NET_IPV6)
memcpy(net_sin6(&info.ai_addr), net_sin6(&addr),
sizeof(struct sockaddr_in6));
info.ai_family = AF_INET6;
info.ai_addr.sa_family = AF_INET6;
info.ai_addrlen = sizeof(struct sockaddr_in6);
#else
ret = -EAFNOSUPPORT;
goto quit;
#endif
} else {
goto try_resolve;
}
@@ -729,11 +743,14 @@ try_resolve:
quit:
if (ret < 0) {
if (k_delayed_work_remaining_get(&ctx->queries[i].timer) > 0) {
k_delayed_work_cancel(&ctx->queries[i].timer);
}
if (i >= 0) {
if (k_delayed_work_remaining_get(
&ctx->queries[i].timer) > 0) {
k_delayed_work_cancel(&ctx->queries[i].timer);
}
ctx->queries[i].cb = NULL;
ctx->queries[i].cb = NULL;
}
if (dns_id) {
*dns_id = 0;

View File

@@ -0,0 +1,31 @@
CONFIG_NETWORKING=y
CONFIG_NET_TEST=y
CONFIG_RANDOM_GENERATOR=y
CONFIG_TEST_RANDOM_GENERATOR=y
CONFIG_NET_L2_DUMMY=y
CONFIG_DNS_RESOLVER=y
CONFIG_DNS_RESOLVER_MAX_SERVERS=2
CONFIG_DNS_NUM_OF_CONCUR_QUERIES=1
CONFIG_DNS_SERVER_IP_ADDRESSES=y
CONFIG_DNS_SERVER1="192.0.2.2"
CONFIG_DNS_SERVER2="192.0.2.2:5353"
CONFIG_NET_LOG=y
CONFIG_SYS_LOG_NET_LEVEL=2
CONFIG_SYS_LOG_SHOW_COLOR=y
#CONFIG_NET_DEBUG_DNS_RESOLVE=y
CONFIG_NET_IPV4=y
CONFIG_NET_IPV6=n
CONFIG_NET_IPV6_DAD=n
CONFIG_NET_IPV6_MLD=n
CONFIG_NET_IPV6_ND=n
CONFIG_NET_ARP=n
CONFIG_PRINTK=y
CONFIG_ZTEST=y
CONFIG_MAIN_STACK_SIZE=1344

View File

@@ -374,10 +374,12 @@ static void dns_query_ipv4_server_count(void)
continue;
}
if (ctx->servers[i].dns_server.sa_family == AF_INET) {
count++;
if (ctx->servers[i].dns_server.sa_family == AF_INET6) {
continue;
}
count++;
if (net_sin(&ctx->servers[i].dns_server)->sin_port ==
ntohs(53)) {
port++;
@@ -385,7 +387,7 @@ static void dns_query_ipv4_server_count(void)
}
zassert_equal(count, 2, "Invalid number of IPv4 servers");
zassert_equal(port, 2, "Invalid number of IPv4 servers with port 53");
zassert_equal(port, 1, "Invalid number of IPv4 servers with port 53");
}
static void dns_query_ipv6_server_count(void)
@@ -402,18 +404,25 @@ static void dns_query_ipv6_server_count(void)
continue;
}
if (ctx->servers[i].dns_server.sa_family == AF_INET6) {
count++;
if (ctx->servers[i].dns_server.sa_family == AF_INET) {
continue;
}
count++;
if (net_sin6(&ctx->servers[i].dns_server)->sin6_port ==
ntohs(53)) {
port++;
}
}
#if defined(CONFIG_NET_IPV6)
zassert_equal(count, 2, "Invalid number of IPv6 servers");
zassert_equal(port, 2, "Invalid number of IPv6 servers with port 53");
zassert_equal(port, 1, "Invalid number of IPv6 servers with port 53");
#else
zassert_equal(count, 0, "Invalid number of IPv6 servers");
zassert_equal(port, 0, "Invalid number of IPv6 servers with port 53");
#endif
}
static void dns_query_too_many(void)
@@ -671,10 +680,12 @@ void dns_result_numeric_cb(enum dns_resolve_status status,
}
if (info && info->ai_family == AF_INET6) {
#if defined(CONFIG_NET_IPV6)
if (net_ipv6_addr_cmp(&net_sin6(&info->ai_addr)->sin6_addr,
&my_addr3) != true) {
zassert_true(false, "IPv6 address does not match");
}
#endif
}
k_sem_give(&wait_data2);

View File

@@ -3,3 +3,8 @@ tests:
tags: dns net
min_ram: 16
timeout: 600
- test-no-ipv6:
tags: dns net
min_ram: 16
timeout: 600
extra_args: CONF_FILE=prj-no-ipv6.conf