M module-bluetooth/Bluetooth/BluetoothWorker.cpp => module-bluetooth/Bluetooth/BluetoothWorker.cpp +29 -30
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <service-bluetooth/ServiceBluetooth.hpp>
@@ 6,8 6,6 @@
#include "BtCommand.hpp"
#include <log/log.hpp>
#include "interface/BluetoothDriverImpl.hpp"
-#include "interface/profiles/A2DP/A2DP.hpp"
-#include "interface/profiles/HSP/HSP.hpp"
#include "audio/BluetoothAudioDevice.hpp"
#include "BtKeysStorage.hpp"
@@ 26,12 24,12 @@
namespace queues
{
- constexpr inline auto io = "qBtIO";
- constexpr inline auto cmd = "qBtCmds";
- constexpr inline auto btstack = "qBtStack";
+ constexpr auto io = "qBtIO";
+ constexpr auto cmd = "qBtCmds";
+ constexpr auto btstack = "qBtStack";
- constexpr inline auto queueLength = 10;
- constexpr inline auto triggerQueueLength = 3;
+ constexpr auto queueLength = 10;
+ constexpr auto triggerQueueLength = 3;
} // namespace queues
namespace
@@ 120,7 118,7 @@ void BluetoothWorker::registerQueues()
dynamic_cast<ServiceBluetooth *>(service)->workerQueue = workerQueue;
runLoop->setTriggerQueue(Worker::getQueueHandleByName(queues::btstack));
- bsp::BlueKitchen::getInstance()->qHandle = queues[queueIO_handle]->GetQueueHandle();
+ bsp::BlueKitchen::getInstance().qHandle = queues[queueIO_handle]->GetQueueHandle();
}
void BluetoothWorker::onLinkKeyAdded(const std::string &deviceAddress)
@@ 212,49 210,53 @@ auto BluetoothWorker::handleMessage(uint32_t queueID) -> bool
LOG_ERROR("Queue receive failure!");
return false;
}
- auto bt = bsp::BlueKitchen::getInstance();
+
+ auto &blueKitchen = bsp::BlueKitchen::getInstance();
switch (notification) {
- case bluetooth::Message::EvtSending:
+ case bluetooth::Message::EvtSending: {
logHciComs("[evt] sending");
- break;
- case bluetooth::Message::EvtSent:
+ } break;
+
+ case bluetooth::Message::EvtSent: {
logHciComs("[evt] sent");
- if (bt->write_done_cb) {
- bt->write_done_cb();
+ if (blueKitchen.writeDoneCallback) {
+ blueKitchen.writeDoneCallback();
}
- break;
- case bluetooth::Message::EvtReceiving:
+ } break;
+
+ case bluetooth::Message::EvtReceiving: {
logHciComs("[evt] receiving");
- break;
+ } break;
+
case bluetooth::Message::EvtReceived: {
logHciBytes("[evt] BT DMA received <-- [%ld]>%s<",
- bt->read_len,
+ blueKitchen.readLength,
[&]() -> std::string {
std::stringstream ss;
- for (int i = 0; i < bt->read_len; ++i) {
- ss << " 0x" << std::hex << (int)*(bt->read_buff + i);
+ for (auto i = 0; i < blueKitchen.readLength; ++i) {
+ ss << " 0x" << std::hex << static_cast<int>(blueKitchen.readBuffer[i]);
}
return ss.str();
}()
.c_str());
- bt->read_len = 0;
+ blueKitchen.readLength = 0;
- if (bt->read_ready_cb) {
- bt->read_ready_cb();
+ if (blueKitchen.readReadyCallback) {
+ blueKitchen.readReadyCallback();
}
} break;
+
case bluetooth::Message::EvtSendingError:
- [[fallthrough]];
case bluetooth::Message::EvtReceivingError:
- [[fallthrough]];
case bluetooth::Message::EvtUartError:
- [[fallthrough]];
case bluetooth::Message::EvtRecUnwanted:
LOG_ERROR("Uart error [%d]: %s", notification, bluetooth::MessageCstr(notification));
break;
+
default:
LOG_ERROR("Unknown message: %d", notification);
+ break;
}
return true;
@@ 266,9 268,6 @@ void BluetoothWorker::closeWorker()
this->close();
}
-void BluetoothWorker::removeFromBoundDevices(uint8_t *addr)
-{}
-
void BluetoothWorker::setAudioDevice(std::shared_ptr<bluetooth::BluetoothAudioDevice> device)
{
cpp_freertos::LockGuard lock(loopMutex);
M module-bluetooth/Bluetooth/BluetoothWorker.hpp => module-bluetooth/Bluetooth/BluetoothWorker.hpp +1 -2
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 88,7 88,6 @@ class BluetoothWorker : private sys::Worker
void registerQueues();
void onLinkKeyAdded(const std::string &deviceAddress);
- void removeFromBoundDevices(uint8_t *addr);
std::shared_ptr<Mailbox<bluetooth::Command, QueueHandle_t, WorkerLock>> workerQueue;
M module-bluetooth/Bluetooth/BtKeysStorage.cpp => module-bluetooth/Bluetooth/BtKeysStorage.cpp +5 -5
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <algorithm>
@@ 14,10 14,10 @@ namespace bluetooth
{
namespace strings
{
- constexpr inline auto keys = "keys";
- constexpr inline auto link_key = "link_key";
- constexpr inline auto bd_addr = "bd_addr";
- constexpr inline auto type = "type";
+ constexpr auto keys = "keys";
+ constexpr auto link_key = "link_key";
+ constexpr auto bd_addr = "bd_addr";
+ constexpr auto type = "type";
} // namespace strings
auto KeyStorage::getKeyStorage() -> btstack_link_key_db_t *
M module-bluetooth/Bluetooth/glucode/BluetoothRunLoop.cpp => module-bluetooth/Bluetooth/glucode/BluetoothRunLoop.cpp +70 -79
@@ 1,77 1,81 @@
-// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "BluetoothRunLoop.hpp"
#include "btstack_util.h"
+#include <log/log.hpp>
#include <cassert>
+
namespace bluetooth
{
-
- btstack_linked_list_t RunLoop::timers;
- btstack_linked_list_t RunLoop::data_sources;
- bool RunLoop::run_loop_exit_requested;
-
- QueueHandle_t RunLoop::btstack_run_loop_queue;
- TaskHandle_t RunLoop::btstack_run_loop_task;
+ QueueHandle_t RunLoop::btstackRunLoopQueue;
+ TaskHandle_t RunLoop::btstackRunLoopTask;
QueueHandle_t RunLoop::triggerQueue;
- TimerHandle_t RunLoop::testTimer = nullptr;
+ TimerHandle_t RunLoop::btstackTimer = nullptr;
+ btstack_linked_list_t RunLoop::timers;
+ btstack_linked_list_t RunLoop::dataSources;
+ bool RunLoop::runLoopExitRequested;
- auto RunLoop::removeTimer(btstack_timer_source_t *ts) -> bool
+ bool RunLoop::removeTimer(btstack_timer_source_t *timerSource)
{
- return btstack_linked_list_remove(&timers, reinterpret_cast<btstack_linked_item_t *>(ts));
+ return btstack_linked_list_remove(&timers, reinterpret_cast<btstack_linked_item_t *>(timerSource));
}
+
void RunLoop::setTriggerQueue(QueueHandle_t queue)
{
assert(queue != nullptr);
triggerQueue = queue;
}
+
void RunLoop::deinit()
{
- vQueueDelete(btstack_run_loop_queue);
- xTimerDelete(testTimer, 0);
+ vQueueDelete(btstackRunLoopQueue);
+ xTimerDelete(btstackTimer, 0);
}
+
void RunLoop::init()
{
timers = nullptr;
- btstack_run_loop_queue = xQueueCreate(RUN_LOOP_QUEUE_LENGTH, RUN_LOOP_QUEUE_ITEM_SIZE);
+ btstackRunLoopQueue = xQueueCreate(runLoopQueueLength, runLoopQueueItemSize);
- // task to handle to optimize 'run on main thread'
- btstack_run_loop_task = xTaskGetCurrentTaskHandle();
+ // Task to handle to optimize 'run on main thread'
+ btstackRunLoopTask = xTaskGetCurrentTaskHandle();
- LOG_INFO("Run loop init, task %p, queue item size %u",
- btstack_run_loop_task,
- static_cast<int>(sizeof(function_call_t)));
+ LOG_INFO("Run loop init, task %p, queue item size %zu", btstackRunLoopTask, sizeof(FunctionCallType));
}
- void RunLoop::enableDataSourceCallbacks(btstack_data_source_t *ds, uint16_t callback_types)
+
+ void RunLoop::enableDataSourceCallbacks(btstack_data_source_t *dataSource, std::uint16_t callbackTypes)
{
- ds->flags |= callback_types;
+ dataSource->flags |= callbackTypes;
}
- void RunLoop::disableDataSourceCallbacks(btstack_data_source_t *ds, uint16_t callback_types)
+ void RunLoop::disableDataSourceCallbacks(btstack_data_source_t *dataSource, std::uint16_t callbackTypes)
{
- ds->flags &= ~callback_types;
+ dataSource->flags &= ~callbackTypes;
}
- void RunLoop::addDataSource(btstack_data_source_t *ds)
+ void RunLoop::addDataSource(btstack_data_source_t *dataSource)
{
- btstack_linked_list_add(&data_sources, (btstack_linked_item_t *)ds);
+ btstack_linked_list_add(&dataSources, reinterpret_cast<btstack_linked_item_t *>(dataSource));
}
- auto RunLoop::removeDataSource(btstack_data_source_t *ds) -> bool
+ auto RunLoop::removeDataSource(btstack_data_source_t *dataSource) -> bool
{
- return btstack_linked_list_remove(&data_sources, (btstack_linked_item_t *)ds);
+ return btstack_linked_list_remove(&dataSources, reinterpret_cast<btstack_linked_item_t *>(dataSource));
}
+
void RunLoop::triggerExit()
{
- run_loop_exit_requested = true;
+ runLoopExitRequested = true;
}
+
auto RunLoop::getTimeMs() -> TickType_t
{
return xTaskGetTickCount();
}
+
void RunLoop::trigger()
{
-
bool trigger = true;
if (triggerQueue != nullptr) {
xQueueSend(triggerQueue, &trigger, 0);
@@ 80,67 84,55 @@ namespace bluetooth
LOG_FATAL("Trigger queue does not exist!");
}
}
- void RunLoop::executeCodeOnMainThread(void (*fn)(void *arg), void *arg)
- {
-
- // directly call function if already on btstack task
- if (xTaskGetCurrentTaskHandle() == btstack_run_loop_task) {
- (*fn)(arg);
- return;
- }
-
- function_call_t message;
- message.fn = fn;
- message.arg = arg;
- BaseType_t res = xQueueSendToBack(btstack_run_loop_queue, &message, 0); // portMAX_DELAY);
- if (res != pdTRUE) {
- LOG_ERROR("Failed to post fn %p", fn);
- }
- trigger();
- }
- void RunLoop::addTimer(btstack_timer_source_t *ts)
+ void RunLoop::addTimer(btstack_timer_source_t *timerSource)
{
btstack_linked_item_t *it = nullptr;
for (it = reinterpret_cast<btstack_linked_item_t *>(&timers); it->next != nullptr; it = it->next) {
- // don't add timer that's already in there
- auto *next = reinterpret_cast<btstack_timer_source_t *>(it->next);
- if (next == ts) {
+ // Don't add timer that's already in there
+ auto next = reinterpret_cast<btstack_timer_source_t *>(it->next);
+ if (next == timerSource) {
LOG_ERROR("Timer 'btstack_run_loop_timer' already in list!");
return;
}
- // exit if new timeout before list timeout
- int32_t delta = btstack_time_delta(ts->timeout, next->timeout);
+
+ // Exit if new timeout before list timeout
+ const auto delta = btstack_time_delta(timerSource->timeout, next->timeout);
if (delta < 0) {
break;
}
}
- ts->item.next = it->next;
- it->next = reinterpret_cast<btstack_linked_item_t *>(ts);
+ timerSource->item.next = it->next;
+ it->next = reinterpret_cast<btstack_linked_item_t *>(timerSource);
trigger();
}
- void RunLoop::setTimer(btstack_timer_source_t *ts, uint32_t timeout_in_ms)
+
+ void RunLoop::setTimer(btstack_timer_source_t *timerSource, std::uint32_t timeoutMs)
{
- ts->timeout = getTimeMs() + timeout_in_ms + 1;
+ timerSource->timeout = getTimeMs() + timeoutMs + 1;
trigger();
}
- void RunLoop::triggerCallback(TimerHandle_t xTimer)
+
+ void RunLoop::triggerCallback([[maybe_unused]] TimerHandle_t xTimer)
{
trigger();
}
+
void RunLoop::start()
{
- if (testTimer == nullptr) {
- testTimer = xTimerCreate("TestTimer", pdMS_TO_TICKS(1000), pdTRUE, nullptr, triggerCallback);
- xTimerStart(testTimer, 0);
+ if (btstackTimer == nullptr) {
+ btstackTimer =
+ xTimerCreate("BTStackTimer", pdMS_TO_TICKS(defaultTimerPeriodMs), pdTRUE, nullptr, triggerCallback);
+ xTimerStart(btstackTimer, 0);
}
}
+
auto RunLoop::process() -> bool
{
- // process registered function calls on run loop thread
+ // Process registered function calls on run loop thread
while (true) {
- function_call_t message = {nullptr, nullptr};
- BaseType_t res = xQueueReceive(btstack_run_loop_queue, &message, 0);
+ FunctionCallType message = {nullptr, nullptr};
+ const auto res = xQueueReceive(btstackRunLoopQueue, &message, 0);
if (res == pdFALSE) {
break;
}
@@ 149,33 141,33 @@ namespace bluetooth
}
}
- // process timers and get next timeout
- uint32_t timeout_ms = 1000;
+ // Process timers and get next timeout
+ std::uint32_t timeoutMs = defaultTimerPeriodMs;
while (timers != nullptr) {
- auto *ts = reinterpret_cast<btstack_timer_source_t *>(timers);
- uint32_t now = getTimeMs();
- int32_t delta_ms = btstack_time_delta(ts->timeout, now);
- if (delta_ms > 0) {
- timeout_ms = delta_ms;
+ auto timerSource = reinterpret_cast<btstack_timer_source_t *>(timers);
+ const auto now = getTimeMs();
+ const auto deltaMs = btstack_time_delta(timerSource->timeout, now);
+ if (deltaMs > 0) {
+ timeoutMs = deltaMs;
break;
}
- // remove timer before processing it to allow handler to re-register with run loop
- removeTimer(ts);
- ts->process(ts);
+
+ // Remove timer before processing it to allow handler to re-register with run loop
+ removeTimer(timerSource);
+ timerSource->process(timerSource);
}
- // exit triggered by btstack_run_loop_freertos_trigger_exit (from data source, timer, run on main thread)
- if (run_loop_exit_requested) {
+ // Exit triggered by btstack_run_loop_freertos_trigger_exit (from data source, timer, run on main thread)
+ if (runLoopExitRequested) {
return true;
}
- xTimerChangePeriod(testTimer, pdMS_TO_TICKS(timeout_ms), 0);
+ xTimerChangePeriod(btstackTimer, pdMS_TO_TICKS(timeoutMs), 0);
return false;
}
auto RunLoop::getRunLoopInstance() -> btstack_run_loop *
{
-
runLoop = btstack_run_loop{
&init,
&addDataSource,
@@ 191,5 183,4 @@ namespace bluetooth
};
return &runLoop;
}
-
} // namespace bluetooth
M module-bluetooth/Bluetooth/glucode/BluetoothRunLoop.hpp => module-bluetooth/Bluetooth/glucode/BluetoothRunLoop.hpp +35 -27
@@ 1,55 1,63 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
-#include <log/log.hpp>
-#include "queue.hpp"
+
#include <btstack_run_loop.h>
+#include <queue.hpp>
#include <timer.hpp>
namespace bluetooth
{
-
- using function_call_t = struct function_call
+ using FunctionCallType = struct FunctionCall
{
void (*fn)(void *arg);
void *arg;
};
- constexpr inline auto RUN_LOOP_QUEUE_LENGTH = 20;
- constexpr inline auto RUN_LOOP_QUEUE_ITEM_SIZE = sizeof(function_call_t);
+ inline constexpr auto runLoopQueueLength = 20;
+ inline constexpr auto runLoopQueueItemSize = sizeof(FunctionCallType);
class RunLoop
{
+ public:
+ static void trigger();
+ static bool process();
+ static void deinit();
+ static void setTriggerQueue(QueueHandle_t queue);
+ auto getRunLoopInstance() -> btstack_run_loop *;
+
private:
- static auto removeTimer(btstack_timer_source_t *ts) -> bool;
+ static bool removeTimer(btstack_timer_source_t *timerSource);
+
static void init();
- static void enableDataSourceCallbacks(btstack_data_source_t *ds, uint16_t callback_types);
- static void disableDataSourceCallbacks(btstack_data_source_t *ds, uint16_t callback_types);
- static void addDataSource(btstack_data_source_t *ds);
- static auto removeDataSource(btstack_data_source_t *ds) -> bool;
+
+ static void enableDataSourceCallbacks(btstack_data_source_t *dataSource, std::uint16_t callbackTypes);
+ static void disableDataSourceCallbacks(btstack_data_source_t *dataSource, std::uint16_t callbackTypes);
+
+ static void addDataSource(btstack_data_source_t *dataSource);
+ static bool removeDataSource(btstack_data_source_t *dataSource);
+
static void triggerExit();
+
static auto getTimeMs() -> TickType_t;
- static void executeCodeOnMainThread(void (*fn)(void *arg), void *arg);
+
static void addTimer(btstack_timer_source_t *ts);
- static void setTimer(btstack_timer_source_t *ts, uint32_t timeout_in_ms);
+ static void setTimer(btstack_timer_source_t *ts, uint32_t timeoutMs);
+
static void start();
static void triggerCallback(TimerHandle_t xTimer);
- static QueueHandle_t btstack_run_loop_queue;
- static TaskHandle_t btstack_run_loop_task;
+
+ static constexpr auto defaultTimerPeriodMs = 1000;
+
+ static QueueHandle_t btstackRunLoopQueue;
+ static TaskHandle_t btstackRunLoopTask;
static QueueHandle_t triggerQueue;
- static TimerHandle_t testTimer;
+ static TimerHandle_t btstackTimer;
static btstack_linked_list_t timers;
- static btstack_linked_list_t data_sources;
- static bool run_loop_exit_requested;
- btstack_run_loop runLoop;
+ static btstack_linked_list_t dataSources;
+ static bool runLoopExitRequested;
- public:
- static void trigger();
- auto process() -> bool;
- static void deinit();
- void setTriggerQueue(QueueHandle_t queue);
- auto getRunLoopInstance() -> btstack_run_loop *;
+ btstack_run_loop runLoop;
};
-
} // namespace bluetooth
M module-bluetooth/Bluetooth/glucode/btstack_uart_block_rt1051.cpp => module-bluetooth/Bluetooth/glucode/btstack_uart_block_rt1051.cpp +37 -43
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <bsp/bluetooth/Bluetooth.hpp>
@@ 8,96 8,90 @@ using namespace bsp;
extern "C"
{
-
#include "btstack_uart_block_rt1051.h"
#include <hci_transport.h>
#include <btstack_run_loop.h>
#include <btstack_uart_block.h>
-#include <stddef.h> // for null
#include <btstack_run_loop_freertos.h>
+}
- // #define DEBUG_UART
+// #define DEBUG_UART
+namespace
+{
// and it's hci_transport_config_uart_t which is a bit different...
- static int uart_rt1051_init(const btstack_uart_config_t *config)
+ int uart_rt1051_init([[maybe_unused]] const btstack_uart_config_t *config)
{
LOG_INFO("Create BlueKitchen interface");
BlueKitchen::getInstance();
return 0;
}
- static int uart_rt1051_open()
+ int uart_rt1051_open()
{
- LOG_INFO("BlueKitchen uart open");
- BlueKitchen::getInstance()->open();
+ LOG_INFO("BlueKitchen UART open");
+ BlueKitchen::getInstance().open();
return 0;
}
- static int uart_rt1051_close()
+ int uart_rt1051_close()
{
- LOG_INFO("BlueKitchen uart close");
- BlueKitchen::getInstance()->close();
+ LOG_INFO("BlueKitchen UART close");
+ BlueKitchen::getInstance().close();
return 0;
}
- static void uart_rt1051_set_block_received(void (*handler)(void))
+ void uart_rt1051_set_block_received(void (*handler)())
{
- BlueKitchen::getInstance()->read_ready_cb = handler;
+ BlueKitchen::getInstance().readReadyCallback = handler;
}
- static void uart_rt1051_set_block_sent(void (*handler)(void))
+ void uart_rt1051_set_block_sent(void (*handler)())
{
- BlueKitchen::getInstance()->write_done_cb = handler;
+ BlueKitchen::getInstance().writeDoneCallback = handler;
}
- static int uart_rt1051_set_baudrate(uint32_t baudrate)
+ int uart_rt1051_set_baudrate(std::uint32_t baudrate)
{
- BlueKitchen::getInstance()->set_baudrate(baudrate);
+ BlueKitchen::getInstance().setBaudrate(baudrate);
return 0;
}
- static int uart_rt1051_set_parity(int pairity)
+ int uart_rt1051_set_parity(int parity)
{
// Not implemented
- LOG_INFO("BlueKitchen set pairity: %d", pairity);
+ LOG_INFO("BlueKitchen set pairity: %d", parity);
return 0;
}
- static int uart_rt1051_set_flowcontrol(int flowcontrol)
- {
- LOG_INFO("BlueKitchen set flowcontrol: %d", flowcontrol);
- // BlueKitchen::getInstance()->set_rts(); ??
- return 0;
- }
-
- static void uart_rt1051_receive_block(uint8_t *buffer, uint16_t len)
+ void uart_rt1051_receive_block(std::uint8_t *buffer, std::uint16_t len)
{
#ifdef DEBUG_UART
LOG_DEBUG("<-- read: %d", len);
#endif
- BlueKitchen::getInstance()->read(buffer, len);
+ BlueKitchen::getInstance().read(buffer, len);
}
- static void uart_rt1051_send_block(const uint8_t *buffer, uint16_t length)
+ void uart_rt1051_send_block(const uint8_t *buffer, uint16_t length)
{
#ifdef DEBUG_UART
LOG_DEBUG("--> write: %d", length);
#endif
- BlueKitchen::getInstance()->write(buffer, length);
+ BlueKitchen::getInstance().write(buffer, length);
}
- static int btstack_uart_rt1051_get_supported_sleep_modes(void)
+ int btstack_uart_rt1051_get_supported_sleep_modes()
{
return BTSTACK_UART_SLEEP_MASK_RTS_HIGH_WAKE_ON_CTS_PULSE;
}
- static void btstack_uart_rt1051_set_sleep(btstack_uart_sleep_mode_t sleep_mode)
+ void btstack_uart_rt1051_set_sleep([[maybe_unused]] btstack_uart_sleep_mode_t sleep_mode)
{}
- static void btstack_uart_rt1051_set_wakeup_handler(void (*the_wakeup_handler)(void))
+ void btstack_uart_rt1051_set_wakeup_handler([[maybe_unused]] void (*wakeup_handler)())
{}
- static const btstack_uart_block_t btstack_uart_posix = {
+ const btstack_uart_block_t btstack_uart_posix = {
/* int (*init)(hci_transport_config_uart_t * config); */ uart_rt1051_init,
/* int (*open)(void); */ uart_rt1051_open,
/* int (*close)(void); */ uart_rt1051_close,
@@ 105,16 99,16 @@ extern "C"
/* void (*set_block_sent)(void (*handler)(void)); */ uart_rt1051_set_block_sent,
/* int (*set_baudrate)(uint32_t baudrate); */ uart_rt1051_set_baudrate,
/* int (*set_parity)(int parity); */ uart_rt1051_set_parity,
- /* int (*set_flowcontrol)(int flowcontrol); */ NULL, // uart_rt1051_set_flowcontrol,
+ /* int (*set_flowcontrol)(int flowcontrol); */ nullptr,
/* void (*receive_block)(uint8_t *buffer, uint16_t len); */ uart_rt1051_receive_block,
/* void (*send_block)(const uint8_t *buffer, uint16_t length); */ uart_rt1051_send_block,
- /* int (*get_supported_sleep_modes); */ &btstack_uart_rt1051_get_supported_sleep_modes,
- /* void (*set_sleep)(btstack_uart_sleep_mode_t sleep_mode); */ &btstack_uart_rt1051_set_sleep,
- /* void (*set_wakeup_handler)(void (*handler)(void)); */ &btstack_uart_rt1051_set_wakeup_handler,
+ /* int (*get_supported_sleep_modes)(); */ btstack_uart_rt1051_get_supported_sleep_modes,
+ /* void (*set_sleep)(btstack_uart_sleep_mode_t sleep_mode); */ btstack_uart_rt1051_set_sleep,
+ /* void (*set_wakeup_handler)(void (*handler)(void)); */ btstack_uart_rt1051_set_wakeup_handler,
};
+} // namespace
- const btstack_uart_block_t *btstack_uart_block_rt1051_instance()
- {
- return &btstack_uart_posix;
- }
-};
+const btstack_uart_block_t *btstack_uart_block_rt1051_instance()
+{
+ return &btstack_uart_posix;
+}
M module-bluetooth/Bluetooth/glucode/btstack_uart_block_rt1051.h => module-bluetooth/Bluetooth/glucode/btstack_uart_block_rt1051.h +3 -2
@@ 4,10 4,11 @@
extern "C"
{
#endif
+
#include <btstack_uart_block.h>
- const btstack_uart_block_t *btstack_uart_block_rt1051_instance();
+const btstack_uart_block_t *btstack_uart_block_rt1051_instance();
#ifdef __cplusplus
-}; // __cplusplus
+} // __cplusplus
#endif
M module-bluetooth/Bluetooth/glucode/hal_time_ms.c => module-bluetooth/Bluetooth/glucode/hal_time_ms.c +0 -1
@@ 1,4 1,3 @@
-#include "btstack_debug.h"
#include <FreeRTOS.h>
#include <stdint.h>
#include <task.h>
M module-bluetooth/Bluetooth/interface/BluetoothDriverImpl.cpp => module-bluetooth/Bluetooth/interface/BluetoothDriverImpl.cpp +27 -23
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "BluetoothDriverImpl.hpp"
@@ 26,7 26,6 @@ extern "C"
extern "C"
{
#include <btstack_uart.h>
-
#include <btstack_run_loop_posix.h>
#include <btstack_tlv_posix.h>
}
@@ 38,21 37,18 @@ namespace bluetooth
PowerOnCallback Driver::powerOnCallback = nullptr;
#ifdef TARGET_RT1051
- [[maybe_unused]] auto Driver::runLoopInitTarget(const btstack_run_loop *loop) -> const btstack_uart_block_t *
+ auto Driver::runLoopInitTarget(const btstack_run_loop *loop) -> const btstack_uart_block_t *
{
btstack_run_loop_init(loop);
- const btstack_uart_block_t *uartDriver = btstack_uart_block_rt1051_instance();
- return uartDriver;
+ return btstack_uart_block_rt1051_instance();
}
#else
-
- [[maybe_unused]] auto Driver::runLoopInitLinux(const btstack_run_loop *) -> const btstack_uart_block_t *
+ auto Driver::runLoopInitLinux([[maybe_unused]] const btstack_run_loop *loop) -> const btstack_uart_block_t *
{
btstack_run_loop_init(btstack_run_loop_posix_get_instance());
config.device_name = "/dev/telit";
LOG_INFO("H4 device: %s", config.device_name);
- const btstack_uart_block_t *uartDriver = btstack_uart_block_posix_instance();
- return uartDriver;
+ return btstack_uart_block_posix_instance();
}
#endif
@@ 76,22 72,26 @@ namespace bluetooth
auto uartDriver = runLoopInitLinux(runLoop);
#endif
- const hci_transport_t *transport = hci_transport_h4_instance_for_uart(uartDriver);
+ const auto transport = hci_transport_h4_instance_for_uart(uartDriver);
hci_init(transport, (void *)&config);
hci_set_link_key_db(bluetooth::KeyStorage::getKeyStorage());
- hci_event_callback_registration.callback = &hci_packet_handler;
- hci_add_event_handler(&hci_event_callback_registration);
+ hciEventCallbackRegistration.callback = &hciPacketHandler;
+ hci_add_event_handler(&hciEventCallbackRegistration);
gap_ssp_set_io_capability(SSP_IO_CAPABILITY_DISPLAY_YES_NO);
gap_ssp_set_auto_accept(false);
gap_set_class_of_device(0x64020C);
+
LOG_DEBUG("BT worker run success");
return Result::Code::Success;
}
- void Driver::hci_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)
+ void Driver::hciPacketHandler(std::uint8_t packet_type,
+ std::uint16_t channel,
+ std::uint8_t *packet,
+ std::uint16_t size)
{
bd_addr_t addr;
if (packet_type != HCI_EVENT_PACKET) {
@@ 103,7 103,7 @@ namespace bluetooth
break;
}
gap_local_bd_addr(addr);
- LOG_INFO("BTstack up and running");
+ LOG_INFO("BTStack up and running");
bluetooth::KeyStorage::settings->setValue(bluetooth::Settings::State,
static_cast<int>(BluetoothStatus::State::On));
if (powerOnCallback) {
@@ 115,24 115,24 @@ namespace bluetooth
if (hci_event_command_complete_get_return_parameters(packet)[0] != 0u) {
break;
}
- // terminate, name 248 chars
+ // Terminate, name 248 chars
packet[6 + 248] = 0;
}
if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_local_version_information)) {
- local_version_information_handler(packet);
+ localVersionInformationHandler(packet);
}
break;
default:
break;
}
}
- void Driver::local_version_information_handler(uint8_t *packet)
+ void Driver::localVersionInformationHandler(uint8_t *packet)
{
- uint16_t hci_version = packet[6];
- uint16_t hci_revision = little_endian_read_16(packet, 7);
- uint16_t lmp_version = packet[9];
- uint16_t manufacturer = little_endian_read_16(packet, 10);
- uint16_t lmp_subversion = little_endian_read_16(packet, 12);
+ const std::uint16_t hci_version = packet[6];
+ const std::uint16_t hci_revision = little_endian_read_16(packet, 7);
+ const std::uint16_t lmp_version = packet[9];
+ const std::uint16_t manufacturer = little_endian_read_16(packet, 10);
+ const std::uint16_t lmp_subversion = little_endian_read_16(packet, 12);
LOG_INFO("Local version information: HCI Version: 0x%04x, HCI Revision: 0x%04x, LMP Version: 0x%04x, LMP "
"Subversion: 0x%04x, Manufacturer: 0x%04x",
hci_version,
@@ 169,6 169,7 @@ namespace bluetooth
break;
}
}
+
auto Driver::run() -> Result::Code
{
auto ret = hci_power_control(HCI_POWER_ON);
@@ 208,18 209,22 @@ namespace bluetooth
static_cast<int>(BluetoothStatus::State::Off));
return ret != 0 ? Result::Code::LibraryError : Result::Code::Success;
}
+
auto Driver::scan() -> Result
{
return gap->scan();
}
+
void Driver::stopScan()
{
gap->stopScan();
}
+
void Driver::setVisibility(bool visibility)
{
gap->setVisibility(visibility);
}
+
void Driver::pair(Devicei device, std::uint8_t protectionLevel)
{
LOG_INFO("Device: %s, addr: %s", device.name.data(), device.address_str());
@@ 230,5 235,4 @@ namespace bluetooth
{
gap->unpair(device);
}
-
} // namespace bluetooth
M module-bluetooth/Bluetooth/interface/BluetoothDriverImpl.hpp => module-bluetooth/Bluetooth/interface/BluetoothDriverImpl.hpp +7 -4
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 20,12 20,15 @@ namespace bluetooth
private:
static hci_transport_config_uart_t config;
const btstack_run_loop *runLoop;
- btstack_packet_callback_registration_t hci_event_callback_registration;
+ btstack_packet_callback_registration_t hciEventCallbackRegistration;
std::unique_ptr<bluetooth::GAP> gap;
static PowerOnCallback powerOnCallback;
- static void hci_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
- static void local_version_information_handler(uint8_t *packet);
+ static void hciPacketHandler(std::uint8_t packet_type,
+ std::uint16_t channel,
+ std::uint8_t *packet,
+ std::uint16_t size);
+ static void localVersionInformationHandler(std::uint8_t *packet);
#ifdef TARGET_RT1051
[[maybe_unused]] auto runLoopInitTarget(const btstack_run_loop *runLoop) -> const btstack_uart_block_t *;
#else
M module-bsp/board/linux/bluetooth/Bluetooth.cpp => module-bsp/board/linux/bluetooth/Bluetooth.cpp +29 -40
@@ 1,31 1,35 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "bsp/bluetooth/Bluetooth.hpp"
-#include <log/log.hpp>
-
-/// stubs
+#include <memory>
using namespace bsp;
BlueKitchen::BlueKitchen() = default;
+BlueKitchen::~BlueKitchen() = default;
-BlueKitchen *BlueKitchen::getInstance()
+BlueKitchen &BlueKitchen::getInstance()
{
- static BlueKitchen *k = NULL;
- if (k == NULL) {
- k = new BlueKitchen();
+ static std::unique_ptr<BlueKitchen> instance;
+ if (instance == nullptr) {
+ instance = std::make_unique<BlueKitchen>();
}
- return k;
+ return *instance;
}
-BluetoothCommon::BluetoothCommon() = default;
+BTDevice::Error BlueKitchen::read(std::uint8_t *buf, std::size_t size)
+{
+ return BTDevice::Error::Success;
+}
-BlueKitchen::~BlueKitchen()
-{}
+BTDevice::Error BlueKitchen::write(const std::uint8_t *buf, std::size_t size)
+{
+ return BTDevice::Error::Success;
+}
-BluetoothCommon::~BluetoothCommon()
-{}
+BluetoothCommon::BluetoothCommon() = default;
+BluetoothCommon::~BluetoothCommon() = default;
void BluetoothCommon::open()
{}
@@ 33,48 37,33 @@ void BluetoothCommon::open()
void BluetoothCommon::close()
{}
-void BluetoothCommon::sleep_ms(ssize_t ms)
+void BluetoothCommon::sleepMs(std::size_t ms)
{
ulTaskNotifyTake(pdTRUE, ms);
}
-BTdev::Error BlueKitchen::read(uint8_t *buf, size_t nbytes)
-{
- return Success;
-}
-
-BTdev::Error BluetoothCommon::read(uint8_t *buf, size_t nbytes)
-{
- return Success;
-}
-
-BTdev::Error BlueKitchen::write(const uint8_t *buf, size_t nbytes)
-{
- return Success;
-}
-
-BTdev::Error BluetoothCommon::write(const uint8_t *buf, size_t nbytes)
+BTDevice::Error BluetoothCommon::read(std::uint8_t *buf, std::size_t size)
{
- return Success;
+ return BTDevice::Error::Success;
}
-ssize_t BluetoothCommon::write_blocking(const uint8_t *buf, ssize_t nbytes)
+BTDevice::Error BluetoothCommon::write(const std::uint8_t *buf, std::size_t size)
{
- return 0;
+ return BTDevice::Error::Success;
}
-BTdev::Error BluetoothCommon::set_baudrate(uint32_t bd)
+BTDevice::Error BluetoothCommon::setBaudrate([[maybe_unused]] std::uint32_t baud)
{
- return Success;
+ return BTDevice::Error::Success;
}
-BTdev::Error BluetoothCommon::set_reset(bool on)
+BTDevice::Error BluetoothCommon::setReset([[maybe_unused]] bool on)
{
- return Success;
+ return BTDevice::Error::Success;
}
-void BluetoothCommon::init_uart()
+void BluetoothCommon::uartInit()
{}
-void BluetoothCommon::set_irq(bool enable)
+void BluetoothCommon::setIrq([[maybe_unused]] bool enable)
{}
M module-bsp/board/rt1051/bluetooth/BlueKitchen.cpp => module-bsp/board/rt1051/bluetooth/BlueKitchen.cpp +22 -29
@@ 1,11 1,9 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "bsp/bluetooth/Bluetooth.hpp"
#include <log/log.hpp>
#include "FreeRTOS.h"
-#include "fsl_lpuart.h"
-#include "board.h"
#if DEBUG_BLUETOOTH_HCI_COMS == 1
#define logHciStack(...) LOG_DEBUG(__VA_ARGS__)
@@ 17,62 15,57 @@ using namespace bsp;
BlueKitchen::BlueKitchen()
{
- read_buff = NULL;
- read_ready_cb = NULL;
- write_done_cb = NULL;
+ readBuffer = nullptr;
+ readReadyCallback = nullptr;
+ writeDoneCallback = nullptr;
}
BlueKitchen::~BlueKitchen() = default;
-BlueKitchen *BlueKitchen::getInstance()
+BlueKitchen &BlueKitchen::getInstance()
{
- static BlueKitchen *k = NULL;
- if (k == NULL) {
- /// outcomming & incomming heap allocated buffers sizes
- /// packet on IP network cna have MTU 1500, so big enough buffers were added to not throttle comms
- k = new BlueKitchen();
+ static std::unique_ptr<BlueKitchen> instance;
+ if (instance == nullptr) {
+ instance = std::make_unique<BlueKitchen>();
}
- return k;
+ return *instance;
}
-BTdev::Error BlueKitchen::read(uint8_t *buf, size_t nbytes)
+BTDevice::Error BlueKitchen::read(uint8_t *buf, size_t nbytes)
{
logHciStack("BlueKitchen requested to read %d bytes", nbytes);
- uint8_t val;
+ std::uint8_t val;
- read_buff = buf; // point at the Bt stack read buffer
- read_len = nbytes;
+ readBuffer = buf;
+ readLength = nbytes;
- if (BluetoothCommon::read(buf, nbytes) == Success) {
+ if (BluetoothCommon::read(buf, nbytes) == BTDevice::Error::Success) {
val = bluetooth::Message::EvtReceiving;
xQueueSend(qHandle, &val, portMAX_DELAY);
- return BTdev::Success;
+ return BTDevice::Error::Success;
}
else {
val = bluetooth::Message::EvtReceivingError;
xQueueSend(qHandle, &val, portMAX_DELAY);
- return BTdev::ErrorBSP;
+ return BTDevice::Error::ErrorBSP;
}
}
-BTdev::Error BlueKitchen::write(const uint8_t *buf, size_t size)
+BTDevice::Error BlueKitchen::write(const uint8_t *buf, size_t size)
{
- uint8_t val;
-
logHciStack("BlueKitchen sends %d bytes", size);
- if (BluetoothCommon::write(buf, size) == Success) {
+ std::uint8_t val;
+
+ if (BluetoothCommon::write(buf, size) == BTDevice::Error::Success) {
val = bluetooth::Message::EvtSending;
xQueueSend(qHandle, &val, portMAX_DELAY);
- return BTdev::Success;
+ return BTDevice::Error::Success;
}
else {
val = bluetooth::Message::EvtSendingError;
xQueueSend(qHandle, &val, portMAX_DELAY);
- return BTdev::ErrorBSP;
+ return BTDevice::Error::ErrorBSP;
}
}
-
-void BlueKitchen::set_flowcontrol(int on)
-{}
M module-bsp/board/rt1051/bluetooth/BluetoothCommon.cpp => module-bsp/board/rt1051/bluetooth/BluetoothCommon.cpp +118 -129
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "bsp/bluetooth/Bluetooth.hpp"
@@ 23,78 23,103 @@
using namespace bsp;
-lpuart_edma_handle_t BluetoothCommon::uartDmaHandle = {};
+namespace
+{
+ std::uint32_t uartGetPeripheralClock()
+ {
+ constexpr auto UART_PERIPHERAL_PLL_DIVIDER = 6;
+ std::uint32_t freq;
+
+ /* To make it simple, we assume default PLL and divider settings, and the
+ * only variable from application is use PLL3 source or OSC source */
+ if (CLOCK_GetMux(kCLOCK_UartMux) == 0) /* PLL3 div6 80M */
+ {
+ freq =
+ (CLOCK_GetPllFreq(kCLOCK_PllUsb1) / UART_PERIPHERAL_PLL_DIVIDER) / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U);
+ }
+ else {
+ freq = CLOCK_GetOscFreq() / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U);
+ }
+
+ return freq;
+ }
+} // namespace
-uint32_t UartGetPeripheralClock();
+lpuart_edma_handle_t BluetoothCommon::uartDmaHandle = {};
BluetoothCommon::BluetoothCommon()
{
- gpio_pin_config_t gpio_init_structure;
- gpio_init_structure.direction = kGPIO_DigitalOutput;
- gpio_init_structure.interruptMode = kGPIO_NoIntmode;
- gpio_init_structure.outputLogic = 0;
- GPIO_PinInit(BSP_BLUETOOTH_SHUTDOWN_PORT, BSP_BLUETOOTH_SHUTDOWN_PIN, &gpio_init_structure);
+ gpio_pin_config_t gpioConfig;
+ gpioConfig.direction = kGPIO_DigitalOutput;
+ gpioConfig.interruptMode = kGPIO_NoIntmode;
+ gpioConfig.outputLogic = 0;
+ GPIO_PinInit(BSP_BLUETOOTH_SHUTDOWN_PORT, BSP_BLUETOOTH_SHUTDOWN_PIN, &gpioConfig);
}
BluetoothCommon::~BluetoothCommon() = default;
void BluetoothCommon::open()
{
- init_uart();
- init_uart_dma();
+ uartInit();
+ uartDmaInit();
LOG_INFO("Bluetooth HW init done from open!");
- set_irq(true);
- set_reset(true);
- is_open = true;
+
+ setIrq(true);
+ setReset(true);
+ isOpen = true;
LOG_INFO("Bluetooth HW open!");
}
void BluetoothCommon::close()
{
- set_irq(false);
- is_open = false;
- set_reset(false);
- deinit_uart_dma();
- deinit_uart();
+ setReset(false);
+ setIrq(false);
+ isOpen = false;
+
+ uartDmaDeinit();
+ uartDeinit();
LOG_INFO("Bluetooth HW close!");
}
-void BluetoothCommon::sleep_ms(ssize_t ms)
+void BluetoothCommon::sleepMs(std::size_t ms)
{
ulTaskNotifyTake(pdTRUE, ms);
}
-BTdev::Error BluetoothCommon::read(uint8_t *buf, size_t nbytes)
+BTDevice::Error BluetoothCommon::read(std::uint8_t *buf, std::size_t size)
{
auto ret = ErrorUndefined;
- // start RXfer if there is a byte incoming and no pending RXfer
+ // Start RXfer if there is a byte incoming and no pending RXfer
lpuart_transfer_t receiveXfer;
receiveXfer.data = buf;
- receiveXfer.dataSize = nbytes;
+ receiveXfer.dataSize = size;
- // rx config
+ // Rx config
SCB_CleanInvalidateDCache();
LPUART_EnableRx(BSP_BLUETOOTH_UART_BASE, true);
- auto status = LPUART_ReceiveEDMA(BSP_BLUETOOTH_UART_BASE, &uartDmaHandle, &receiveXfer);
+ const auto status = LPUART_ReceiveEDMA(BSP_BLUETOOTH_UART_BASE, &uartDmaHandle, &receiveXfer);
switch (status) {
case kStatus_Success:
ret = Success;
break;
case kStatus_LPUART_RxBusy:
ret = ErrorBSP;
- LOG_WARN("BT UART RX DMA already busy");
+ LOG_WARN("BT UART Rx DMA already busy");
break;
case kStatus_InvalidArgument:
- LOG_WARN("BT UART RX DMA invalid argument");
+ LOG_WARN("BT UART Rx DMA invalid argument");
ret = ErrorBSP;
break;
+ default:
+ LOG_WARN("Unhandled case, status %ld", status);
+ break;
}
return ret;
}
-BTdev::Error BluetoothCommon::write(const uint8_t *buf, size_t size)
+BTDevice::Error BluetoothCommon::write(const std::uint8_t *buf, std::size_t size)
{
logHciBytes("BT DMA to write --> [%d]>%s<",
size,
@@ 106,27 131,28 @@ BTdev::Error BluetoothCommon::write(const uint8_t *buf, size_t size)
return ss.str();
}()
.c_str());
+
auto ret = ErrorUndefined;
lpuart_transfer_t sendXfer;
- sendXfer.data = const_cast<uint8_t *>(buf);
+ sendXfer.data = const_cast<std::uint8_t *>(buf);
sendXfer.dataSize = size;
uartDmaHandle.userData = xTaskGetCurrentTaskHandle();
- // tx config
+ // Tx config
SCB_CleanInvalidateDCache();
LPUART_EnableTx(BSP_BLUETOOTH_UART_BASE, true);
- auto sent = LPUART_SendEDMA(BSP_BLUETOOTH_UART_BASE, &uartDmaHandle, &sendXfer);
- switch (sent) {
+ const auto status = LPUART_SendEDMA(BSP_BLUETOOTH_UART_BASE, &uartDmaHandle, &sendXfer);
+ switch (status) {
case kStatus_Success:
- // orchestrate a DMA Tx
+ // Orchestrate a DMA Tx
logHciComs("DMA Tx started (%d)", size);
ret = Success;
break;
case kStatus_LPUART_TxBusy:
- // could've checked beforehand
+ // Could've checked beforehand
LOG_WARN("Previous DMA Tx is still pending");
ret = ErrorBSP;
break;
@@ 135,98 161,59 @@ BTdev::Error BluetoothCommon::write(const uint8_t *buf, size_t size)
LOG_ERROR("DMA Tx invalid arg");
ret = ErrorBSP;
break;
+ default:
+ LOG_WARN("Unhandled case, status %ld", status);
+ break;
}
return ret;
}
-ssize_t BluetoothCommon::write_blocking(const uint8_t *buf, ssize_t nbytes)
-{
- ssize_t ret = -1;
-
- auto wrote = write(const_cast<uint8_t *>(buf), nbytes);
-
- if (wrote == nbytes) { // success orchestrating a transfer
- constexpr auto writeBlockingTimeout = pdMS_TO_TICKS(100);
- auto ulNotificationValue = ulTaskNotifyTake(pdFALSE, writeBlockingTimeout);
- if (ulNotificationValue != 0) { // success completing a transfer
- logHciComs("DMA Tx wrote");
- ret = nbytes;
- }
- else {
- LOG_ERROR("DMA Tx timeout");
- ret = -1;
- }
- }
- else {
- LOG_WARN("DMA Tx not wrote (%d/%d)", wrote, nbytes);
- }
- return ret;
-}
-
-BTdev::Error BluetoothCommon::set_baudrate(uint32_t bd)
+BTDevice::Error BluetoothCommon::setBaudrate(std::uint32_t baud)
{
- LOG_INFO("Set baudrate: %" PRIu32, bd);
+ LOG_INFO("Set baudrate: %" PRIu32, baud);
Error ret = Success;
- int err = 0;
- if ((err = LPUART_SetBaudRate(BSP_BLUETOOTH_UART_BASE, bd, UartGetPeripheralClock())) != 0) {
- LOG_ERROR("BT error: baudrate [%lu] set err: %d", bd, err);
+ const auto err = LPUART_SetBaudRate(BSP_BLUETOOTH_UART_BASE, baud, uartGetPeripheralClock());
+ if (err) {
+ LOG_ERROR("BT: baudrate %lu, error %ld", baud, err);
ret = ErrorBSP;
}
- BSP_BLUETOOTH_UART_BASE->FIFO |= LPUART_FIFO_RXFLUSH_MASK; // flush fifo
- BSP_BLUETOOTH_UART_BASE->FIFO &= ~LPUART_FIFO_RXFE_MASK; // disable fifo
+ BSP_BLUETOOTH_UART_BASE->FIFO |= LPUART_FIFO_RXFLUSH_MASK; // Flush fifo
+ BSP_BLUETOOTH_UART_BASE->FIFO &= ~LPUART_FIFO_RXFE_MASK; // Disable fifo
return ret;
}
-BTdev::Error BluetoothCommon::set_reset(bool on)
+BTDevice::Error BluetoothCommon::setReset(bool on)
{
if (on) {
GPIO_PinWrite(BSP_BLUETOOTH_SHUTDOWN_PORT, BSP_BLUETOOTH_SHUTDOWN_PIN, 0);
- // docs: "nSHUTD must be low for a minimum of 5 ms."
- sleep_ms(5 + 2);
+ sleepMs(5 + 2); // docs: "nSHUTD must be low for a minimum of 5 ms."
}
- LOG_INFO("reset %s", on ? "on" : "off");
+ LOG_INFO("reset: %s", on ? "on" : "off");
GPIO_PinWrite(BSP_BLUETOOTH_SHUTDOWN_PORT, BSP_BLUETOOTH_SHUTDOWN_PIN, on ? 1U : 0U);
return Success;
}
-uint32_t UartGetPeripheralClock()
+void BluetoothCommon::uartInit()
{
- const int UART_PERIPHERAL_PLL_DIVIDER = 6;
- uint32_t freq = 0;
- /* To make it simple, we assume default PLL and divider settings, and the only variable
- from application is use PLL3 source or OSC source */
- if (CLOCK_GetMux(kCLOCK_UartMux) == 0) /* PLL3 div6 80M */
- {
- freq = (CLOCK_GetPllFreq(kCLOCK_PllUsb1) / UART_PERIPHERAL_PLL_DIVIDER) / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U);
- }
- else {
- freq = CLOCK_GetOscFreq() / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U);
- }
-
- return freq;
-}
-
-void BluetoothCommon::init_uart()
-{
- lpuart_config_t bt_c;
- LPUART_GetDefaultConfig(&bt_c);
- bt_c.baudRate_Bps = baudrate;
- bt_c.dataBitsCount = kLPUART_EightDataBits;
- bt_c.parityMode = kLPUART_ParityDisabled;
- bt_c.isMsb = false;
- bt_c.rxIdleType = kLPUART_IdleTypeStartBit;
- bt_c.rxIdleConfig = kLPUART_IdleCharacter1;
- bt_c.enableTx = false;
- bt_c.enableRx = false;
- bt_c.enableTxCTS = true;
- bt_c.txCtsConfig = kLPUART_CtsSampleAtStart; // to be able to stop TX mid-transfer
- bt_c.enableRxRTS = true; // == BSP_BLUETOOTH_UART_BASE->MODIR |= LPUART_MODIR_RXRTSE_MASK;
-
- if (LPUART_Init(BSP_BLUETOOTH_UART_BASE, &bt_c, UartGetPeripheralClock()) != kStatus_Success) {
- LOG_ERROR("BT: UART config error Could not initialize the uart!");
+ lpuart_config_t uartConfig;
+ LPUART_GetDefaultConfig(&uartConfig);
+ uartConfig.baudRate_Bps = defaultBaudRate;
+ uartConfig.dataBitsCount = kLPUART_EightDataBits;
+ uartConfig.parityMode = kLPUART_ParityDisabled;
+ uartConfig.isMsb = false;
+ uartConfig.rxIdleType = kLPUART_IdleTypeStartBit;
+ uartConfig.rxIdleConfig = kLPUART_IdleCharacter1;
+ uartConfig.enableTx = false;
+ uartConfig.enableRx = false;
+ uartConfig.enableTxCTS = true;
+ uartConfig.txCtsConfig = kLPUART_CtsSampleAtStart; // To be able to stop TX mid-transfer
+ uartConfig.enableRxRTS = true; // == BSP_BLUETOOTH_UART_BASE->MODIR |= LPUART_MODIR_RXRTSE_MASK;
+
+ if (LPUART_Init(BSP_BLUETOOTH_UART_BASE, &uartConfig, uartGetPeripheralClock()) != kStatus_Success) {
+ LOG_ERROR("BT: UART config error, could not initialize!");
return;
}
- BSP_BLUETOOTH_UART_BASE->MODIR |= LPUART_MODIR_TXRTSPOL_MASK; // apparently docs are not clear here. HIGH during TX
+ BSP_BLUETOOTH_UART_BASE->MODIR |= LPUART_MODIR_TXRTSPOL_MASK; // Apparently docs are not clear here. HIGH during Tx
LPUART_ClearStatusFlags(BSP_BLUETOOTH_UART_BASE, 0xFFFFFFFF);
NVIC_ClearPendingIRQ(LPUART2_IRQn);
@@ 234,18 221,18 @@ void BluetoothCommon::init_uart()
NVIC_EnableIRQ(LPUART2_IRQn);
}
-void BluetoothCommon::init_uart_dma()
+void BluetoothCommon::uartDmaInit()
{
dmamux = drivers::DriverDMAMux::Create(static_cast<drivers::DMAMuxInstances>(BoardDefinitions::BLUETOOTH_DMAMUX),
drivers::DriverDMAMuxParams{});
dma = drivers::DriverDMA::Create(static_cast<drivers::DMAInstances>(BoardDefinitions::BLUETOOTH_DMA),
drivers::DriverDMAParams{});
- uartTxDmaHandle = dma->CreateHandle(static_cast<uint32_t>(BoardDefinitions::BLUETOOTH_TX_DMA_CHANNEL));
- uartRxDmaHandle = dma->CreateHandle(static_cast<uint32_t>(BoardDefinitions::BLUETOOTH_RX_DMA_CHANNEL));
+ uartTxDmaHandle = dma->CreateHandle(static_cast<std::uint32_t>(BoardDefinitions::BLUETOOTH_TX_DMA_CHANNEL));
+ uartRxDmaHandle = dma->CreateHandle(static_cast<std::uint32_t>(BoardDefinitions::BLUETOOTH_RX_DMA_CHANNEL));
- dmamux->Enable(static_cast<uint32_t>(BoardDefinitions::BLUETOOTH_TX_DMA_CHANNEL), kDmaRequestMuxLPUART2Tx);
- dmamux->Enable(static_cast<uint32_t>(BoardDefinitions::BLUETOOTH_RX_DMA_CHANNEL), kDmaRequestMuxLPUART2Rx);
+ dmamux->Enable(static_cast<std::uint32_t>(BoardDefinitions::BLUETOOTH_TX_DMA_CHANNEL), kDmaRequestMuxLPUART2Tx);
+ dmamux->Enable(static_cast<std::uint32_t>(BoardDefinitions::BLUETOOTH_RX_DMA_CHANNEL), kDmaRequestMuxLPUART2Rx);
LPUART_TransferCreateHandleEDMA(BSP_BLUETOOTH_UART_BASE,
&uartDmaHandle,
@@ 255,7 242,7 @@ void BluetoothCommon::init_uart_dma()
reinterpret_cast<edma_handle_t *>(uartRxDmaHandle->GetHandle()));
}
-void BluetoothCommon::deinit_uart()
+void BluetoothCommon::uartDeinit()
{
LPUART_EnableRx(BSP_BLUETOOTH_UART_BASE, false);
LPUART_EnableTx(BSP_BLUETOOTH_UART_BASE, false);
@@ 268,40 255,42 @@ void BluetoothCommon::deinit_uart()
LPUART_Deinit(BSP_BLUETOOTH_UART_BASE);
}
-void BluetoothCommon::deinit_uart_dma()
+void BluetoothCommon::uartDmaDeinit()
{
- dmamux->Disable(static_cast<uint32_t>(BoardDefinitions::BLUETOOTH_RX_DMA_CHANNEL));
- dmamux->Disable(static_cast<uint32_t>(BoardDefinitions::BLUETOOTH_TX_DMA_CHANNEL));
+ dmamux->Disable(static_cast<std::uint32_t>(BoardDefinitions::BLUETOOTH_RX_DMA_CHANNEL));
+ dmamux->Disable(static_cast<std::uint32_t>(BoardDefinitions::BLUETOOTH_TX_DMA_CHANNEL));
}
void BluetoothCommon::uartDmaCallback(LPUART_Type *base, lpuart_edma_handle_t *handle, status_t status, void *userData)
{
- BaseType_t taskwoken = 0;
- uint8_t val;
- bsp::BlueKitchen *bt = bsp::BlueKitchen::getInstance();
+ std::uint8_t val;
+ BaseType_t xHigherPriorityTaskWoken = 0;
+ auto &blueKitchen = bsp::BlueKitchen::getInstance();
switch (status) {
case kStatus_LPUART_TxIdle: {
- logHciComs("DMA irq: TX done");
+ logHciComs("DMA IRQ: TX done");
LPUART_EnableTx(BSP_BLUETOOTH_UART_BASE, false);
val = bluetooth::Message::EvtSent;
- xQueueSendFromISR(bt->qHandle, &val, &taskwoken);
- portEND_SWITCHING_ISR(taskwoken);
+ xQueueSendFromISR(blueKitchen.qHandle, &val, &xHigherPriorityTaskWoken);
+ portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
break;
}
case kStatus_LPUART_RxIdle:
- logHciComs("DMA irq: RX done");
+ logHciComs("DMA IRQ: RX done");
LPUART_EnableRx(BSP_BLUETOOTH_UART_BASE, false);
val = bluetooth::Message::EvtReceived;
- xQueueSendFromISR(bt->qHandle, &val, &taskwoken);
- portEND_SWITCHING_ISR(taskwoken);
+ xQueueSendFromISR(blueKitchen.qHandle, &val, &xHigherPriorityTaskWoken);
+ portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
+ break;
+ default:
+ logHciComs("DMA IRQ: unhandled case");
break;
}
}
-void BluetoothCommon::set_irq(bool enable)
+void BluetoothCommon::setIrq(bool enable)
{
- // printf("%s\n", __FUNCTION__);
LPUART_EnableRx(BSP_BLUETOOTH_UART_BASE, false);
LPUART_EnableTx(BSP_BLUETOOTH_UART_BASE, false);
LPUART_ClearStatusFlags(BSP_BLUETOOTH_UART_BASE, 0xFFFFFFFF);
@@ 317,18 306,18 @@ extern "C"
{
void LPUART2_IRQHandler(void)
{
- uint32_t isrReg = LPUART_GetStatusFlags(BSP_BLUETOOTH_UART_BASE);
- BaseType_t taskwoken = 0;
+ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
uint8_t val = bluetooth::Message::EvtReceived;
- bsp::BlueKitchen *bt = bsp::BlueKitchen::getInstance();
+ uint32_t isrReg = LPUART_GetStatusFlags(BSP_BLUETOOTH_UART_BASE);
+ bsp::BlueKitchen &blueKitchen = bsp::BlueKitchen::getInstance();
if (isrReg & kLPUART_RxDataRegFullFlag) {
- LOG_WARN("Bluetooth IRQ RX full");
+ LOG_WARN("Bluetooth IRQ Rx full");
}
if (isrReg & kLPUART_RxOverrunFlag) {
- LOG_WARN("Bluetooth IRQ RX overrun");
+ LOG_WARN("Bluetooth IRQ Rx overrun");
val = bluetooth::Message::EvtUartError;
- xQueueSendFromISR(bt->qHandle, &val, &taskwoken);
+ xQueueSendFromISR(blueKitchen.qHandle, &val, &xHigherPriorityTaskWoken);
}
LPUART_ClearStatusFlags(BSP_BLUETOOTH_UART_BASE, isrReg);
}
D module-bsp/board/rt1051/bluetooth/Bluetopia.cpp => module-bsp/board/rt1051/bluetooth/Bluetopia.cpp +0 -57
@@ 1,57 0,0 @@
-// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#include "bluetooth/Bluetooth.hpp"
-#include <log/log.hpp>
-#include "fsl_lpuart.h"
-#include "board.h"
-
-namespace bsp
-{
-
- Bluetopia::Bluetopia(unsigned int in_size, unsigned int out_size, int threshold)
- : BluetoothCommon(default_buff_size, default_buff_size, 32)
- {}
-
- Bluetopia::~Bluetopia()
- {}
-
- Bluetopia *Bluetopia::getInstance()
- {
- static Bluetopia *inst = NULL;
- if (inst == NULL) {
- inst = new Bluetopia();
- }
- return inst;
- }
-
- ssize_t Bluetopia::read(void *, size_t nbytes)
- {
- LOG_INFO("not implemented");
- return 0;
- }
-
- extern "C"
- {
- void LPUART2_IRQHandler(void)
- {
- uint32_t isrReg = LPUART_GetStatusFlags(BSP_BLUETOOTH_UART_BASE);
- static char characterReceived = 0;
-
- if (isrReg & kLPUART_RxDataRegFullFlag) {
- characterReceived = LPUART_ReadByte(BSP_BLUETOOTH_UART_BASE);
- bsp::Bluetopia *bt = bsp::Bluetopia::getInstance();
- if (bt->in.push(characterReceived) == 0) {
- bt->set_data();
- }
- if (bt->in.threshold_guard()) {
- bt->set_rts(false);
- }
- }
- // TODO ths should be handled - othervise uart might be `nicelly` blocked
- if (isrReg & kLPUART_RxOverrunFlag) {
- printf("Overrun\n");
- }
- LPUART_ClearStatusFlags(BSP_BLUETOOTH_UART_BASE, isrReg);
- }
- };
M module-bsp/bsp/bluetooth/Bluetooth.cpp => module-bsp/bsp/bluetooth/Bluetooth.cpp +8 -15
@@ 1,25 1,18 @@
#include "Bluetooth.hpp"
#include <cstdarg>
+namespace bsp
+{
+ BTDevice::BTDevice() : logLevel{LogNone}, isOpen{false}, logFunction{nullptr}
+ {}
-namespace bsp {
- BTdev::BTdev() : flog(nullptr)
+ void BTDevice::log(LogLevel level, const char *val, ...)
{
- is_open = false;
- }
-
- BTdev::~BTdev()
- {
- }
-
- void BTdev::log(LogLvl lvl,const char* val, ...)
- {
- if(loglvl>=lvl && flog) {
+ if ((logLevel >= level) && (logFunction != nullptr)) {
va_list args;
va_start(args, val);
- flog(val,args);
+ logFunction(val, args);
va_end(args);
}
}
-
-};
+}
M module-bsp/bsp/bluetooth/Bluetooth.hpp => module-bsp/bsp/bluetooth/Bluetooth.hpp +90 -84
@@ 1,7 1,7 @@
#pragma once
-#include <cstdint> // uint32
-#include <sys/types.h> // ssize_t
+#include <cstdint>
+#include <sys/types.h>
#include <cstdarg>
#include <FreeRTOS.h>
#include <thread.hpp>
@@ 13,10 13,10 @@
#include "drivers/dma/DriverDMA.hpp"
#endif
-/// c++ low level driver overlay
-
-namespace bsp {
+/// C++ low level driver overlay
+namespace bsp
+{
namespace bluetooth
{
enum Message : std::uint8_t
@@ 34,95 34,101 @@ namespace bsp {
};
}
- class BTdev {
- public:
- enum Error {
- Success,
- ErrorUndefined,
- ErrorTimeout,
- ErrorBSP,
- };
- enum LogLvl {
- LogNone,
- LogError,
- LogWarning,
- LogDebug,
- };
- typedef int(*LogFoo)(const char*,va_list args);
- private:
- LogFoo flog;
- public:
- LogLvl loglvl;
- bool is_open;
- static const unsigned int default_timeout_ms = 1000;
- static const unsigned int default_buff_size = 1024;
- static const unsigned int default_baudrate = 115200;
-
- BTdev();
- virtual ~BTdev();
-
- // general
- virtual void open() = 0; // enable device -> irq enable
- virtual void close() = 0; // disable device -> irq disable
- virtual BTdev::Error read(uint8_t *buf, size_t nbytes) = 0;
- void log(LogLvl lvl,const char* val, ...);
- // uart specific
+ class BTDevice
+ {
+ public:
+ enum Error
+ {
+ Success,
+ ErrorUndefined,
+ ErrorTimeout,
+ ErrorBSP,
+ };
+
+ enum LogLevel
+ {
+ LogNone,
+ LogError,
+ LogWarning,
+ LogDebug,
+ };
+
+ using LogFunction = int (*)(const char *msg, va_list args);
+
+ BTDevice();
+ virtual ~BTDevice() = default;
+
+ virtual void open() = 0; // enable device -> irq enable
+ virtual void close() = 0; // disable device -> irq disable
+
+ virtual Error read(std::uint8_t *buf, std::size_t size) = 0;
+
+ void log(LogLevel level, const char *msg, ...);
+
+ LogLevel logLevel;
+ bool isOpen;
+
+ private:
+ LogFunction logFunction;
};
- class BluetoothCommon : public BTdev
+ class BluetoothCommon : public BTDevice
{
- public:
- static const ssize_t baudrate =115200;
- static const ssize_t off_threshold =16;
- static const ssize_t on_threshold =32;
-
- BluetoothCommon();
- virtual ~BluetoothCommon();
- // uart specific Common part
- virtual void open() override;
- virtual void close() override;
- virtual BTdev::Error read(uint8_t *buf, size_t nbytes) override;
- virtual BTdev::Error write(const uint8_t *buf, size_t nbytes);
- virtual ssize_t write_blocking(const uint8_t *buf, ssize_t nbytes);
- Error set_baudrate(uint32_t bd);
- Error set_reset(bool on);
- void sleep_ms(ssize_t ms);
- void set_irq(bool enable);
-
- private:
- void init_uart();
- void deinit_uart();
- void init_uart_dma();
- void deinit_uart_dma();
+ public:
+ static constexpr std::uint32_t defaultBaudRate = 115200;
+
+ BluetoothCommon();
+ virtual ~BluetoothCommon();
+
+ // uart specific Common part
+ virtual void open() override;
+ virtual void close() override;
+
+ virtual Error read(std::uint8_t *buf, std::size_t size) override;
+ virtual Error write(const std::uint8_t *buf, std::size_t size);
+
+ Error setBaudrate(std::uint32_t baud);
+ Error setReset(bool on);
+ void setIrq(bool enable);
+
+ void sleepMs(std::size_t ms);
+
+ private:
+ void uartInit();
+ void uartDeinit();
+
+ void uartDmaInit();
+ void uartDmaDeinit();
#if defined(TARGET_RT1051)
- std::shared_ptr<drivers::DriverDMAMux> dmamux;
- std::shared_ptr<drivers::DriverDMA> dma;
- std::unique_ptr<drivers::DriverDMAHandle> uartRxDmaHandle;
- std::unique_ptr<drivers::DriverDMAHandle> uartTxDmaHandle;
- static AT_NONCACHEABLE_SECTION_INIT(lpuart_edma_handle_t uartDmaHandle);
- static void uartDmaCallback(LPUART_Type *base, lpuart_edma_handle_t *handle, status_t status, void *userData);
+ std::shared_ptr<drivers::DriverDMAMux> dmamux;
+ std::shared_ptr<drivers::DriverDMA> dma;
+ std::unique_ptr<drivers::DriverDMAHandle> uartRxDmaHandle;
+ std::unique_ptr<drivers::DriverDMAHandle> uartTxDmaHandle;
+ static AT_NONCACHEABLE_SECTION_INIT(lpuart_edma_handle_t uartDmaHandle);
+
+ static void uartDmaCallback(LPUART_Type *base, lpuart_edma_handle_t *handle, status_t status, void *userData);
#endif
};
- /// definitions needed by BT stack
+ /// Definitions needed by BT stack
+ class BlueKitchen : public BluetoothCommon
+ {
+ public:
+ BlueKitchen();
+ virtual ~BlueKitchen();
+ static BlueKitchen &getInstance();
- class BlueKitchen : public BluetoothCommon {
- public:
- BlueKitchen();
- virtual ~BlueKitchen();
- static BlueKitchen *getInstance();
+ virtual Error read(uint8_t *buf, size_t size) override;
+ virtual Error write(const uint8_t *buf, size_t size) override;
- virtual BTdev::Error read(uint8_t *buf, size_t nbytes) override;
- virtual BTdev::Error write(const uint8_t *buf, size_t size) override;
- uint32_t read_len = 0;
- uint8_t* read_buff;
+ std::uint32_t readLength = 0;
+ std::uint8_t *readBuffer;
- void set_flowcontrol(int on);
+ void (*readReadyCallback)();
+ void (*writeDoneCallback)();
- void (*read_ready_cb)(void);
- void (*write_done_cb)(void);
- /// to be able to trigger events on thread
- xQueueHandle qHandle = nullptr;
+ /// to be able to trigger events on thread
+ xQueueHandle qHandle = nullptr;
};
-};
+}
M module-bsp/drivers/dma/DriverDMA.hpp => module-bsp/drivers/dma/DriverDMA.hpp +3 -2
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#ifndef PUREPHONE_DRIVERDMA_HPP
@@ 9,7 9,6 @@
namespace drivers
{
-
enum class DMAInstances
{
DMA_0,
@@ 22,6 21,8 @@ namespace drivers
class DriverDMAHandle
{
public:
+ virtual ~DriverDMAHandle() = default;
+
virtual void *GetHandle() = 0;
};
M module-utils/log/api/log/debug.hpp => module-utils/log/api/log/debug.hpp +2 -2
@@ 1,4 1,4 @@
-// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once
@@ 13,7 13,7 @@
#define DEBUG_GUI_TEXT 0 /// show basic debug messages for gui::Text - warning this can be hard on cpu
#define DEBUG_GUI_TEXT_LINES 0 /// show extended debug messages for gui::Text - lines building
#define DEBUG_GUI_TEXT_CURSOR 0 /// show extended debug messages for gui::Text - cursor handling
-#define DEBUG_HEAP_ALLOCATIONS 0 /// gather heap allocations statictics
+#define DEBUG_HEAP_ALLOCATIONS 0 /// gather heap allocations statistics
#define DEBUG_INPUT_EVENTS 0 /// show input events prints in system
#define DEBUG_MISSING_ASSETS 0 /// show debug concerning missing assets
#define DEBUG_SCOPED_TIMINGS 0 /// show timings in measured functions