diff --git a/port/nrf5-zephyr/hci_firmware.patch b/port/nrf5-zephyr/hci_firmware.patch index 3f269d818..3a0a4523c 100644 --- a/port/nrf5-zephyr/hci_firmware.patch +++ b/port/nrf5-zephyr/hci_firmware.patch @@ -1,60 +1,55 @@ -diff --git a/samples/bluetooth/hci_uart/flash_nrf51_pca10028.sh b/samples/bluetooth/hci_uart/flash_nrf51_pca10028.sh -new file mode 100755 -index 0000000..d51907f ---- /dev/null -+++ b/samples/bluetooth/hci_uart/flash_nrf51_pca10028.sh -@@ -0,0 +1,4 @@ -+#!/bin/sh -+nrfjprog --eraseall -f nrf51 -+nrfjprog --program outdir/nrf51_pca10028/zephyr.hex -f nrf51 -+nrfjprog --reset -f nrf51 -diff --git a/samples/bluetooth/hci_uart/flash_nrf52_pca10040.sh b/samples/bluetooth/hci_uart/flash_nrf52_pca10040.sh -new file mode 100755 -index 0000000..cc20145 ---- /dev/null -+++ b/samples/bluetooth/hci_uart/flash_nrf52_pca10040.sh -@@ -0,0 +1,4 @@ -+#!/bin/sh -+nrfjprog --eraseall -f nrf52 -+nrfjprog --program outdir/nrf52_pca10040/zephyr.hex -f nrf52 -+nrfjprog --reset -f nrf52 diff --git a/samples/bluetooth/hci_uart/nrf5.conf b/samples/bluetooth/hci_uart/nrf5.conf -index c3b362d..9fe511f 100644 +index 8b268bc73..b00853925 100644 --- a/samples/bluetooth/hci_uart/nrf5.conf +++ b/samples/bluetooth/hci_uart/nrf5.conf -@@ -7,6 +7,6 @@ CONFIG_UART_INTERRUPT_DRIVEN=y - CONFIG_BLUETOOTH=y - CONFIG_BLUETOOTH_HCI_RAW=y - CONFIG_BLUETOOTH_MAX_CONN=16 +@@ -4,7 +4,7 @@ CONFIG_UART_CONSOLE=n + CONFIG_GPIO=y + CONFIG_SERIAL=y + CONFIG_UART_INTERRUPT_DRIVEN=y -CONFIG_UART_NRF5_BAUD_RATE=1000000 +CONFIG_UART_NRF5_BAUD_RATE=115200 CONFIG_UART_NRF5_FLOW_CONTROL=y - CONFIG_BLUETOOTH_CONTROLLER_ASSERT_HANDLER=y + CONFIG_MAIN_STACK_SIZE=512 + CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=512 diff --git a/samples/bluetooth/hci_uart/src/Makefile b/samples/bluetooth/hci_uart/src/Makefile -index b666967..8606b24 100644 +index ae704cee5..833816b50 100644 --- a/samples/bluetooth/hci_uart/src/Makefile +++ b/samples/bluetooth/hci_uart/src/Makefile -@@ -1 +1,2 @@ +@@ -1,3 +1,4 @@ + ccflags-y += -I${ZEPHYR_BASE}/subsys/bluetooth + obj-y += main.o +ccflags-y += -I../../../subsys/bluetooth/controller/ll_sw diff --git a/samples/bluetooth/hci_uart/src/main.c b/samples/bluetooth/hci_uart/src/main.c -index 76e75e1..70da655 100644 +index c21d76215..c8680a43d 100644 --- a/samples/bluetooth/hci_uart/src/main.c +++ b/samples/bluetooth/hci_uart/src/main.c -@@ -36,6 +36,9 @@ - #include - #include +@@ -29,6 +29,9 @@ + + #include "common/log.h" +#include "ll.h" +#include "nrf.h" + static struct device *hci_uart_dev; - - #define STACK_SIZE 1024 -@@ -354,6 +357,18 @@ static int hci_uart_init(struct device *unused) + static BT_STACK_NOINIT(tx_thread_stack, CONFIG_BT_HCI_TX_STACK_SIZE); + static struct k_thread tx_thread_data; +@@ -341,6 +344,30 @@ static int hci_uart_init(struct device *unused) DEVICE_INIT(hci_uart, "hci_uart", &hci_uart_init, NULL, NULL, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); ++void little_endian_store_16(uint8_t *buffer, uint16_t pos, uint16_t value){ ++ buffer[pos++] = value; ++ buffer[pos++] = value >> 8; ++} ++ ++void little_endian_store_32(uint8_t *buffer, uint16_t pos, uint32_t value){ ++ buffer[pos++] = value; ++ buffer[pos++] = value >> 8; ++ buffer[pos++] = value >> 16; ++ buffer[pos++] = value >> 24; ++} ++ +void little_endian_store_16(uint8_t *buffer, uint16_t pos, uint16_t value){ + buffer[pos++] = value; + buffer[pos++] = value >> 8; @@ -70,29 +65,65 @@ index 76e75e1..70da655 100644 void main(void) { /* incoming events and data from the controller */ -@@ -373,6 +388,12 @@ void main(void) - NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); +@@ -351,6 +378,13 @@ void main(void) + /* Enable the raw interface, this will in turn open the HCI driver */ bt_enable_raw(&rx_queue); -+ ++ + // make Random Static Address available via HCI Read BD ADDR as fake public address + uint8_t addr[6]; + little_endian_store_16(addr, 4, NRF_FICR->DEVICEADDR[1] | 0xc000); + little_endian_store_32(addr, 0, NRF_FICR->DEVICEADDR[0]); + ll_address_set(0, addr); - - while (1) { - struct net_buf *buf; ++ + /* Spawn the TX thread and start feeding commands and data to the + * controller + */ diff --git a/subsys/bluetooth/controller/ll_sw/ctrl.h b/subsys/bluetooth/controller/ll_sw/ctrl.h -index f9b092d..b950083 100644 +index ecec3ccc3..88cdba5fc 100644 --- a/subsys/bluetooth/controller/ll_sw/ctrl.h +++ b/subsys/bluetooth/controller/ll_sw/ctrl.h -@@ -79,7 +79,7 @@ - * Controller Interface Defines - ****************************************************************************/ - #define RADIO_BLE_VERSION_NUMBER (0x08) --#define RADIO_BLE_COMPANY_ID (0xFFFF) +@@ -128,7 +128,7 @@ + #if defined(CONFIG_BT_CTLR_COMPANY_ID) + #define RADIO_BLE_COMPANY_ID CONFIG_BT_CTLR_COMPANY_ID + #else +-#define RADIO_BLE_COMPANY_ID 0xFFFF +#define RADIO_BLE_COMPANY_ID (0x0059) // Nordic Semiconductor ASA - #define RADIO_BLE_SUB_VERSION_NUMBER (0xFFFF) - #define RADIO_BLE_FEATURES (0x1F) /* LE Ping, Slave Initiated - * Feature request, Extended + #endif + #if defined(CONFIG_BT_CTLR_SUBVERSION_NUMBER) + #define RADIO_BLE_SUB_VERSION_NUMBER \ +diff --git a/drivers/serial/uart_nrf5.c b/drivers/serial/uart_nrf5.c +index e8ebfa5d9..9a5c70e1e 100644 +--- a/drivers/serial/uart_nrf5.c ++++ b/drivers/serial/uart_nrf5.c +@@ -227,7 +227,7 @@ static int uart_nrf5_init(struct device *dev) + + #endif /* CONFIG_UART_NRF5_FLOW_CONTROL */ + +- DEV_DATA(dev)->baud_rate = CONFIG_UART_NRF5_BAUD_RATE; ++ DEV_DATA(dev)->baud_rate = 115200; + + /* Set baud rate */ + err = baudrate_set(dev, DEV_DATA(dev)->baud_rate, +diff --git a/subsys/Kconfig b/subsys/Kconfig +index 4966a0b81..546713963 100644 +--- a/subsys/Kconfig ++++ b/subsys/Kconfig +@@ -24,3 +24,5 @@ source "subsys/net/Kconfig" + source "subsys/shell/Kconfig" + + source "subsys/usb/Kconfig" ++ ++source "subsys/btstack/Kconfig" +diff --git a/subsys/Makefile b/subsys/Makefile +index a9a2aa153..94da28f17 100644 +--- a/subsys/Makefile ++++ b/subsys/Makefile +@@ -1,6 +1,7 @@ + obj-$(CONFIG_FILE_SYSTEM) += fs/ + obj-$(CONFIG_USB) += usb/ + obj-$(CONFIG_BT) += bluetooth/ ++obj-$(CONFIG_BTSTACK) += btstack/ + obj-$(CONFIG_NET_BUF) += net/ + obj-$(CONFIG_CONSOLE_SHELL) += shell/ + obj-$(CONFIG_CONSOLE_PULL) += console/ diff --git a/port/nrf5-zephyr/main.c b/port/nrf5-zephyr/main.c index ca4a729e5..7c1ce675a 100644 --- a/port/nrf5-zephyr/main.c +++ b/port/nrf5-zephyr/main.c @@ -1,77 +1,39 @@ /* - * Copyright (C) 2016 BlueKitchen GmbH - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * 4. Any redistribution, use, or modification is done solely for - * personal benefit and not for any commercial purpose or for - * monetary gain. - * - * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS - * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF - * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Please inquire about commercial licensing options at - * contact@bluekitchen-gmbh.com + * Copyright (c) 2016 Nordic Semiconductor ASA + * Copyright (c) 2015-2016 Intel Corporation * + * SPDX-License-Identifier: Apache-2.0 */ -#define __BTSTACK_FILE__ "main.c" - /** - * BTstack port for Zephyr Bluetooth Controller - * - * Data Sources aside from the HCI Controller are not supported yet - * Timers are supported by waiting on the HCI Controller RX queue until the next timeout is due - */ - -// libc #include #include #include #include -// zephyr +#include #include +#include +#include +#include + #include #include -#include -#include -#include -#include -#include -#include #include -#include -// Bluetooth Controller -#include "ll.h" +#include #include +#include #include #include #include -// Nordic NFK +#include "ll.h" + +// Nordic NDK #include "nrf.h" +#include "common/log.h" + // BTstack #include "btstack_debug.h" #include "btstack_event.h" @@ -81,50 +43,45 @@ #include "hci_dump.h" #include "hci_transport.h" -static btstack_packet_callback_registration_t hci_event_callback_registration; +// static struct device *hci_uart_dev; +// static BT_STACK_NOINIT(tx_thread_stack, CONFIG_BT_HCI_TX_STACK_SIZE); +// static struct k_thread tx_thread_data; -static void (*transport_packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size); +/* HCI command buffers */ +#define CMD_BUF_SIZE BT_BUF_RX_SIZE +NET_BUF_POOL_DEFINE(cmd_tx_pool, CONFIG_BT_HCI_CMD_COUNT, CMD_BUF_SIZE, BT_BUF_USER_DATA_MIN, NULL); + +#if defined(CONFIG_BT_CTLR) +#define BT_L2CAP_MTU (CONFIG_BT_CTLR_TX_BUFFER_SIZE - BT_L2CAP_HDR_SIZE) +#else +#define BT_L2CAP_MTU 65 /* 64-byte public key + opcode */ +#endif /* CONFIG_BT_CTLR */ + +/** Data size needed for ACL buffers */ +#define BT_BUF_ACL_SIZE BT_L2CAP_BUF_SIZE(BT_L2CAP_MTU) + +#if defined(CONFIG_BT_CTLR_TX_BUFFERS) +#define TX_BUF_COUNT CONFIG_BT_CTLR_TX_BUFFERS +#else +#define TX_BUF_COUNT 6 +#endif + +NET_BUF_POOL_DEFINE(acl_tx_pool, TX_BUF_COUNT, BT_BUF_ACL_SIZE, BT_BUF_USER_DATA_MIN, NULL); + +static K_FIFO_DEFINE(tx_queue); +static K_FIFO_DEFINE(rx_queue); // // hci_transport_zephyr.c // -/* HCI command buffers */ -#define CMD_BUF_SIZE (CONFIG_BLUETOOTH_HCI_SEND_RESERVE + \ - sizeof(struct bt_hci_cmd_hdr) + \ - CONFIG_BLUETOOTH_MAX_CMD_LEN) - -static struct nano_fifo avail_cmd_tx; -static NET_BUF_POOL(cmd_tx_pool, CONFIG_BLUETOOTH_HCI_CMD_COUNT, CMD_BUF_SIZE, - &avail_cmd_tx, NULL, BT_BUF_USER_DATA_MIN); - -#define BT_L2CAP_MTU 64 -/** Data size needed for ACL buffers */ -#define BT_BUF_ACL_SIZE (CONFIG_BLUETOOTH_HCI_RECV_RESERVE + \ - sizeof(struct bt_hci_acl_hdr) + \ - 4 /* L2CAP header size */ + \ - BT_L2CAP_MTU) - -static struct nano_fifo avail_acl_tx; -static NET_BUF_POOL(acl_tx_pool, CONFIG_BLUETOOTH_CONTROLLER_TX_BUFFERS, - BT_BUF_ACL_SIZE, &avail_acl_tx, NULL, BT_BUF_USER_DATA_MIN); - -static struct nano_fifo rx_queue; -static struct nano_fifo tx_queue; +static void (*transport_packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size); /** * init transport * @param transport_config */ static void transport_init(const void *transport_config){ - /* Initialize the buffer pools */ - net_buf_pool_init(cmd_tx_pool); - net_buf_pool_init(acl_tx_pool); - - /* Initialize the FIFOs */ - nano_fifo_init(&tx_queue); - nano_fifo_init(&rx_queue); - /* startup Controller */ bt_enable_raw(&rx_queue); } @@ -161,7 +118,7 @@ static int transport_send_packet(uint8_t packet_type, uint8_t *packet, int size) struct net_buf *buf; switch (packet_type){ case HCI_COMMAND_DATA_PACKET: - buf = net_buf_get(&avail_cmd_tx, 0); + buf = net_buf_alloc(&cmd_tx_pool, K_NO_WAIT); if (buf) { bt_buf_set_type(buf, BT_BUF_CMD); memcpy(net_buf_add(buf, size), packet, size); @@ -171,7 +128,7 @@ static int transport_send_packet(uint8_t packet_type, uint8_t *packet, int size) } break; case HCI_ACL_DATA_PACKET: - buf = net_buf_get(&avail_acl_tx, 0); + buf = net_buf_alloc(&acl_tx_pool, K_NO_WAIT); if (buf) { bt_buf_set_type(buf, BT_BUF_ACL_OUT); memcpy(net_buf_add(buf, size), packet, size); @@ -222,26 +179,19 @@ static void transport_deliver_controller_packet(struct net_buf * buf){ net_buf_unref(buf); } + // btstack_run_loop_zephry.c // the run loop static btstack_linked_list_t timers; -static int sys_clock_ms_per_tick; // set in btstack_run_loop_zephyr_init() - +// TODO: handle 32 bit ms time overrun static uint32_t btstack_run_loop_zephyr_get_time_ms(void){ - return sys_tick_get_32() * sys_clock_ms_per_tick; -} - -static uint32_t btstack_run_loop_zephyr_ticks_for_ms(uint32_t time_in_ms){ - return time_in_ms / sys_clock_ms_per_tick; + return k_uptime_get_32(); } static void btstack_run_loop_zephyr_set_timer(btstack_timer_source_t *ts, uint32_t timeout_in_ms){ - uint32_t ticks = btstack_run_loop_zephyr_ticks_for_ms(timeout_in_ms); - if (ticks == 0) ticks++; - // time until next tick is < hal_tick_get_tick_period_in_ms() and we don't know, so we add one - ts->timeout = sys_tick_get_32() + 1 + ticks; + ts->timeout = k_uptime_get_32() + 1 + timeout_in_ms; } /** @@ -287,10 +237,10 @@ static void btstack_run_loop_zephyr_dump_timer(void){ static void btstack_run_loop_zephyr_execute(void) { while (1) { // get next timeout - int32_t timeout_ticks = TICKS_UNLIMITED; + int32_t timeout_ticks = K_FOREVER; if (timers) { btstack_timer_source_t * ts = (btstack_timer_source_t *) timers; - uint32_t now = sys_tick_get_32(); + uint32_t now = k_uptime_get_32(); if (ts->timeout < now){ // remove timer before processing it to allow handler to re-register with run loop btstack_run_loop_remove_timer(ts); @@ -302,7 +252,7 @@ static void btstack_run_loop_zephyr_execute(void) { } // process RX fifo only - struct net_buf *buf = net_buf_get_timeout(&rx_queue, 0, timeout_ticks); + struct net_buf *buf = net_buf_get(&rx_queue, timeout_ticks); if (buf){ transport_deliver_controller_packet(buf); } @@ -311,8 +261,6 @@ static void btstack_run_loop_zephyr_execute(void) { static void btstack_run_loop_zephyr_btstack_run_loop_init(void){ timers = NULL; - sys_clock_ms_per_tick = sys_clock_us_per_tick / 1000; - log_info("btstack_run_loop_init: ms_per_tick %u", sys_clock_ms_per_tick); } static const btstack_run_loop_t btstack_run_loop_wiced = { @@ -335,7 +283,7 @@ const btstack_run_loop_t * btstack_run_loop_zephyr_get_instance(void){ return &btstack_run_loop_wiced; } -// main.c +static btstack_packet_callback_registration_t hci_event_callback_registration; static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ if (packet_type != HCI_EVENT_PACKET) return; @@ -346,8 +294,20 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack int btstack_main(void); +#if defined(CONFIG_BT_CTLR_ASSERT_HANDLER) +void bt_ctlr_assert_handle(char *file, u32_t line) +{ + printf("CONFIG_BT_CTLR_ASSERT_HANDLER: file %s, line %u\n", file, line); + while (1) { + } +} +#endif /* CONFIG_BT_CTLR_ASSERT_HANDLER */ + + void main(void) { + // configure console UART by replacing CONFIG_UART_NRF5_BAUD_RATE with 115200 in uart_console.c + printf("BTstack booting up..\n"); // start with BTstack init - especially configure HCI Transport @@ -360,6 +320,7 @@ void main(void) // init HCI hci_init(transport_get_instance(), NULL); +#if 1 // nRF5 chipsets don't have an official public address // Instead, they use a Static Random Address set in the factory bd_addr_t addr; @@ -373,7 +334,8 @@ void main(void) // make Random Static Address available via HCI Read BD ADDR as fake public address little_endian_store_32(addr, 0, NRF_FICR->DEVICEADDR[0]); little_endian_store_16(addr, 4, NRF_FICR->DEVICEADDR[1] | 0xc000); - ll_address_set(0, addr); + ll_addr_set(0, addr); +#endif #endif // inform about BTstack state diff --git a/port/nrf5-zephyr/nrf5.conf b/port/nrf5-zephyr/nrf5.conf index 1e63b2990..e2321582e 100644 --- a/port/nrf5-zephyr/nrf5.conf +++ b/port/nrf5-zephyr/nrf5.conf @@ -1,18 +1,23 @@ +# Debug output CONFIG_CONSOLE=y CONFIG_STDOUT_CONSOLE=y CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_NRF5=y +CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_UART_NRF5_BAUD_RATE=115200 -# CONFIG_UART_NRF5_FLOW_CONTROL=y +CONFIG_UART_DRV_CMD=y + +# Threads stacks +CONFIG_MAIN_STACK_SIZE=2048 +# CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=512 + +# Bluetooth Config +CONFIG_BT=y +CONFIG_BT_HCI_RAW=y +CONFIG_BT_MAX_CONN=16 +CONFIG_BT_CTLR_ASSERT_HANDLER=y +CONFIG_BT_TINYCRYPT_ECC=n +CONFIG_BTSTACK=y CONFIG_GPIO=y -CONFIG_SERIAL=y -CONFIG_UART_INTERRUPT_DRIVEN=y - -CONFIG_BLUETOOTH=y -CONFIG_BLUETOOTH_HCI_RAW=y -CONFIG_BLUETOOTH_MAX_CONN=16 -CONFIG_BLUETOOTH_CONTROLLER_RX_BUFFERS=4 -CONFIG_BLUETOOTH_CONTROLLER_TX_BUFFERS=4 - -CONFIG_BTSTACK=y -CONFIG_MAIN_STACK_SIZE=2048