Initial commit for hci_uart
This commit is contained in:
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# editors
|
||||||
|
*.swp
|
||||||
|
*~
|
||||||
|
|
||||||
|
# build
|
||||||
|
/build*/
|
||||||
8
CMakeLists.txt
Normal file
8
CMakeLists.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
|
||||||
|
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||||
|
project(hci_uart)
|
||||||
|
|
||||||
|
target_sources(app PRIVATE src/main.c)
|
||||||
202
README.rst
Normal file
202
README.rst
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
.. zephyr:code-sample:: bluetooth_hci_uart
|
||||||
|
:name: HCI UART
|
||||||
|
:relevant-api: hci_raw bluetooth uart_interface
|
||||||
|
|
||||||
|
Expose a Bluetooth controller to another device or CPU over UART.
|
||||||
|
|
||||||
|
Overview
|
||||||
|
*********
|
||||||
|
|
||||||
|
Expose Bluetooth controller support over UART to another device/CPU
|
||||||
|
using the H:4 HCI transport protocol (requires HW flow control from the UART).
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
************
|
||||||
|
|
||||||
|
* A board with Bluetooth LE support
|
||||||
|
|
||||||
|
Default UART settings
|
||||||
|
*********************
|
||||||
|
|
||||||
|
By default the controller builds use the following settings:
|
||||||
|
|
||||||
|
* Baudrate: 1Mbit/s
|
||||||
|
* 8 bits, no parity, 1 stop bit
|
||||||
|
* Hardware Flow Control (RTS/CTS) enabled
|
||||||
|
|
||||||
|
Building and Running
|
||||||
|
********************
|
||||||
|
|
||||||
|
This sample can be found under :zephyr_file:`samples/bluetooth/hci_uart` in the
|
||||||
|
Zephyr tree, and it is built as a standard Zephyr application.
|
||||||
|
|
||||||
|
Using the controller with emulators and BlueZ
|
||||||
|
*********************************************
|
||||||
|
|
||||||
|
The instructions below show how to use a Nordic nRF5x device as a Zephyr BLE
|
||||||
|
controller and expose it to Linux's BlueZ. This can be very useful for testing
|
||||||
|
the Zephyr Link Layer with the BlueZ Host. The Zephyr Bluetooth LE controller can also
|
||||||
|
provide a modern Bluetooth LE 5.0 controller to a Linux-based machine for native
|
||||||
|
BLE support or QEMU-based development.
|
||||||
|
|
||||||
|
First, make sure you have a recent BlueZ version installed by following the
|
||||||
|
instructions in the :ref:`bluetooth_bluez` section.
|
||||||
|
|
||||||
|
Now build and flash the sample for the Nordic nRF5x board of your choice.
|
||||||
|
All of the Nordic Development Kits come with a Segger IC that provides a
|
||||||
|
debugger interface and a CDC ACM serial port bridge. More information can be
|
||||||
|
found in :ref:`nordic_segger`.
|
||||||
|
|
||||||
|
For example, to build for the nRF52832 Development Kit:
|
||||||
|
|
||||||
|
.. zephyr-app-commands::
|
||||||
|
:zephyr-app: samples/bluetooth/hci_uart
|
||||||
|
:board: nrf52dk/nrf52832
|
||||||
|
:goals: build flash
|
||||||
|
|
||||||
|
.. _bluetooth-hci-uart-qemu-posix:
|
||||||
|
|
||||||
|
Using the controller with QEMU or native_sim
|
||||||
|
============================================
|
||||||
|
|
||||||
|
In order to use the HCI UART controller with QEMU or :ref:`native_sim <native_sim>` you will need
|
||||||
|
to attach it to the Linux Host first. To do so simply build the sample and
|
||||||
|
connect the UART to the Linux machine, and then attach it with this command:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
sudo btattach -B /dev/ttyACM0 -S 1000000 -R
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Depending on the serial port you are using you will need to modify the
|
||||||
|
``/dev/ttyACM0`` string to point to the serial device your controller is
|
||||||
|
connected to.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
If using the BBC micro:bit you will need to modify the baudrate argument
|
||||||
|
from ``1000000`` to ``115200``.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
The ``-R`` flag passed to ``btattach`` instructs the kernel to avoid
|
||||||
|
interacting with the controller and instead just be aware of it in order
|
||||||
|
to proxy it to QEMU later.
|
||||||
|
|
||||||
|
If you are running :file:`btmon` you should see a brief log showing how the
|
||||||
|
Linux kernel identifies the attached controller.
|
||||||
|
|
||||||
|
Once the controller is attached follow the instructions in the
|
||||||
|
:ref:`bluetooth_qemu_native` section to use QEMU with it.
|
||||||
|
|
||||||
|
.. _bluetooth-hci-uart-bluez:
|
||||||
|
|
||||||
|
Using the controller with BlueZ
|
||||||
|
===============================
|
||||||
|
|
||||||
|
In order to use the HCI UART controller with BlueZ you will need to attach it
|
||||||
|
to the Linux Host first. To do so simply build the sample and connect the
|
||||||
|
UART to the Linux machine, and then attach it with this command:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
sudo btattach -B /dev/ttyACM0 -S 1000000
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Depending on the serial port you are using you will need to modify the
|
||||||
|
``/dev/ttyACM0`` string to point to the serial device your controller is
|
||||||
|
connected to.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
If using the BBC micro:bit you will need to modify the baudrate argument
|
||||||
|
from ``1000000`` to ``115200``.
|
||||||
|
|
||||||
|
If you are running :file:`btmon` you should see a comprehensive log showing how
|
||||||
|
BlueZ loads and initializes the attached controller.
|
||||||
|
|
||||||
|
Once the controller is attached follow the instructions in the
|
||||||
|
:ref:`bluetooth_ctlr_bluez` section to use BlueZ with it.
|
||||||
|
|
||||||
|
Debugging the controller
|
||||||
|
========================
|
||||||
|
|
||||||
|
The sample can be debugged using RTT since the UART is otherwise used by this
|
||||||
|
application. To enable debug over RTT the debug configuration file can be used.
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
west build samples/bluetooth/hci_uart -- -DEXTRA_CONF_FILE='debug.conf'
|
||||||
|
|
||||||
|
Then attach RTT as described here: :ref:`Using Segger J-Link <Using Segger J-Link>`
|
||||||
|
|
||||||
|
Support for the Direction Finding
|
||||||
|
=================================
|
||||||
|
|
||||||
|
The sample can be built with the support for the Bluetooth LE Direction Finding.
|
||||||
|
To enable this feature build this sample for specific board variants that provide
|
||||||
|
required hardware configuration for the Radio.
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
west build samples/bluetooth/hci_uart -b nrf52833dk/nrf52833@df -- -DCONFIG_BT_CTLR_DF=y
|
||||||
|
|
||||||
|
You can use following targets:
|
||||||
|
|
||||||
|
* ``nrf5340dk/nrf5340/cpunet@df``
|
||||||
|
* ``nrf52833dk/nrf52833@df``
|
||||||
|
|
||||||
|
Check the :zephyr:code-sample:`ble_direction_finding_connectionless_rx` and the
|
||||||
|
:zephyr:code-sample:`ble_direction_finding_connectionless_tx` for more details.
|
||||||
|
|
||||||
|
Using a USB CDC ACM UART
|
||||||
|
========================
|
||||||
|
|
||||||
|
The sample can be configured to use a USB UART instead. See :zephyr_file:`samples/bluetooth/hci_uart/boards/nrf52840dongle_nrf52840.conf` and :zephyr_file:`samples/bluetooth/hci_uart/boards/nrf52840dongle_nrf52840.overlay`.
|
||||||
|
|
||||||
|
Using the controller with the Zephyr host
|
||||||
|
=========================================
|
||||||
|
|
||||||
|
This describes how to hook up a board running this sample to a board running
|
||||||
|
an application that uses the Zephyr host.
|
||||||
|
|
||||||
|
On the controller side, the ``zephyr,bt-c2h-uart`` DTS property (in the ``chosen``
|
||||||
|
block) is used to select which uart device to use. For example if we want to
|
||||||
|
keep the console logs, we can keep console on uart0 and the HCI on uart1 like
|
||||||
|
so:
|
||||||
|
|
||||||
|
.. code-block:: dts
|
||||||
|
|
||||||
|
/ {
|
||||||
|
chosen {
|
||||||
|
zephyr,console = &uart0;
|
||||||
|
zephyr,shell-uart = &uart0;
|
||||||
|
zephyr,bt-c2h-uart = &uart1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
On the host application, some config options need to be used to select the H4
|
||||||
|
driver instead of the built-in controller:
|
||||||
|
|
||||||
|
.. code-block:: cfg
|
||||||
|
|
||||||
|
CONFIG_BT_HCI=y
|
||||||
|
CONFIG_BT_CTLR=n
|
||||||
|
|
||||||
|
Similarly, the ``zephyr,bt-hci`` DTS property selects which HCI instance to use.
|
||||||
|
The UART needs to have as its child node a HCI UART node:
|
||||||
|
|
||||||
|
.. code-block:: dts
|
||||||
|
|
||||||
|
/ {
|
||||||
|
chosen {
|
||||||
|
zephyr,console = &uart0;
|
||||||
|
zephyr,shell-uart = &uart0;
|
||||||
|
zephyr,bt-hci = &bt_hci_uart;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&uart1 {
|
||||||
|
status = "okay";
|
||||||
|
bt_hci_uart: bt_hci_uart {
|
||||||
|
compatible = "zephyr,bt-hci-uart";
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
};
|
||||||
8
boards/96b_nitrogen.overlay
Normal file
8
boards/96b_nitrogen.overlay
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
/* SPDX-License-Identifier: Apache-2.0 */
|
||||||
|
|
||||||
|
&uart0 {
|
||||||
|
compatible = "nordic,nrf-uart";
|
||||||
|
current-speed = <1000000>;
|
||||||
|
hw-flow-control;
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
8
boards/bbc_microbit.conf
Normal file
8
boards/bbc_microbit.conf
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
CONFIG_MAIN_STACK_SIZE=512
|
||||||
|
CONFIG_IDLE_STACK_SIZE=256
|
||||||
|
CONFIG_ISR_STACK_SIZE=512
|
||||||
|
CONFIG_BT_MAX_CONN=10
|
||||||
|
# Revert values set in prj.conf, set them to their Kconfig default value
|
||||||
|
CONFIG_BT_BUF_CMD_TX_SIZE=65
|
||||||
|
CONFIG_BT_BUF_ACL_RX_SIZE=69
|
||||||
|
CONFIG_BT_BUF_EVT_DISCARDABLE_SIZE=43
|
||||||
4
boards/esp32_devkitc_wroom_procpu.conf
Normal file
4
boards/esp32_devkitc_wroom_procpu.conf
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
CONFIG_CONSOLE=y
|
||||||
|
CONFIG_STDOUT_CONSOLE=y
|
||||||
|
CONFIG_UART_CONSOLE=y
|
||||||
|
CONFIG_BT_MAX_CONN=9
|
||||||
34
boards/esp32_devkitc_wroom_procpu.overlay
Normal file
34
boards/esp32_devkitc_wroom_procpu.overlay
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/ {
|
||||||
|
chosen {
|
||||||
|
zephyr,bt-c2h-uart = &uart1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&pinctrl {
|
||||||
|
|
||||||
|
uart1_default: uart1_default {
|
||||||
|
group1 {
|
||||||
|
pinmux = <UART1_TX_GPIO5>,
|
||||||
|
<UART1_RX_GPIO18>,
|
||||||
|
<UART1_RTS_GPIO19>;
|
||||||
|
};
|
||||||
|
group2 {
|
||||||
|
pinmux = <UART1_CTS_GPIO23>;
|
||||||
|
bias-pull-up;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
&uart1 {
|
||||||
|
status = "okay";
|
||||||
|
current-speed = <921600>;
|
||||||
|
pinctrl-0 = <&uart1_default>;
|
||||||
|
pinctrl-names = "default";
|
||||||
|
};
|
||||||
8
boards/nrf51_blenano.conf
Normal file
8
boards/nrf51_blenano.conf
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
CONFIG_MAIN_STACK_SIZE=512
|
||||||
|
CONFIG_BT_MAX_CONN=10
|
||||||
|
CONFIG_IDLE_STACK_SIZE=256
|
||||||
|
CONFIG_ISR_STACK_SIZE=512
|
||||||
|
# Revert values set in prj.conf, set them to their Kconfig default value
|
||||||
|
CONFIG_BT_BUF_CMD_TX_SIZE=65
|
||||||
|
CONFIG_BT_BUF_ACL_RX_SIZE=69
|
||||||
|
CONFIG_BT_BUF_EVT_DISCARDABLE_SIZE=43
|
||||||
8
boards/nrf51_blenano.overlay
Normal file
8
boards/nrf51_blenano.overlay
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
/* SPDX-License-Identifier: Apache-2.0 */
|
||||||
|
|
||||||
|
&uart0 {
|
||||||
|
compatible = "nordic,nrf-uart";
|
||||||
|
current-speed = <1000000>;
|
||||||
|
status = "okay";
|
||||||
|
hw-flow-control;
|
||||||
|
};
|
||||||
1
boards/nrf51dk_nrf51822.conf
Normal file
1
boards/nrf51dk_nrf51822.conf
Normal file
@@ -0,0 +1 @@
|
|||||||
|
CONFIG_MAIN_STACK_SIZE=512
|
||||||
8
boards/nrf51dk_nrf51822.overlay
Normal file
8
boards/nrf51dk_nrf51822.overlay
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
/* SPDX-License-Identifier: Apache-2.0 */
|
||||||
|
|
||||||
|
&uart0 {
|
||||||
|
compatible = "nordic,nrf-uart";
|
||||||
|
current-speed = <1000000>;
|
||||||
|
status = "okay";
|
||||||
|
hw-flow-control;
|
||||||
|
};
|
||||||
1
boards/nrf51dongle_nrf51822.conf
Normal file
1
boards/nrf51dongle_nrf51822.conf
Normal file
@@ -0,0 +1 @@
|
|||||||
|
CONFIG_MAIN_STACK_SIZE=512
|
||||||
8
boards/nrf51dongle_nrf51822.overlay
Normal file
8
boards/nrf51dongle_nrf51822.overlay
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
/* SPDX-License-Identifier: Apache-2.0 */
|
||||||
|
|
||||||
|
&uart0 {
|
||||||
|
compatible = "nordic,nrf-uart";
|
||||||
|
current-speed = <1000000>;
|
||||||
|
status = "okay";
|
||||||
|
hw-flow-control;
|
||||||
|
};
|
||||||
12
boards/nrf52833dk_nrf52833.overlay
Normal file
12
boards/nrf52833dk_nrf52833.overlay
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 Nordic Semiconductor ASA
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
&uart0 {
|
||||||
|
compatible = "nordic,nrf-uarte";
|
||||||
|
current-speed = <1000000>;
|
||||||
|
status = "okay";
|
||||||
|
hw-flow-control;
|
||||||
|
};
|
||||||
33
boards/nrf52833dk_nrf52833_df.overlay
Normal file
33
boards/nrf52833dk_nrf52833_df.overlay
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 Nordic Semiconductor ASA
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
&uart0 {
|
||||||
|
compatible = "nordic,nrf-uarte";
|
||||||
|
current-speed = <1000000>;
|
||||||
|
status = "okay";
|
||||||
|
hw-flow-control;
|
||||||
|
};
|
||||||
|
|
||||||
|
&radio {
|
||||||
|
status = "okay";
|
||||||
|
/* This is an example number of antennas that may be available
|
||||||
|
* on antenna matrix board.
|
||||||
|
*/
|
||||||
|
dfe-antenna-num = <10>;
|
||||||
|
/* This is an example switch pattern that will be used to set an
|
||||||
|
* antenna for Tx PDU (period before start of Tx CTE).
|
||||||
|
*/
|
||||||
|
dfe-pdu-antenna = <0x0>;
|
||||||
|
|
||||||
|
/* These are example GPIO pin numbers that are provided to
|
||||||
|
* Radio peripheral. The pins will be acquired by Radio to
|
||||||
|
* drive antenna switching when AoD is enabled.
|
||||||
|
*/
|
||||||
|
dfegpio0-gpios = <&gpio0 3 0>;
|
||||||
|
dfegpio1-gpios = <&gpio0 4 0>;
|
||||||
|
dfegpio2-gpios = <&gpio0 28 0>;
|
||||||
|
dfegpio3-gpios = <&gpio0 29 0>;
|
||||||
|
};
|
||||||
8
boards/nrf52840dk_nrf52840.overlay
Normal file
8
boards/nrf52840dk_nrf52840.overlay
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
/* SPDX-License-Identifier: Apache-2.0 */
|
||||||
|
|
||||||
|
&uart0 {
|
||||||
|
compatible = "nordic,nrf-uart";
|
||||||
|
current-speed = <1000000>;
|
||||||
|
status = "okay";
|
||||||
|
hw-flow-control;
|
||||||
|
};
|
||||||
4
boards/nrf52840dongle_nrf52840.conf
Normal file
4
boards/nrf52840dongle_nrf52840.conf
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
CONFIG_USB_DEVICE_STACK=y
|
||||||
|
CONFIG_USB_DEVICE_PRODUCT="Zephyr HCI UART sample"
|
||||||
|
CONFIG_USB_CDC_ACM=y
|
||||||
|
CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n
|
||||||
8
boards/nrf52_blenano2.overlay
Normal file
8
boards/nrf52_blenano2.overlay
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
/* SPDX-License-Identifier: Apache-2.0 */
|
||||||
|
|
||||||
|
&uart0 {
|
||||||
|
compatible = "nordic,nrf-uart";
|
||||||
|
current-speed = <1000000>;
|
||||||
|
status = "okay";
|
||||||
|
hw-flow-control;
|
||||||
|
};
|
||||||
8
boards/nrf52dk_nrf52832.overlay
Normal file
8
boards/nrf52dk_nrf52832.overlay
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
/* SPDX-License-Identifier: Apache-2.0 */
|
||||||
|
|
||||||
|
&uart0 {
|
||||||
|
compatible = "nordic,nrf-uart";
|
||||||
|
current-speed = <1000000>;
|
||||||
|
status = "okay";
|
||||||
|
hw-flow-control;
|
||||||
|
};
|
||||||
8
boards/nrf5340dk_nrf5340_cpuapp.overlay
Normal file
8
boards/nrf5340dk_nrf5340_cpuapp.overlay
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
/* SPDX-License-Identifier: Apache-2.0 */
|
||||||
|
|
||||||
|
&uart0 {
|
||||||
|
compatible = "nordic,nrf-uarte";
|
||||||
|
current-speed = <1000000>;
|
||||||
|
status = "okay";
|
||||||
|
hw-flow-control;
|
||||||
|
};
|
||||||
8
boards/nrf5340dk_nrf5340_cpunet.overlay
Normal file
8
boards/nrf5340dk_nrf5340_cpunet.overlay
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
/* SPDX-License-Identifier: Apache-2.0 */
|
||||||
|
|
||||||
|
&uart0 {
|
||||||
|
compatible = "nordic,nrf-uarte";
|
||||||
|
current-speed = <1000000>;
|
||||||
|
status = "okay";
|
||||||
|
hw-flow-control;
|
||||||
|
};
|
||||||
33
boards/nrf5340dk_nrf5340_cpunet_df.overlay
Normal file
33
boards/nrf5340dk_nrf5340_cpunet_df.overlay
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 Nordic Semiconductor ASA
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
&uart0 {
|
||||||
|
compatible = "nordic,nrf-uarte";
|
||||||
|
current-speed = <1000000>;
|
||||||
|
status = "okay";
|
||||||
|
hw-flow-control;
|
||||||
|
};
|
||||||
|
|
||||||
|
&radio {
|
||||||
|
status = "okay";
|
||||||
|
/* This is an example number of antennas that may be available
|
||||||
|
* on antenna matrix board.
|
||||||
|
*/
|
||||||
|
dfe-antenna-num = <10>;
|
||||||
|
/* This is an example switch pattern that will be used to set an
|
||||||
|
* antenna for Tx PDU (period before start of Tx CTE).
|
||||||
|
*/
|
||||||
|
dfe-pdu-antenna = <0x0>;
|
||||||
|
|
||||||
|
/* These are example GPIO pin numbers that are provided to
|
||||||
|
* Radio peripheral. The pins will be acquired by Radio to
|
||||||
|
* drive antenna switching when AoD is enabled.
|
||||||
|
*/
|
||||||
|
dfegpio0-gpios = <&gpio0 4 0>;
|
||||||
|
dfegpio1-gpios = <&gpio0 5 0>;
|
||||||
|
dfegpio2-gpios = <&gpio0 6 0>;
|
||||||
|
dfegpio3-gpios = <&gpio0 7 0>;
|
||||||
|
};
|
||||||
8
boards/nrf5340pdk_nrf5340_cpuapp.overlay
Normal file
8
boards/nrf5340pdk_nrf5340_cpuapp.overlay
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
/* SPDX-License-Identifier: Apache-2.0 */
|
||||||
|
|
||||||
|
&uart0 {
|
||||||
|
compatible = "nordic,nrf-uarte";
|
||||||
|
current-speed = <1000000>;
|
||||||
|
status = "okay";
|
||||||
|
hw-flow-control;
|
||||||
|
};
|
||||||
12
boards/nrf54l15dk_nrf54l15_cpuapp.overlay
Normal file
12
boards/nrf54l15dk_nrf54l15_cpuapp.overlay
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 Nordic Semiconductor ASA
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
&uart20 {
|
||||||
|
compatible = "nordic,nrf-uarte";
|
||||||
|
current-speed = <1000000>;
|
||||||
|
status = "okay";
|
||||||
|
hw-flow-control;
|
||||||
|
};
|
||||||
33
boards/nrf54l15dk_nrf54l15_cpuapp_df.overlay
Normal file
33
boards/nrf54l15dk_nrf54l15_cpuapp_df.overlay
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 Nordic Semiconductor ASA
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
&uart20 {
|
||||||
|
compatible = "nordic,nrf-uarte";
|
||||||
|
current-speed = <1000000>;
|
||||||
|
status = "okay";
|
||||||
|
hw-flow-control;
|
||||||
|
};
|
||||||
|
|
||||||
|
&radio {
|
||||||
|
status = "okay";
|
||||||
|
/* This is an example number of antennas that may be available
|
||||||
|
* on antenna matrix board.
|
||||||
|
*/
|
||||||
|
dfe-antenna-num = <10>;
|
||||||
|
/* This is an example switch pattern that will be used to set an
|
||||||
|
* antenna for Tx PDU (period before start of Tx CTE).
|
||||||
|
*/
|
||||||
|
dfe-pdu-antenna = <0x0>;
|
||||||
|
|
||||||
|
/* These are example GPIO pin numbers that are provided to
|
||||||
|
* Radio peripheral. The pins will be acquired by Radio to
|
||||||
|
* drive antenna switching when AoD is enabled.
|
||||||
|
*/
|
||||||
|
dfegpio0-gpios = <&gpio1 4 0>;
|
||||||
|
dfegpio1-gpios = <&gpio1 5 0>;
|
||||||
|
dfegpio2-gpios = <&gpio1 6 0>;
|
||||||
|
dfegpio3-gpios = <&gpio1 7 0>;
|
||||||
|
};
|
||||||
4
boards/nrf9160dk_nrf52840.conf
Normal file
4
boards/nrf9160dk_nrf52840.conf
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# Override prj.conf defaults
|
||||||
|
CONFIG_CONSOLE=y
|
||||||
|
CONFIG_STDOUT_CONSOLE=y
|
||||||
|
CONFIG_UART_CONSOLE=y
|
||||||
20
boards/nrf9160dk_nrf52840.overlay
Normal file
20
boards/nrf9160dk_nrf52840.overlay
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2021 Nordic Semiconductor ASA
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <nrf52840/nrf9160dk_nrf52840_reset_on_if5.dtsi>
|
||||||
|
|
||||||
|
#include <nrf52840/nrf9160dk_uart1_on_if0_3.dtsi>
|
||||||
|
|
||||||
|
&uart1 {
|
||||||
|
current-speed = <1000000>;
|
||||||
|
hw-flow-control;
|
||||||
|
};
|
||||||
|
|
||||||
|
/ {
|
||||||
|
chosen {
|
||||||
|
zephyr,bt-c2h-uart=&uart1;
|
||||||
|
};
|
||||||
|
};
|
||||||
8
boards/nrf9160dk_nrf52840_0_14_0.overlay
Normal file
8
boards/nrf9160dk_nrf52840_0_14_0.overlay
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2021 Nordic Semiconductor ASA
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Use the reset line that is available starting from v0.14.0 of the DK. */
|
||||||
|
#include <nrf52840/nrf9160dk_nrf52840_reset_on_if9.dtsi>
|
||||||
7
boards/rv32m1_vega_openisa_rv32m1_ri5cy.conf
Normal file
7
boards/rv32m1_vega_openisa_rv32m1_ri5cy.conf
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#
|
||||||
|
# Copyright 2020, NXP
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
|
||||||
|
CONFIG_UART_INTERRUPT_DRIVEN=y
|
||||||
28
boards/rv32m1_vega_openisa_rv32m1_ri5cy.overlay
Normal file
28
boards/rv32m1_vega_openisa_rv32m1_ri5cy.overlay
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 NXP
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/ {
|
||||||
|
chosen {
|
||||||
|
zephyr,bt-c2h-uart = &lpuart0;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&lptmr1 {
|
||||||
|
interrupt-parent = <&intmux0_ch2>;
|
||||||
|
};
|
||||||
|
|
||||||
|
&intmux0_ch2 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&intmux0_ch3 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&generic_fsk {
|
||||||
|
interrupt-parent = <&intmux0_ch3>;
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
4
boards/yd_esp32_procpu.conf
Normal file
4
boards/yd_esp32_procpu.conf
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
CONFIG_CONSOLE=y
|
||||||
|
CONFIG_STDOUT_CONSOLE=y
|
||||||
|
CONFIG_UART_CONSOLE=y
|
||||||
|
CONFIG_BT_MAX_CONN=9
|
||||||
34
boards/yd_esp32_procpu.overlay
Normal file
34
boards/yd_esp32_procpu.overlay
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/ {
|
||||||
|
chosen {
|
||||||
|
zephyr,bt-c2h-uart = &uart1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&pinctrl {
|
||||||
|
|
||||||
|
uart1_default: uart1_default {
|
||||||
|
group1 {
|
||||||
|
pinmux = <UART1_TX_GPIO5>,
|
||||||
|
<UART1_RX_GPIO18>,
|
||||||
|
<UART1_RTS_GPIO19>;
|
||||||
|
};
|
||||||
|
group2 {
|
||||||
|
pinmux = <UART1_CTS_GPIO23>;
|
||||||
|
bias-pull-up;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
&uart1 {
|
||||||
|
status = "okay";
|
||||||
|
current-speed = <921600>;
|
||||||
|
pinctrl-0 = <&uart1_default>;
|
||||||
|
pinctrl-names = "default";
|
||||||
|
};
|
||||||
21
debug.conf
Normal file
21
debug.conf
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
CONFIG_ASSERT=y
|
||||||
|
|
||||||
|
CONFIG_THREAD_NAME=y
|
||||||
|
CONFIG_THREAD_ANALYZER=y
|
||||||
|
CONFIG_THREAD_ANALYZER_AUTO=y
|
||||||
|
CONFIG_THREAD_ANALYZER_RUN_UNLOCKED=y
|
||||||
|
|
||||||
|
CONFIG_HW_STACK_PROTECTION=y
|
||||||
|
|
||||||
|
CONFIG_CONSOLE=y
|
||||||
|
CONFIG_LOG=y
|
||||||
|
CONFIG_LOG_BUFFER_SIZE=4096
|
||||||
|
CONFIG_RTT_CONSOLE=y
|
||||||
|
CONFIG_LOG_BACKEND_RTT=y
|
||||||
|
CONFIG_LOG_BACKEND_RTT_MODE_DROP=n
|
||||||
|
CONFIG_USE_SEGGER_RTT=y
|
||||||
|
CONFIG_SEGGER_RTT_BUFFER_SIZE_UP=4096
|
||||||
|
CONFIG_LOG_BACKEND_SHOW_COLOR=n
|
||||||
|
CONFIG_LOG_PROCESS_THREAD_STACK_SIZE=1024
|
||||||
|
|
||||||
|
CONFIG_LOG_DEFAULT_LEVEL=3
|
||||||
7
dts/arm/nordic/override.dtsi
Normal file
7
dts/arm/nordic/override.dtsi
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/* Keep default IRQ priority low for peripherals to reduce Radio ISR latency.
|
||||||
|
* ARM Cortex-M4 lowest priority value of 5, i.e. considering Zephyr reserved 2
|
||||||
|
* levels for Exceptions and ZLI (if enabled).
|
||||||
|
* ARM Cortex-M0 lowest priority value of 3, i.e. we use it as Zephyr has no
|
||||||
|
* support for ZLI on Cortex-M0.
|
||||||
|
*/
|
||||||
|
#define NRF_DEFAULT_IRQ_PRIORITY 3
|
||||||
109
overlay-all-bt_ll_sw_split.conf
Normal file
109
overlay-all-bt_ll_sw_split.conf
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
CONFIG_BT_BUF_EVT_RX_COUNT=16
|
||||||
|
|
||||||
|
CONFIG_BT_BUF_EVT_RX_SIZE=255
|
||||||
|
CONFIG_BT_BUF_ACL_RX_SIZE=255
|
||||||
|
CONFIG_BT_BUF_ACL_TX_SIZE=251
|
||||||
|
CONFIG_BT_BUF_CMD_TX_SIZE=255
|
||||||
|
|
||||||
|
# Host and Controller common dependencies
|
||||||
|
CONFIG_BT_EXT_ADV=y
|
||||||
|
CONFIG_BT_PER_ADV=y
|
||||||
|
CONFIG_BT_PER_ADV_SYNC=y
|
||||||
|
CONFIG_BT_PER_ADV_SYNC_MAX=2
|
||||||
|
|
||||||
|
# Broadcast and Connected ISO
|
||||||
|
CONFIG_BT_ISO_BROADCASTER=y
|
||||||
|
CONFIG_BT_ISO_SYNC_RECEIVER=y
|
||||||
|
CONFIG_BT_ISO_CENTRAL=y
|
||||||
|
CONFIG_BT_ISO_PERIPHERAL=y
|
||||||
|
|
||||||
|
# ISO Streams
|
||||||
|
CONFIG_BT_ISO_MAX_CHAN=2
|
||||||
|
|
||||||
|
# Controller
|
||||||
|
CONFIG_BT_LL_SW_SPLIT=y
|
||||||
|
CONFIG_BT_CTLR_ASSERT_HANDLER=y
|
||||||
|
CONFIG_BT_CTLR_DTM_HCI=y
|
||||||
|
|
||||||
|
# Rx ACL and Adv Reports
|
||||||
|
CONFIG_BT_CTLR_RX_BUFFERS=9
|
||||||
|
CONFIG_BT_CTLR_DATA_LENGTH_MAX=251
|
||||||
|
|
||||||
|
# Coded PHY support
|
||||||
|
CONFIG_BT_CTLR_PHY_CODED=y
|
||||||
|
|
||||||
|
# Advertising Sets and Extended Scanning
|
||||||
|
CONFIG_BT_CTLR_ADV_EXT=y
|
||||||
|
CONFIG_BT_CTLR_ADV_SET=3
|
||||||
|
CONFIG_BT_CTLR_ADV_DATA_LEN_MAX=191
|
||||||
|
CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX=1650
|
||||||
|
|
||||||
|
CONFIG_BT_CTLR_ADVANCED_FEATURES=y
|
||||||
|
CONFIG_BT_CTLR_ADV_AUX_SET=3
|
||||||
|
CONFIG_BT_CTLR_ADV_AUX_PDU_BACK2BACK=y
|
||||||
|
CONFIG_BT_CTLR_ADV_SYNC_SET=3
|
||||||
|
CONFIG_BT_CTLR_ADV_SYNC_PDU_BACK2BACK=y
|
||||||
|
CONFIG_BT_CTLR_ADV_DATA_BUF_MAX=6
|
||||||
|
|
||||||
|
# Increase the below to receive interleaved advertising chains
|
||||||
|
CONFIG_BT_CTLR_SCAN_AUX_SET=1
|
||||||
|
|
||||||
|
CONFIG_BT_CTLR_ADV_RESERVE_MAX=n
|
||||||
|
CONFIG_BT_CTLR_CENTRAL_RESERVE_MAX=n
|
||||||
|
CONFIG_BT_CTLR_SLOT_RESERVATION_UPDATE=n
|
||||||
|
CONFIG_BT_CTLR_SCAN_UNRESERVED=y
|
||||||
|
CONFIG_BT_TICKER_NEXT_SLOT_GET_MATCH=y
|
||||||
|
CONFIG_BT_TICKER_EXT=y
|
||||||
|
CONFIG_BT_TICKER_EXT_SLOT_WINDOW_YIELD=y
|
||||||
|
|
||||||
|
# Control Procedure
|
||||||
|
CONFIG_BT_CTLR_LLCP_LOCAL_PROC_CTX_BUF_NUM=6
|
||||||
|
|
||||||
|
# Direction Finding
|
||||||
|
CONFIG_BT_CTLR_DF=y
|
||||||
|
CONFIG_BT_CTLR_DF_PER_ADV_CTE_NUM_MAX=3
|
||||||
|
CONFIG_BT_CTLR_DF_PER_SCAN_CTE_NUM_MAX=3
|
||||||
|
|
||||||
|
# Direction Finding Tx
|
||||||
|
CONFIG_BT_CTLR_DF_CTE_TX=y
|
||||||
|
CONFIG_BT_CTLR_DF_CONN_CTE_TX=y
|
||||||
|
CONFIG_BT_CTLR_DF_ANT_SWITCH_TX=y
|
||||||
|
CONFIG_BT_CTLR_DF_CONN_CTE_RSP=y
|
||||||
|
|
||||||
|
# Direction Finding Rx
|
||||||
|
CONFIG_BT_CTLR_DF_CTE_RX=y
|
||||||
|
CONFIG_BT_CTLR_DF_CONN_CTE_RX=y
|
||||||
|
CONFIG_BT_CTLR_DF_ANT_SWITCH_RX=y
|
||||||
|
CONFIG_BT_CTLR_DF_CONN_CTE_REQ=y
|
||||||
|
|
||||||
|
# ISO Broadcaster Controller
|
||||||
|
CONFIG_BT_CTLR_ADV_EXT=y
|
||||||
|
CONFIG_BT_CTLR_ADV_PERIODIC=y
|
||||||
|
CONFIG_BT_CTLR_ADV_ISO=y
|
||||||
|
CONFIG_BT_CTLR_ADV_ISO_PDU_LEN_MAX=247
|
||||||
|
CONFIG_BT_CTLR_ADV_ISO_STREAM_MAX=2
|
||||||
|
|
||||||
|
# ISO Receive Controller
|
||||||
|
CONFIG_BT_CTLR_ADV_EXT=y
|
||||||
|
CONFIG_BT_CTLR_SYNC_PERIODIC=y
|
||||||
|
CONFIG_BT_CTLR_SYNC_ISO=y
|
||||||
|
CONFIG_BT_CTLR_SYNC_ISO_PDU_LEN_MAX=251
|
||||||
|
CONFIG_BT_CTLR_SYNC_ISO_STREAM_MAX=2
|
||||||
|
|
||||||
|
# ISO Connection Oriented
|
||||||
|
CONFIG_BT_CTLR_CENTRAL_ISO=y
|
||||||
|
CONFIG_BT_CTLR_PERIPHERAL_ISO=y
|
||||||
|
CONFIG_BT_CTLR_CONN_ISO_SDU_LEN_MAX=247
|
||||||
|
CONFIG_BT_CTLR_CONN_ISO_PDU_LEN_MAX=251
|
||||||
|
|
||||||
|
# ISO Transmissions
|
||||||
|
CONFIG_BT_CTLR_ISO_TX_BUFFERS=8
|
||||||
|
CONFIG_BT_CTLR_ISO_TX_BUFFER_SIZE=255
|
||||||
|
CONFIG_BT_CTLR_ISOAL_SOURCES=2
|
||||||
|
|
||||||
|
# ISO Receptions
|
||||||
|
CONFIG_BT_CTLR_ISO_RX_BUFFERS=8
|
||||||
|
CONFIG_BT_CTLR_ISOAL_SINKS=2
|
||||||
|
|
||||||
|
# Tx Power Dynamic Control
|
||||||
|
CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL=y
|
||||||
23
prj.conf
Normal file
23
prj.conf
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
CONFIG_CONSOLE=n
|
||||||
|
CONFIG_STDOUT_CONSOLE=n
|
||||||
|
CONFIG_UART_CONSOLE=n
|
||||||
|
CONFIG_GPIO=y
|
||||||
|
CONFIG_SERIAL=y
|
||||||
|
CONFIG_UART_INTERRUPT_DRIVEN=y
|
||||||
|
CONFIG_BT=y
|
||||||
|
CONFIG_BT_HCI_RAW=y
|
||||||
|
CONFIG_BT_HCI_RAW_H4=y
|
||||||
|
CONFIG_BT_HCI_RAW_H4_ENABLE=y
|
||||||
|
CONFIG_BT_BUF_ACL_RX_SIZE=255
|
||||||
|
CONFIG_BT_BUF_CMD_TX_SIZE=255
|
||||||
|
CONFIG_BT_BUF_EVT_DISCARDABLE_SIZE=255
|
||||||
|
CONFIG_BT_CTLR_ASSERT_HANDLER=y
|
||||||
|
CONFIG_BT_MAX_CONN=16
|
||||||
|
CONFIG_BT_TINYCRYPT_ECC=n
|
||||||
|
CONFIG_BT_CTLR_DTM_HCI=y
|
||||||
|
|
||||||
|
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=512
|
||||||
|
|
||||||
|
# Workaround: Unable to allocate command buffer when using K_NO_WAIT since
|
||||||
|
# Host number of completed commands does not follow normal flow control.
|
||||||
|
CONFIG_BT_BUF_CMD_TX_COUNT=10
|
||||||
81
sample.yaml
Normal file
81
sample.yaml
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
sample:
|
||||||
|
name: Bluetooth HCI UART
|
||||||
|
description: Allows Zephyr to provide Bluetooth connectivity via UART
|
||||||
|
tests:
|
||||||
|
sample.bluetooth.hci_uart.nrf5:
|
||||||
|
harness: bluetooth
|
||||||
|
platform_allow:
|
||||||
|
- nrf52dk/nrf52832
|
||||||
|
tags:
|
||||||
|
- uart
|
||||||
|
- bluetooth
|
||||||
|
sample.bluetooth.hci_uart.nrf52833.df:
|
||||||
|
harness: bluetooth
|
||||||
|
platform_allow: nrf52833dk/nrf52833
|
||||||
|
extra_args:
|
||||||
|
- DTC_OVERLAY_FILE=./boards/nrf52833dk_nrf52833_df.overlay
|
||||||
|
- SNIPPET="bt-ll-sw-split"
|
||||||
|
extra_configs:
|
||||||
|
- CONFIG_BT_CTLR_DF=y
|
||||||
|
tags:
|
||||||
|
- uart
|
||||||
|
- bluetooth
|
||||||
|
sample.bluetooth.hci_uart.nrf5340_netcore.df:
|
||||||
|
harness: bluetooth
|
||||||
|
platform_allow: nrf5340dk/nrf5340/cpunet
|
||||||
|
extra_args:
|
||||||
|
- DTC_OVERLAY_FILE=./boards/nrf5340dk_nrf5340_cpunet_df.overlay
|
||||||
|
- SNIPPET="bt-ll-sw-split"
|
||||||
|
extra_configs:
|
||||||
|
- CONFIG_BT_CTLR_DF=y
|
||||||
|
tags:
|
||||||
|
- uart
|
||||||
|
- bluetooth
|
||||||
|
sample.bluetooth.hci_uart.nrf52833.df.iq_report:
|
||||||
|
harness: bluetooth
|
||||||
|
platform_allow: nrf52833dk/nrf52833
|
||||||
|
extra_args:
|
||||||
|
- DTC_OVERLAY_FILE=./boards/nrf52833dk_nrf52833_df.overlay
|
||||||
|
- SNIPPET="bt-ll-sw-split"
|
||||||
|
extra_configs:
|
||||||
|
- CONFIG_BT_CTLR_DF=y
|
||||||
|
- CONFIG_BT_CTLR_DTM_HCI_DF_IQ_REPORT=y
|
||||||
|
tags:
|
||||||
|
- uart
|
||||||
|
- bluetooth
|
||||||
|
sample.bluetooth.hci_uart.nrf5340_netcore.df.iq_report:
|
||||||
|
harness: bluetooth
|
||||||
|
platform_allow: nrf5340dk/nrf5340/cpunet
|
||||||
|
extra_args:
|
||||||
|
- DTC_OVERLAY_FILE=./boards/nrf5340dk_nrf5340_cpunet_df.overlay
|
||||||
|
- SNIPPET="bt-ll-sw-split"
|
||||||
|
extra_configs:
|
||||||
|
- CONFIG_BT_CTLR_DF=y
|
||||||
|
- CONFIG_BT_CTLR_DTM_HCI_DF_IQ_REPORT=y
|
||||||
|
tags:
|
||||||
|
- uart
|
||||||
|
- bluetooth
|
||||||
|
sample.bluetooth.hci_uart.nrf52833.all:
|
||||||
|
harness: bluetooth
|
||||||
|
platform_allow: nrf52833dk/nrf52833
|
||||||
|
integration_platforms:
|
||||||
|
- nrf52833dk/nrf52833
|
||||||
|
extra_args:
|
||||||
|
- OVERLAY_CONFIG=overlay-all-bt_ll_sw_split.conf
|
||||||
|
- DTC_OVERLAY_FILE=./boards/nrf52833dk_nrf52833_df.overlay
|
||||||
|
- SNIPPET="bt-ll-sw-split"
|
||||||
|
tags:
|
||||||
|
- uart
|
||||||
|
- bluetooth
|
||||||
|
sample.bluetooth.hci_uart.nrf54l15.all:
|
||||||
|
harness: bluetooth
|
||||||
|
platform_allow: nrf54l15dk/nrf54l15/cpuapp
|
||||||
|
integration_platforms:
|
||||||
|
- nrf54l15dk/nrf54l15/cpuapp
|
||||||
|
extra_args:
|
||||||
|
- OVERLAY_CONFIG=overlay-all-bt_ll_sw_split.conf
|
||||||
|
- DTC_OVERLAY_FILE=./boards/nrf54l15dk_nrf54l15_cpuapp_df.overlay
|
||||||
|
- SNIPPET="bt-ll-sw-split"
|
||||||
|
tags:
|
||||||
|
- uart
|
||||||
|
- bluetooth
|
||||||
413
src/main.c
Normal file
413
src/main.c
Normal file
@@ -0,0 +1,413 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Nordic Semiconductor ASA
|
||||||
|
* Copyright (c) 2015-2016 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <zephyr/kernel.h>
|
||||||
|
#include <zephyr/arch/cpu.h>
|
||||||
|
#include <zephyr/sys/byteorder.h>
|
||||||
|
#include <zephyr/logging/log.h>
|
||||||
|
#include <zephyr/sys/util.h>
|
||||||
|
|
||||||
|
#include <zephyr/device.h>
|
||||||
|
#include <zephyr/init.h>
|
||||||
|
#include <zephyr/drivers/uart.h>
|
||||||
|
|
||||||
|
#include <zephyr/usb/usb_device.h>
|
||||||
|
|
||||||
|
#include <zephyr/net_buf.h>
|
||||||
|
#include <zephyr/bluetooth/bluetooth.h>
|
||||||
|
#include <zephyr/bluetooth/l2cap.h>
|
||||||
|
#include <zephyr/bluetooth/hci.h>
|
||||||
|
#include <zephyr/bluetooth/buf.h>
|
||||||
|
#include <zephyr/bluetooth/hci_raw.h>
|
||||||
|
|
||||||
|
#define LOG_MODULE_NAME hci_uart
|
||||||
|
LOG_MODULE_REGISTER(LOG_MODULE_NAME);
|
||||||
|
|
||||||
|
static const struct device *const hci_uart_dev =
|
||||||
|
DEVICE_DT_GET(DT_CHOSEN(zephyr_bt_c2h_uart));
|
||||||
|
static K_THREAD_STACK_DEFINE(tx_thread_stack, CONFIG_BT_HCI_TX_STACK_SIZE);
|
||||||
|
static struct k_thread tx_thread_data;
|
||||||
|
static K_FIFO_DEFINE(tx_queue);
|
||||||
|
|
||||||
|
/* RX in terms of bluetooth communication */
|
||||||
|
static K_FIFO_DEFINE(uart_tx_queue);
|
||||||
|
|
||||||
|
#define H4_CMD 0x01
|
||||||
|
#define H4_ACL 0x02
|
||||||
|
#define H4_SCO 0x03
|
||||||
|
#define H4_EVT 0x04
|
||||||
|
#define H4_ISO 0x05
|
||||||
|
|
||||||
|
/* Receiver states. */
|
||||||
|
#define ST_IDLE 0 /* Waiting for packet type. */
|
||||||
|
#define ST_HDR 1 /* Receiving packet header. */
|
||||||
|
#define ST_PAYLOAD 2 /* Receiving packet payload. */
|
||||||
|
#define ST_DISCARD 3 /* Dropping packet. */
|
||||||
|
|
||||||
|
/* Length of a discard/flush buffer.
|
||||||
|
* This is sized to align with a BLE HCI packet:
|
||||||
|
* 1 byte H:4 header + 32 bytes ACL/event data
|
||||||
|
* Bigger values might overflow the stack since this is declared as a local
|
||||||
|
* variable, smaller ones will force the caller to call into discard more
|
||||||
|
* often.
|
||||||
|
*/
|
||||||
|
#define H4_DISCARD_LEN 33
|
||||||
|
|
||||||
|
static int h4_read(const struct device *uart, uint8_t *buf, size_t len)
|
||||||
|
{
|
||||||
|
int rx = uart_fifo_read(uart, buf, len);
|
||||||
|
|
||||||
|
LOG_DBG("read %d req %d", rx, len);
|
||||||
|
|
||||||
|
return rx;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool valid_type(uint8_t type)
|
||||||
|
{
|
||||||
|
return (type == H4_CMD) | (type == H4_ACL) | (type == H4_ISO);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Function expects that type is validated and only CMD, ISO or ACL will be used. */
|
||||||
|
static uint32_t get_len(const uint8_t *hdr_buf, uint8_t type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case H4_CMD:
|
||||||
|
return ((const struct bt_hci_cmd_hdr *)hdr_buf)->param_len;
|
||||||
|
case H4_ISO:
|
||||||
|
return bt_iso_hdr_len(
|
||||||
|
sys_le16_to_cpu(((const struct bt_hci_iso_hdr *)hdr_buf)->len));
|
||||||
|
case H4_ACL:
|
||||||
|
return sys_le16_to_cpu(((const struct bt_hci_acl_hdr *)hdr_buf)->len);
|
||||||
|
default:
|
||||||
|
LOG_ERR("Invalid type: %u", type);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Function expects that type is validated and only CMD, ISO or ACL will be used. */
|
||||||
|
static int hdr_len(uint8_t type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case H4_CMD:
|
||||||
|
return sizeof(struct bt_hci_cmd_hdr);
|
||||||
|
case H4_ISO:
|
||||||
|
return sizeof(struct bt_hci_iso_hdr);
|
||||||
|
case H4_ACL:
|
||||||
|
return sizeof(struct bt_hci_acl_hdr);
|
||||||
|
default:
|
||||||
|
LOG_ERR("Invalid type: %u", type);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rx_isr(void)
|
||||||
|
{
|
||||||
|
static struct net_buf *buf;
|
||||||
|
static int remaining;
|
||||||
|
static uint8_t state;
|
||||||
|
static uint8_t type;
|
||||||
|
static uint8_t hdr_buf[MAX(sizeof(struct bt_hci_cmd_hdr),
|
||||||
|
sizeof(struct bt_hci_acl_hdr))];
|
||||||
|
int read;
|
||||||
|
|
||||||
|
do {
|
||||||
|
switch (state) {
|
||||||
|
case ST_IDLE:
|
||||||
|
/* Get packet type */
|
||||||
|
read = h4_read(hci_uart_dev, &type, sizeof(type));
|
||||||
|
/* since we read in loop until no data is in the fifo,
|
||||||
|
* it is possible that read = 0.
|
||||||
|
*/
|
||||||
|
if (read) {
|
||||||
|
if (valid_type(type)) {
|
||||||
|
/* Get expected header size and switch
|
||||||
|
* to receiving header.
|
||||||
|
*/
|
||||||
|
remaining = hdr_len(type);
|
||||||
|
state = ST_HDR;
|
||||||
|
} else {
|
||||||
|
LOG_WRN("Unknown header %d", type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ST_HDR:
|
||||||
|
read = h4_read(hci_uart_dev,
|
||||||
|
&hdr_buf[hdr_len(type) - remaining],
|
||||||
|
remaining);
|
||||||
|
remaining -= read;
|
||||||
|
if (remaining == 0) {
|
||||||
|
/* Header received. Allocate buffer and get
|
||||||
|
* payload length. If allocation fails leave
|
||||||
|
* interrupt. On failed allocation state machine
|
||||||
|
* is reset.
|
||||||
|
*/
|
||||||
|
buf = bt_buf_get_tx(BT_BUF_H4, K_NO_WAIT,
|
||||||
|
&type, sizeof(type));
|
||||||
|
if (!buf) {
|
||||||
|
LOG_ERR("No available command buffers!");
|
||||||
|
state = ST_IDLE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
remaining = get_len(hdr_buf, type);
|
||||||
|
|
||||||
|
net_buf_add_mem(buf, hdr_buf, hdr_len(type));
|
||||||
|
if (remaining > net_buf_tailroom(buf)) {
|
||||||
|
LOG_ERR("Not enough space in buffer");
|
||||||
|
net_buf_unref(buf);
|
||||||
|
state = ST_DISCARD;
|
||||||
|
} else {
|
||||||
|
state = ST_PAYLOAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ST_PAYLOAD:
|
||||||
|
read = h4_read(hci_uart_dev, net_buf_tail(buf),
|
||||||
|
remaining);
|
||||||
|
buf->len += read;
|
||||||
|
remaining -= read;
|
||||||
|
if (remaining == 0) {
|
||||||
|
/* Packet received */
|
||||||
|
LOG_DBG("putting RX packet in queue.");
|
||||||
|
k_fifo_put(&tx_queue, buf);
|
||||||
|
state = ST_IDLE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ST_DISCARD:
|
||||||
|
{
|
||||||
|
uint8_t discard[H4_DISCARD_LEN];
|
||||||
|
size_t to_read = MIN(remaining, sizeof(discard));
|
||||||
|
|
||||||
|
read = h4_read(hci_uart_dev, discard, to_read);
|
||||||
|
remaining -= read;
|
||||||
|
if (remaining == 0) {
|
||||||
|
state = ST_IDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
read = 0;
|
||||||
|
__ASSERT_NO_MSG(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
} while (read);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tx_isr(void)
|
||||||
|
{
|
||||||
|
static struct net_buf *buf;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (!buf) {
|
||||||
|
buf = k_fifo_get(&uart_tx_queue, K_NO_WAIT);
|
||||||
|
if (!buf) {
|
||||||
|
uart_irq_tx_disable(hci_uart_dev);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
len = uart_fifo_fill(hci_uart_dev, buf->data, buf->len);
|
||||||
|
net_buf_pull(buf, len);
|
||||||
|
if (!buf->len) {
|
||||||
|
net_buf_unref(buf);
|
||||||
|
buf = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bt_uart_isr(const struct device *unused, void *user_data)
|
||||||
|
{
|
||||||
|
ARG_UNUSED(unused);
|
||||||
|
ARG_UNUSED(user_data);
|
||||||
|
|
||||||
|
if (!(uart_irq_rx_ready(hci_uart_dev) ||
|
||||||
|
uart_irq_tx_ready(hci_uart_dev))) {
|
||||||
|
LOG_DBG("spurious interrupt");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uart_irq_tx_ready(hci_uart_dev)) {
|
||||||
|
tx_isr();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uart_irq_rx_ready(hci_uart_dev)) {
|
||||||
|
rx_isr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = k_fifo_get(&tx_queue, K_FOREVER);
|
||||||
|
/* Pass buffer to the stack */
|
||||||
|
err = bt_send(buf);
|
||||||
|
if (err) {
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
k_yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int h4_send(struct net_buf *buf)
|
||||||
|
{
|
||||||
|
LOG_DBG("buf %p type %u len %u", buf, bt_buf_get_type(buf),
|
||||||
|
buf->len);
|
||||||
|
|
||||||
|
k_fifo_put(&uart_tx_queue, buf);
|
||||||
|
uart_irq_tx_enable(hci_uart_dev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_BT_CTLR_ASSERT_HANDLER)
|
||||||
|
void bt_ctlr_assert_handle(char *file, uint32_t line)
|
||||||
|
{
|
||||||
|
uint32_t len = 0U, pos = 0U;
|
||||||
|
|
||||||
|
/* Disable interrupts, this is unrecoverable */
|
||||||
|
(void)irq_lock();
|
||||||
|
|
||||||
|
uart_irq_rx_disable(hci_uart_dev);
|
||||||
|
uart_irq_tx_disable(hci_uart_dev);
|
||||||
|
|
||||||
|
if (file) {
|
||||||
|
while (file[len] != '\0') {
|
||||||
|
if (file[len] == '/') {
|
||||||
|
pos = len + 1;
|
||||||
|
}
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
file += pos;
|
||||||
|
len -= pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
uart_poll_out(hci_uart_dev, H4_EVT);
|
||||||
|
/* Vendor-Specific debug event */
|
||||||
|
uart_poll_out(hci_uart_dev, 0xff);
|
||||||
|
/* 0xAA + strlen + \0 + 32-bit line number */
|
||||||
|
uart_poll_out(hci_uart_dev, 1 + len + 1 + 4);
|
||||||
|
uart_poll_out(hci_uart_dev, 0xAA);
|
||||||
|
|
||||||
|
if (len) {
|
||||||
|
while (*file != '\0') {
|
||||||
|
uart_poll_out(hci_uart_dev, *file);
|
||||||
|
file++;
|
||||||
|
}
|
||||||
|
uart_poll_out(hci_uart_dev, 0x00);
|
||||||
|
}
|
||||||
|
|
||||||
|
uart_poll_out(hci_uart_dev, line >> 0 & 0xff);
|
||||||
|
uart_poll_out(hci_uart_dev, line >> 8 & 0xff);
|
||||||
|
uart_poll_out(hci_uart_dev, line >> 16 & 0xff);
|
||||||
|
uart_poll_out(hci_uart_dev, line >> 24 & 0xff);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BT_CTLR_ASSERT_HANDLER */
|
||||||
|
|
||||||
|
static int hci_uart_init(void)
|
||||||
|
{
|
||||||
|
LOG_DBG("");
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_USB_CDC_ACM)) {
|
||||||
|
if (usb_enable(NULL)) {
|
||||||
|
LOG_ERR("Failed to enable USB");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!device_is_ready(hci_uart_dev)) {
|
||||||
|
LOG_ERR("HCI UART %s is not ready", hci_uart_dev->name);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uart_irq_rx_disable(hci_uart_dev);
|
||||||
|
uart_irq_tx_disable(hci_uart_dev);
|
||||||
|
|
||||||
|
uart_irq_callback_set(hci_uart_dev, bt_uart_isr);
|
||||||
|
|
||||||
|
uart_irq_rx_enable(hci_uart_dev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SYS_INIT(hci_uart_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
/* incoming events and data from the controller */
|
||||||
|
static K_FIFO_DEFINE(rx_queue);
|
||||||
|
int err;
|
||||||
|
|
||||||
|
LOG_DBG("Start");
|
||||||
|
__ASSERT(hci_uart_dev, "UART device is NULL");
|
||||||
|
|
||||||
|
/* Enable the raw interface, this will in turn open the HCI driver */
|
||||||
|
bt_enable_raw(&rx_queue);
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_BT_WAIT_NOP)) {
|
||||||
|
/* Issue a Command Complete with NOP */
|
||||||
|
int i;
|
||||||
|
|
||||||
|
const struct {
|
||||||
|
const uint8_t h4;
|
||||||
|
const struct bt_hci_evt_hdr hdr;
|
||||||
|
const struct bt_hci_evt_cmd_complete cc;
|
||||||
|
} __packed cc_evt = {
|
||||||
|
.h4 = H4_EVT,
|
||||||
|
.hdr = {
|
||||||
|
.evt = BT_HCI_EVT_CMD_COMPLETE,
|
||||||
|
.len = sizeof(struct bt_hci_evt_cmd_complete),
|
||||||
|
},
|
||||||
|
.cc = {
|
||||||
|
.ncmd = 1,
|
||||||
|
.opcode = sys_cpu_to_le16(BT_OP_NOP),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(cc_evt); i++) {
|
||||||
|
uart_poll_out(hci_uart_dev,
|
||||||
|
*(((const uint8_t *)&cc_evt)+i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Spawn the TX thread and start feeding commands and data to the
|
||||||
|
* controller
|
||||||
|
*/
|
||||||
|
k_thread_create(&tx_thread_data, tx_thread_stack,
|
||||||
|
K_THREAD_STACK_SIZEOF(tx_thread_stack), tx_thread,
|
||||||
|
NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT);
|
||||||
|
k_thread_name_set(&tx_thread_data, "HCI uart TX");
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
struct net_buf *buf;
|
||||||
|
|
||||||
|
buf = k_fifo_get(&rx_queue, K_FOREVER);
|
||||||
|
err = h4_send(buf);
|
||||||
|
if (err) {
|
||||||
|
LOG_ERR("Failed to send");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user