From b7438b4fd911faa1fd381dadf1bba5f1c2d36660 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Mon, 7 Oct 2024 12:35:25 +0200 Subject: [PATCH 1/5] zephyr raw hci porting --- src/utility/HCIUartTransport.cpp | 2 +- src/utility/HCIVirtualTransportZephyr.cpp | 111 ++++++++++++++++++++++ src/utility/HCIVirtualTransportZephyr.h | 49 ++++++++++ src/utility/HCIVirtualZephyrMacros.c | 43 +++++++++ 4 files changed, 204 insertions(+), 1 deletion(-) create mode 100644 src/utility/HCIVirtualTransportZephyr.cpp create mode 100644 src/utility/HCIVirtualTransportZephyr.h create mode 100644 src/utility/HCIVirtualZephyrMacros.c diff --git a/src/utility/HCIUartTransport.cpp b/src/utility/HCIUartTransport.cpp index 191811a7..0e308338 100644 --- a/src/utility/HCIUartTransport.cpp +++ b/src/utility/HCIUartTransport.cpp @@ -17,7 +17,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if !defined(ARDUINO_ARCH_MBED) && !defined(ESP32) && !defined(ARDUINO_SILABS) && !defined(ARDUINO_UNOR4_WIFI) || defined(TARGET_NANO_RP2040_CONNECT) //|| defined(CORE_CM4) +#if !defined(ARDUINO_ARCH_MBED) && !defined(ESP32) && !defined(ARDUINO_SILABS) && !defined(ARDUINO_UNOR4_WIFI) && !defined(__ZEPHYR__) || defined(TARGET_NANO_RP2040_CONNECT) //|| defined(CORE_CM4) #include "HCIUartTransport.h" diff --git a/src/utility/HCIVirtualTransportZephyr.cpp b/src/utility/HCIVirtualTransportZephyr.cpp new file mode 100644 index 00000000..1b650714 --- /dev/null +++ b/src/utility/HCIVirtualTransportZephyr.cpp @@ -0,0 +1,111 @@ +/* + This file is part of the ArduinoBLE library. + Copyright (c) 2018 Arduino SA. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#if defined(__ZEPHYR__) + +#include "HCIVirtualTransportZephyr.h" + +extern "C" struct k_fifo* __rx_queue; + +HCIVirtualTransportZephyrClass::HCIVirtualTransportZephyrClass() +{ +} + +HCIVirtualTransportZephyrClass::~HCIVirtualTransportZephyrClass() +{ +} + +extern "C" void set_public_address(struct k_fifo *rx_queue); +int HCIVirtualTransportZephyrClass::begin() +{ + bt_enable_raw(__rx_queue); + //bt_hci_raw_set_mode(BT_HCI_RAW_MODE_PASSTHROUGH); + set_public_address(__rx_queue); + bt_hci_raw_set_mode(BT_HCI_RAW_MODE_H4); + rxbuf.clear(); + return 1; +} + +void HCIVirtualTransportZephyrClass::end() +{ +} + +void HCIVirtualTransportZephyrClass::wait(unsigned long timeout) +{ + delay(timeout); +} + +int HCIVirtualTransportZephyrClass::available() +{ + if (rxbuf.available()) { + return rxbuf.available(); + } + + static struct net_buf *buf; + buf = net_buf_get(__rx_queue, K_MSEC(10)); + if (!buf) { + return 0; + } + + for (int i = 0; i < buf->len; i++) { + rxbuf.store_char((uint8_t)buf->data[i]); + } + net_buf_pull(buf, buf->len); + if (!buf->len) { + net_buf_unref(buf); + buf = NULL; + } + + return rxbuf.available(); +} + +// never called +int HCIVirtualTransportZephyrClass::peek() +{ + return -1; +} + +int HCIVirtualTransportZephyrClass::read() +{ + + if (rxbuf.available()) { + return rxbuf.read_char(); + } + + return -1; +} + +size_t HCIVirtualTransportZephyrClass::write(const uint8_t* data, size_t length) +{ + struct net_buf *__net_buf = bt_buf_get_tx(BT_BUF_H4, K_MSEC(10), data, length); + if (__net_buf) { + auto err = bt_send(__net_buf); + if (err) { + net_buf_unref(__net_buf); + } + return length; + } + return 0; +} + +HCIVirtualTransportZephyrClass HCIVirtualTransportZephyr; + +HCITransportInterface& HCITransport = HCIVirtualTransportZephyr; + +#endif diff --git a/src/utility/HCIVirtualTransportZephyr.h b/src/utility/HCIVirtualTransportZephyr.h new file mode 100644 index 00000000..b213aede --- /dev/null +++ b/src/utility/HCIVirtualTransportZephyr.h @@ -0,0 +1,49 @@ +/* + This file is part of the ArduinoBLE library. + Copyright (c) 2018 Arduino SA. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "HCITransport.h" +#include "api/RingBuffer.h" +#include +#include +#include + +extern "C" { +#include +#include +} + +class HCIVirtualTransportZephyrClass : public HCITransportInterface { +public: + HCIVirtualTransportZephyrClass(); + virtual ~HCIVirtualTransportZephyrClass(); + + virtual int begin(); + virtual void end(); + + virtual void wait(unsigned long timeout); + + virtual int available(); + virtual int peek(); + virtual int read(); + + virtual size_t write(const uint8_t* data, size_t length); + +private: + RingBufferN<258> rxbuf; +}; \ No newline at end of file diff --git a/src/utility/HCIVirtualZephyrMacros.c b/src/utility/HCIVirtualZephyrMacros.c new file mode 100644 index 00000000..ac44a880 --- /dev/null +++ b/src/utility/HCIVirtualZephyrMacros.c @@ -0,0 +1,43 @@ +#if defined(__ZEPHYR__) + +#include +#include +#include + +static K_FIFO_DEFINE(rx_queue); +struct k_fifo* __rx_queue = &rx_queue; + + +// from https://github.com/thomasstenersen/sdk-zephyr/commit/df546a0eb9b96b453373f38483959d2363a83cae#diff-217778ef1d0638c89207786f06425396891f987713120e83db724d26b9813eebR331 +// referenced by https://devzone.nordicsemi.com/f/nordic-q-a/73310/incompatibility-between-mcumgr-cli-and-hci_usb-when-running-with-bt_ll_softdevice-enabled + +void set_public_address(struct k_fifo *rx_queue) +{ + const struct bt_hci_cp_vs_write_bd_addr cmd = { + .bdaddr.val = {0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA} + }; + const struct bt_hci_cmd_hdr cmd_header = { + .opcode = BT_HCI_OP_VS_WRITE_BD_ADDR, + .param_len = sizeof(cmd) + }; + struct net_buf *buf; + int err; + buf = bt_buf_get_tx(BT_BUF_CMD, K_NO_WAIT, + &cmd_header, sizeof(cmd_header)); + net_buf_add_mem(buf, &cmd, sizeof(cmd)); + err = bt_send(buf); + __ASSERT_NO_MSG(err == 0); + /* Pull out the command complete. */ + buf = net_buf_get(rx_queue, K_SECONDS(10)); /* 10s == HCI_CMD_TIMEOUT */ + struct bt_hci_evt_hdr *hdr; + __ASSERT_NO_MSG(buf != NULL); + __ASSERT_NO_MSG(buf->len >= sizeof(*hdr)); + hdr = net_buf_pull_mem(buf, sizeof(*hdr)); + __ASSERT_NO_MSG(hdr->evt == BT_HCI_EVT_CMD_COMPLETE); + struct bt_hci_evt_cmd_complete *evt; + evt = net_buf_pull_mem(buf, sizeof(*evt)); + __ASSERT_NO_MSG(sys_le16_to_cpu(evt->opcode) == BT_HCI_OP_VS_WRITE_BD_ADDR); + net_buf_unref(buf); +} + +#endif \ No newline at end of file From fe2b3afdd41449cddbfda7a2b05e004c37c93908 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Thu, 20 Mar 2025 17:47:04 +0100 Subject: [PATCH 2/5] zephyr: port to 4.2.0+ --- src/utility/HCIVirtualTransportZephyr.cpp | 2 +- src/utility/HCIVirtualZephyrMacros.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utility/HCIVirtualTransportZephyr.cpp b/src/utility/HCIVirtualTransportZephyr.cpp index 1b650714..55689baa 100644 --- a/src/utility/HCIVirtualTransportZephyr.cpp +++ b/src/utility/HCIVirtualTransportZephyr.cpp @@ -58,7 +58,7 @@ int HCIVirtualTransportZephyrClass::available() } static struct net_buf *buf; - buf = net_buf_get(__rx_queue, K_MSEC(10)); + buf = (struct net_buf*)k_fifo_get(__rx_queue, K_MSEC(10)); if (!buf) { return 0; } diff --git a/src/utility/HCIVirtualZephyrMacros.c b/src/utility/HCIVirtualZephyrMacros.c index ac44a880..e6cda9b8 100644 --- a/src/utility/HCIVirtualZephyrMacros.c +++ b/src/utility/HCIVirtualZephyrMacros.c @@ -28,7 +28,7 @@ void set_public_address(struct k_fifo *rx_queue) err = bt_send(buf); __ASSERT_NO_MSG(err == 0); /* Pull out the command complete. */ - buf = net_buf_get(rx_queue, K_SECONDS(10)); /* 10s == HCI_CMD_TIMEOUT */ + buf = (struct net_buf*)k_fifo_get(rx_queue, K_SECONDS(10)); /* 10s == HCI_CMD_TIMEOUT */ struct bt_hci_evt_hdr *hdr; __ASSERT_NO_MSG(buf != NULL); __ASSERT_NO_MSG(buf->len >= sizeof(*hdr)); From f99b7a0501147e05fb168729b68428b218a2203d Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Fri, 23 May 2025 12:18:21 +0200 Subject: [PATCH 3/5] fix indentation --- src/utility/HCIVirtualTransportZephyr.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/utility/HCIVirtualTransportZephyr.cpp b/src/utility/HCIVirtualTransportZephyr.cpp index 55689baa..12b20b81 100644 --- a/src/utility/HCIVirtualTransportZephyr.cpp +++ b/src/utility/HCIVirtualTransportZephyr.cpp @@ -58,7 +58,7 @@ int HCIVirtualTransportZephyrClass::available() } static struct net_buf *buf; - buf = (struct net_buf*)k_fifo_get(__rx_queue, K_MSEC(10)); + buf = (struct net_buf*)k_fifo_get(__rx_queue, K_MSEC(10)); if (!buf) { return 0; } @@ -68,9 +68,9 @@ int HCIVirtualTransportZephyrClass::available() } net_buf_pull(buf, buf->len); if (!buf->len) { - net_buf_unref(buf); - buf = NULL; - } + net_buf_unref(buf); + buf = NULL; + } return rxbuf.available(); } From ffa99f756a0ad1acd3880446fa5a8e38611bc2a8 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Fri, 23 May 2025 12:19:07 +0200 Subject: [PATCH 4/5] zephyr: undefine common board names --- src/local/BLELocalDevice.cpp | 8 ++++++++ src/utility/HCIUartTransport.cpp | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/local/BLELocalDevice.cpp b/src/local/BLELocalDevice.cpp index 5792353f..89c7a580 100644 --- a/src/local/BLELocalDevice.cpp +++ b/src/local/BLELocalDevice.cpp @@ -25,6 +25,14 @@ #include "BLELocalDevice.h" +#ifdef __ZEPHYR__ +#undef ARDUINO_PORTENTA_H7_M7 +#undef ARDUINO_OPTA +#undef ARDUINO_GIGA +#undef ARDUINO_NICLA_VISION +#undef ARDUINO_PORTENTA_C33 +#endif + #if defined(PORTENTA_H7_PINS) || defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_OPTA) #ifndef BT_REG_ON #define BT_REG_ON PJ_12 diff --git a/src/utility/HCIUartTransport.cpp b/src/utility/HCIUartTransport.cpp index 0e308338..5a848ea7 100644 --- a/src/utility/HCIUartTransport.cpp +++ b/src/utility/HCIUartTransport.cpp @@ -17,7 +17,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#if !defined(ARDUINO_ARCH_MBED) && !defined(ESP32) && !defined(ARDUINO_SILABS) && !defined(ARDUINO_UNOR4_WIFI) && !defined(__ZEPHYR__) || defined(TARGET_NANO_RP2040_CONNECT) //|| defined(CORE_CM4) +#if !defined(ARDUINO_ARCH_MBED) && !defined(__ZEPHYR__) && !defined(ESP32) && !defined(ARDUINO_SILABS) && !defined(ARDUINO_UNOR4_WIFI) && !defined(__ZEPHYR__) || defined(TARGET_NANO_RP2040_CONNECT) //|| defined(CORE_CM4) #include "HCIUartTransport.h" From 8874209c43300897bb98e2b5f6da97e7923e2195 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Fri, 23 May 2025 12:19:49 +0200 Subject: [PATCH 5/5] Address removal of BT_HCI_RAW_MODE_H4 --- src/utility/HCIVirtualTransportZephyr.cpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/utility/HCIVirtualTransportZephyr.cpp b/src/utility/HCIVirtualTransportZephyr.cpp index 12b20b81..e6226ee4 100644 --- a/src/utility/HCIVirtualTransportZephyr.cpp +++ b/src/utility/HCIVirtualTransportZephyr.cpp @@ -32,12 +32,28 @@ HCIVirtualTransportZephyrClass::~HCIVirtualTransportZephyrClass() } extern "C" void set_public_address(struct k_fifo *rx_queue); +extern "C" int bt_h4_vnd_setup(const struct device *dev); +struct h4_config { + const struct device *uart; + k_thread_stack_t *rx_thread_stack; + size_t rx_thread_stack_size; + struct k_thread *rx_thread; +}; + int HCIVirtualTransportZephyrClass::begin() { bt_enable_raw(__rx_queue); - //bt_hci_raw_set_mode(BT_HCI_RAW_MODE_PASSTHROUGH); +#if defined(CONFIG_BT_HCI_SETUP) + const struct device *dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_bt_hci)); + if (!dev) { + return 0; + } + const struct h4_config *cfg = (const struct h4_config *)dev->config; + bt_h4_vnd_setup(cfg->uart); +#else set_public_address(__rx_queue); - bt_hci_raw_set_mode(BT_HCI_RAW_MODE_H4); +#endif + rxbuf.clear(); return 1; } @@ -93,7 +109,7 @@ int HCIVirtualTransportZephyrClass::read() size_t HCIVirtualTransportZephyrClass::write(const uint8_t* data, size_t length) { - struct net_buf *__net_buf = bt_buf_get_tx(BT_BUF_H4, K_MSEC(10), data, length); + struct net_buf *__net_buf = bt_buf_get_tx(bt_buf_type_from_h4(data[0], BT_BUF_OUT), K_FOREVER, &data[1], length - 1); if (__net_buf) { auto err = bt_send(__net_buf); if (err) {