diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index c35760d03..33dcdda59 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -8,11 +8,9 @@ "https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "1c8cec495288dccd14fdae6e3f95f772c1c91857047a098fad772034264cc8cb", "https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16", "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed", - "https://bcr.bazel.build/modules/abseil-cpp/20240116.2/MODULE.bazel": "73939767a4686cd9a520d16af5ab440071ed75cec1a876bf2fcfaf1f71987a16", - "https://bcr.bazel.build/modules/abseil-cpp/20240116.2/source.json": "750d5e29326fb59cbe61116a7b803c8a1d0a7090a9c8ed89888d188e3c473fc7", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/source.json": "9be551b8d4e3ef76875c0d744b5d6a504a27e3ae67bc6b28f46415fd2d2957da", "https://bcr.bazel.build/modules/apple_support/1.13.0/MODULE.bazel": "7c8cdea7e031b7f9f67f0b497adf6d2c6a2675e9304ca93a9af6ed84eef5a524", - "https://bcr.bazel.build/modules/apple_support/1.15.1/MODULE.bazel": "a0556fefca0b1bb2de8567b8827518f94db6a6e7e7d632b4c48dc5f865bc7c85", - "https://bcr.bazel.build/modules/apple_support/1.15.1/source.json": "517f2b77430084c541bc9be2db63fdcbb7102938c5f64c17ee60ffda2e5cf07b", + "https://bcr.bazel.build/modules/apple_support/1.13.0/source.json": "aef5da52fdcfa9173e02c0cb772c85be5b01b9d49f97f9bb0fe3efe738938ba4", "https://bcr.bazel.build/modules/aspect_bazel_lib/1.31.2/MODULE.bazel": "7bee702b4862612f29333590f4b658a5832d433d6f8e4395f090e8f4e85d442f", "https://bcr.bazel.build/modules/aspect_bazel_lib/1.38.0/MODULE.bazel": "6307fec451ba9962c1c969eb516ebfe1e46528f7fa92e1c9ac8646bef4cdaa3f", "https://bcr.bazel.build/modules/aspect_bazel_lib/1.40.3/MODULE.bazel": "668e6bcb4d957fc0e284316dba546b705c8d43c857f87119619ee83c4555b859", @@ -41,8 +39,6 @@ "https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917", "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b", "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/source.json": "f121b43eeefc7c29efbd51b83d08631e2347297c95aac9764a701f2a6a2bb953", - "https://bcr.bazel.build/modules/boringssl/0.20240913.0/MODULE.bazel": "fcaa7503a5213290831a91ed1eb538551cf11ac0bc3a6ad92d0fef92c5bd25fb", - "https://bcr.bazel.build/modules/boringssl/0.20240913.0/source.json": "540753d29c271a302442a3d3c6ccd4faace597e7bcf0f77049fe59535782ce9f", "https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84", "https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8", "https://bcr.bazel.build/modules/freertos/10.5.1.bcr.2/MODULE.bazel": "dcc13aef86495f5418f4cdd532eefe9a4319c44771ef57b8abda0c3560d8e6ed", @@ -57,9 +53,8 @@ "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb", "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4", "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6", + "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/source.json": "41e9e129f80d8c8bf103a7acc337b76e54fad1214ac0a7084bf24f4cd924b8b4", "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f", - "https://bcr.bazel.build/modules/googletest/1.15.2/MODULE.bazel": "6de1edc1d26cafb0ea1a6ab3f4d4192d91a312fd2d360b63adaa213cd00b2108", - "https://bcr.bazel.build/modules/googletest/1.15.2/source.json": "dbdda654dcb3a0d7a8bc5d0ac5fc7e150b58c2a986025ae5bc634bb2cb61f470", "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902", "https://bcr.bazel.build/modules/pico-sdk/2.0.0/MODULE.bazel": "f96b730c6e871c1ca0a879b961a1a2430a4afbcb08a8dae8c8fa3ed2c86d9655", "https://bcr.bazel.build/modules/pico-sdk/2.0.0/source.json": "75dce384ee879127ca9d0f88d2154af4b7e59c7e72f3e2e6995e82c75fcd5961", @@ -81,11 +76,9 @@ "https://bcr.bazel.build/modules/protobuf/3.19.2/MODULE.bazel": "532ffe5f2186b69fdde039efe6df13ba726ff338c6bc82275ad433013fa10573", "https://bcr.bazel.build/modules/protobuf/3.19.6/MODULE.bazel": "9233edc5e1f2ee276a60de3eaa47ac4132302ef9643238f23128fea53ea12858", "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e", - "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/MODULE.bazel": "e6f4c20442eaa7c90d7190d8dc539d0ab422f95c65a57cc59562170c58ae3d34", - "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/source.json": "6900fdc8a9e95866b8c0d4ad4aba4d4236317b5c1cd04c502df3f0d33afed680", + "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/source.json": "be4789e951dd5301282729fe3d4938995dc4c1a81c2ff150afc9f1b0504c6022", "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206", - "https://bcr.bazel.build/modules/re2/2024-07-02/MODULE.bazel": "0eadc4395959969297cbcf31a249ff457f2f1d456228c67719480205aa306daa", - "https://bcr.bazel.build/modules/re2/2024-07-02/source.json": "547d0111a9d4f362db32196fef805abbf3676e8d6afbe44d395d87816c1130ca", + "https://bcr.bazel.build/modules/re2/2023-09-01/source.json": "e044ce89c2883cd957a2969a43e79f7752f9656f6b20050b62f90ede21ec6eb4", "https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8", "https://bcr.bazel.build/modules/rules_android/0.1.1/source.json": "e6986b41626ee10bdc864937ffb6d6bf275bb5b9c65120e6137d56e6331f089e", "https://bcr.bazel.build/modules/rules_buf/0.1.1/MODULE.bazel": "6189aec18a4f7caff599ad41b851ab7645d4f1e114aa6431acf9b0666eb92162", @@ -151,7 +144,6 @@ "https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382", "https://bcr.bazel.build/modules/rules_python/0.28.0/MODULE.bazel": "cba2573d870babc976664a912539b320cbaa7114cd3e8f053c720171cde331ed", "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58", - "https://bcr.bazel.build/modules/rules_python/0.33.2/MODULE.bazel": "3e036c4ad8d804a4dad897d333d8dce200d943df4827cb849840055be8d2e937", "https://bcr.bazel.build/modules/rules_python/0.36.0/MODULE.bazel": "a4ce1ccea92b9106c7d16ab9ee51c6183107e78ba4a37aa65055227b80cd480c", "https://bcr.bazel.build/modules/rules_python/0.36.0/source.json": "b79cbb7b2ae1751949e2f6ee6692822e4ffd13ca1e959ce99abec4ac7666162a", "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c", @@ -861,37 +853,6 @@ ] } }, - "@@pybind11_bazel+//:internal_configure.bzl%internal_configure_extension": { - "general": { - "bzlTransitiveDigest": "E2bVqsWslm5GH4rxOm+GWHFpneuy7kuqsKWgAIw5Avo=", - "usagesDigest": "qiX97eIdtifnntL7rISA+4Anot1sjD1YCIoUPSEkeG0=", - "recordedFileInputs": { - "@@pybind11_bazel+//MODULE.bazel": "e6f4c20442eaa7c90d7190d8dc539d0ab422f95c65a57cc59562170c58ae3d34" - }, - "recordedDirentsInputs": {}, - "envVariables": {}, - "generatedRepoSpecs": { - "pybind11": { - "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl", - "ruleClassName": "http_archive", - "attributes": { - "build_file": "@@pybind11_bazel+//:pybind11-BUILD.bazel", - "strip_prefix": "pybind11-2.12.0", - "urls": [ - "https://github.com/pybind/pybind11/archive/v2.12.0.zip" - ] - } - } - }, - "recordedRepoMappingEntries": [ - [ - "pybind11_bazel+", - "bazel_tools", - "bazel_tools" - ] - ] - } - }, "@@rules_buf+//buf:extensions.bzl%ext": { "general": { "bzlTransitiveDigest": "gmPmM7QT5Jez2VVFcwbbMf/QWSRag+nJ1elFJFFTcn0=", diff --git a/WORKSPACE b/WORKSPACE index eca5e87a2..0b9d88bbc 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -145,15 +145,6 @@ http_archive( url = "https://github.com/Mbed-TLS/mbedtls/releases/download/v2.28.8/mbedtls-2.28.8.tar.bz2", ) -# TODO: https://pwbug.dev/354747966 - Update the BCR version of Emboss. -git_repository( - name = "com_google_emboss", - # LINT.IfChange(emboss) - remote = "https://pigweed.googlesource.com/third_party/github/google/emboss", - tag = "v2024.0809.170004", - # LINT.ThenChange(/pw_package/py/pw_package/packages/emboss.py:emboss) -) - git_repository( name = "mcuxpresso", commit = "6f3fd257cdcf978a4d26e7d6e9eed9240037422b", diff --git a/pw_bluetooth_sapphire/host/gap/bredr_connection_manager.cc b/pw_bluetooth_sapphire/host/gap/bredr_connection_manager.cc index 0bac26539..8885cd883 100644 --- a/pw_bluetooth_sapphire/host/gap/bredr_connection_manager.cc +++ b/pw_bluetooth_sapphire/host/gap/bredr_connection_manager.cc @@ -629,8 +629,8 @@ void BrEdrConnectionManager::AttachInspect(inspect::Node& parent, void BrEdrConnectionManager::WritePageTimeout( pw::chrono::SystemClock::duration page_timeout, hci::ResultFunction<> cb) { - BT_ASSERT(page_timeout >= hci_spec::kMinPageTimeoutDuration); - BT_ASSERT(page_timeout <= hci_spec::kMaxPageTimeoutDuration); + PW_CHECK(page_timeout >= hci_spec::kMinPageTimeoutDuration); + PW_CHECK(page_timeout <= hci_spec::kMaxPageTimeoutDuration); const int64_t raw_page_timeout = page_timeout / hci_spec::kPerPageTimeoutUnit; diff --git a/pw_bluetooth_sapphire_mcuxpresso/BUILD.bazel b/pw_bluetooth_sapphire_mcuxpresso/BUILD.bazel index 606f01c39..e59847036 100644 --- a/pw_bluetooth_sapphire_mcuxpresso/BUILD.bazel +++ b/pw_bluetooth_sapphire_mcuxpresso/BUILD.bazel @@ -16,6 +16,11 @@ cc_library( "public", ], deps = [ + "@pigweed//pw_containers:vector", + "@pigweed//pw_containers:inline_queue", + "@pigweed//pw_thread:thread", + "@pigweed//pw_sync:interrupt_spin_lock", + "@pigweed//pw_sync:thread_notification", "@pigweed//pw_bluetooth:pw_bluetooth", "@pigweed//pw_bluetooth_sapphire/host:stack", "//targets:mcuxpresso_sdk", diff --git a/pw_bluetooth_sapphire_mcuxpresso/controller.cc b/pw_bluetooth_sapphire_mcuxpresso/controller.cc index d83966d2b..db896e2e5 100644 --- a/pw_bluetooth_sapphire_mcuxpresso/controller.cc +++ b/pw_bluetooth_sapphire_mcuxpresso/controller.cc @@ -1,80 +1,251 @@ #include "pw_bluetooth_sapphire_mcuxpresso/controller.h" +#include #include +#include #include -#include "bluetooth/bluetooth.h" -#include "bluetooth/hci.h" +#include "controller/controller.h" #include "pw_bluetooth/controller.h" +#include "pw_bluetooth_sapphire/internal/host/common/byte_buffer.h" +#include "pw_bluetooth_sapphire/internal/host/common/packet_view.h" +#include "pw_bluetooth_sapphire/internal/host/hci-spec/protocol.h" +#include "pw_containers/inline_deque.h" +#include "pw_containers/vector.h" +#include "pw_log/log.h" +#include "pw_preprocessor/util.h" +#include "pw_thread/detached_thread.h" +PW_EXTERN_C_START +#include "controller_hci_uart.h" +PW_EXTERN_C_END +namespace pw::bluetooth { -template -struct CallbackCaster; +static pw::Vector EventPacketFromBytes(std::byte* data) { + bt::hci_spec::EventHeader* eventHeader = + reinterpret_cast(data); + // PW_CHECK_NULL(eventHeader); + return std::move( + pw::Vector(data, + data + sizeof(bt::hci_spec::EventHeader) + + eventHeader->parameter_total_size)); +} -template -struct CallbackCaster { - template - static Ret callback(Args... args) { - return func(args...); +static pw::Vector ACLPacketFromBytes(std::byte* data) { + bt::hci_spec::ACLDataHeader* eventHeader = + reinterpret_cast(data); + // PW_CHECK_NULL(eventHeader); + return std::move( + pw::Vector(data, + data + sizeof(bt::hci_spec::ACLDataHeader) + + eventHeader->data_total_length)); +} + +static void Mimxrt595Controller::hci_uart_transmit_cb(hal_uart_handle_t handle, + hal_uart_status_t status, + void* userData) { + // TODO: make sure if this function doesn't need synchronization with + // 'hci_uart_write_data' + if (handle == nullptr) { + return; + } + Mimxrt595Controller* controller_ptr = + static_cast(userData); + if (controller_ptr == nullptr) { + return; } - static std::function func; -}; -template -std::function CallbackCaster::func; + switch (status) { + case kStatus_HAL_UartTxIdle: + break; + case kStatus_HAL_UartRxIdle: + controller_ptr->hci_uart_rx_bytes_ptr += + controller_ptr->hci_uart_rx.dataSize; + ht_parse_packet(&controller_ptr->ht); -typedef void (*callback_t)(int); + if (controller_ptr->ht.packet_expected_len == 1) { + PacketType packet_type = (PacketType)controller_ptr->hci_uart_rx_buf[0]; + std::byte* packet_data = controller_ptr->hci_uart_rx_buf.data() + 1; + { + std::lock_guard lock(controller_ptr->hci_uart_tx_queue_mutex); + switch (packet_type) { + case kHciEventData: + controller_ptr->hci_uart_tx_queue.push(std::make_pair( + packet_type, EventPacketFromBytes(packet_data))); + break; + case kHciAclData: + controller_ptr->hci_uart_tx_queue.push( + std::make_pair(packet_type, ACLPacketFromBytes(packet_data))); + break; + default: + PW_LOG_CRITICAL("UNIMPLEMENTED: packet_type: %d", packet_type); + break; + } + } + + controller_ptr->hci_uart_rx_bytes_ptr = 0U; + controller_ptr->hci_uart_cond.release(); + } + + controller_ptr->hci_uart_rx.data = + &controller_ptr + ->hci_uart_rx_buf[controller_ptr->hci_uart_rx_bytes_ptr]; + controller_ptr->hci_uart_rx.dataSize = + controller_ptr->ht.packet_expected_len; + + HAL_UartReceiveNonBlocking( + (hal_uart_handle_t)controller_ptr->hci_uart_handle, + (uint8_t*)controller_ptr->hci_uart_rx.data, + controller_ptr->hci_uart_rx.dataSize); + break; + default: + break; + } +} + +void Mimxrt595Controller::hci_uart_write_data(std::byte* buf, uint16_t length) { + HAL_UartSendNonBlocking( + (hal_uart_handle_t)hci_uart_handle, (uint8_t*)buf, length); +} + +void Mimxrt595Controller::hci_uart_send_data(PacketType type, + uint8_t* buf, + uint16_t length) { + hci_uart_tx_buf[0] = (std::byte)type; + std::memcpy(&hci_uart_tx_buf[1], buf, length); + + hci_uart_write_data(hci_uart_tx_buf.data(), length + 1); +} + +pw::Status Mimxrt595Controller::hci_uart_init() { + hal_uart_config_t config; + hal_uart_status_t ret; + hal_uart_status_t status; + + controller_hci_uart_config_t getConfig; + + if (controller_hci_uart_get_configuration(&getConfig) != 0) { + return pw::Status::InvalidArgument(); + } + + config.srcClock_Hz = getConfig.clockSrc; + config.baudRate_Bps = getConfig.runningBaudrate; + config.parityMode = kHAL_UartParityDisabled; + config.stopBitCount = kHAL_UartOneStopBit; + config.enableRx = 1U; + config.enableTx = 1U; + config.instance = getConfig.instance; + config.enableRxRTS = getConfig.enableRxRTS; + config.enableTxCTS = getConfig.enableTxCTS; + + if (HAL_UartInit((hal_uart_handle_t)hci_uart_handle, &config) != + kStatus_HAL_UartSuccess) { + return pw::Status::InvalidArgument(); + } + + if (HAL_UartInstallCallback((hal_uart_handle_t)hci_uart_handle, + hci_uart_transmit_cb, + this) != kStatus_HAL_UartSuccess) { + return pw::Status::Unknown(); + } + + ht_parse_packet_init(&ht); + hci_uart_rx_bytes_ptr = 0U; + ht.packet = (uint8_t*)&hci_uart_rx_buf[0U]; + + hci_uart_rx.data = &hci_uart_rx_buf[hci_uart_rx_bytes_ptr]; + hci_uart_rx.dataSize = ht.packet_expected_len; + + if (HAL_UartReceiveNonBlocking((hal_uart_handle_t)hci_uart_handle, + (uint8_t*)hci_uart_rx.data, + hci_uart_rx.dataSize) != + kStatus_HAL_UartSuccess) { + return pw::Status::Unknown(); + } + + pw::thread::DetachedThread( + pw::thread::freertos::Options() + .set_name("EtherMind UART Task") + .set_priority(BT_TASK_PRIORITY + 2U), + [this]() { + while (true) { + hci_uart_cond.acquire(); + + while (!hci_uart_tx_queue.empty()) { + hci_uart_tx_queue_mutex.lock(); + auto [packet_type, packet_data] = hci_uart_tx_queue.front(); + hci_uart_tx_queue.pop(); + hci_uart_tx_queue_mutex.unlock(); + + switch (packet_type) { + case kHciEventData: + event_function_(pw::span(packet_data.data(), + packet_data.size())); + break; + case kHciAclData: + acl_function_(pw::span(packet_data.data(), + packet_data.size())); + break; + default: + PW_LOG_CRITICAL("UNKNOWN: packet_type: %d", packet_type); + break; + } + } + } + }); + + return pw::Status(); +} -namespace pw::bluetooth { void Mimxrt595Controller::SetEventFunction(DataFunction func) { - (void)func; + event_function_ = std::move(func); } void Mimxrt595Controller::SetReceiveAclFunction(DataFunction func) { - (void)func; + acl_function_ = std::move(func); } void Mimxrt595Controller::SetReceiveScoFunction(DataFunction func) { - (void)func; + (void)func; + PW_LOG_CRITICAL("UNIMPLEMENTED: SetReceiveScoFunction"); } // void Mimxrt595Controller::SetReceiveIsoFunction(DataFunction /*func*/) {} void Mimxrt595Controller::Initialize(Callback complete_callback, Callback error_callback) { - initialize_complete_callback_ = std::move(complete_callback); - initialize_error_callback_ = std::move(error_callback); + error_callback_ = std::move(error_callback); + pw::thread::DetachedThread( + pw::thread::freertos::Options().set_name( + "Mimxrt595Controller Initialize Thread"), + [complete_callback_ = std::move(complete_callback), this]() mutable { + controller_init(); - CallbackCaster::func = - std::bind(&Mimxrt595Controller::bt_ready_cb, this, std::placeholders::_1); - callback_t func = - static_cast(CallbackCaster::callback); + complete_callback_(hci_uart_init()); - bt_enable(func); + PW_LOG_INFO("Bluetooth initialized"); + }); } void Mimxrt595Controller::Close(Callback callback) { - // MIMXRT595 SDK currently doesn't implement a close function - // so we just call the callback with OK + // TODO: Previously used API didn't had a close function + // now, we are using bare HCI API, check again that it still doesn't allow + // to close callback(Status()); } void Mimxrt595Controller::SendCommand(span command) { - uint16_t opcode = (uint16_t)(command[0]) | (uint16_t)(command[1] << 8); - struct net_buf* buf = - bt_hci_cmd_create(opcode, sizeof(std::byte) * command.size() - 2); - std::byte* payload = - (std::byte*)net_buf_add(buf, sizeof(std::byte) * command.size() - 2); - std::copy(command.begin() + 2, command.end(), payload); - - bt_hci_cmd_send(opcode, buf); + auto command_buffer = bt::DynamicByteBuffer(bt::BufferView(command)); + hci_uart_send_data(kHciCommand, command_buffer.data(), command_buffer.size()); } void Mimxrt595Controller::SendAclData(span data) { - (void)data; + auto data_buffer = bt::DynamicByteBuffer(bt::BufferView(data)); + hci_uart_send_data(kHciAclData, data_buffer.data(), data_buffer.size()); } void Mimxrt595Controller::SendScoData(span data) { - (void)data; + PW_LOG_CRITICAL("UNIMPLEMENTED: SendScoData"); + (void)data; } // void Mimxrt595Controller::SendIsoData(span /*data*/) {} @@ -83,34 +254,31 @@ void Mimxrt595Controller::ConfigureSco(ScoCodingFormat coding_format, ScoEncoding encoding, ScoSampleRate sample_rate, Callback callback) { - (void)coding_format; - (void)encoding; - (void)sample_rate; - (void)callback; + PW_LOG_CRITICAL("UNIMPLEMENTED: ConfigureSco"); + (void)coding_format; + (void)encoding; + (void)sample_rate; + (void)callback; } void Mimxrt595Controller::ResetSco(Callback callback) { - (void)callback; + PW_LOG_CRITICAL("UNIMPLEMENTED: ResetSco"); + (void)callback; } void Mimxrt595Controller::GetFeatures(Callback callback) { - constexpr FeaturesBits features = - FeaturesBits::kHciSco | FeaturesBits::kHciIso; + constexpr FeaturesBits features = FeaturesBits::kHciSco | + FeaturesBits::kHciIso | + FeaturesBits::kSetAclPriorityCommand; callback(features); } void Mimxrt595Controller::EncodeVendorCommand( VendorCommandParameters parameters, Callback>)> callback) { - (void)parameters; - (void)callback; + PW_LOG_CRITICAL("UNIMPLEMENTED: EncodeVendorCommand"); + (void)parameters; + (void)callback; } -void Mimxrt595Controller::bt_ready_cb(int err) { - if (err == 0) { - initialize_complete_callback_(Status()); - } else { - initialize_error_callback_(Status::Unknown()); - } -} -}; // namespace pw::bluetooth +} // namespace pw::bluetooth diff --git a/pw_bluetooth_sapphire_mcuxpresso/public/pw_bluetooth_sapphire_mcuxpresso/controller.h b/pw_bluetooth_sapphire_mcuxpresso/public/pw_bluetooth_sapphire_mcuxpresso/controller.h index a62c4fa46..d1e636426 100644 --- a/pw_bluetooth_sapphire_mcuxpresso/public/pw_bluetooth_sapphire_mcuxpresso/controller.h +++ b/pw_bluetooth_sapphire_mcuxpresso/public/pw_bluetooth_sapphire_mcuxpresso/controller.h @@ -1,11 +1,21 @@ #pragma once #include "pw_bluetooth/controller.h" +#include "pw_bluetooth_sapphire/internal/host/hci-spec/protocol.h" +#include "pw_bluetooth_sapphire/internal/host/transport/acl_data_packet.h" +#include "pw_bluetooth_sapphire/internal/host/transport/control_packets.h" +#include "pw_containers/inline_queue.h" +#include "pw_sync/interrupt_spin_lock.h" +#include "pw_sync/thread_notification.h" + +PW_EXTERN_C_START +#include "fsl_adapter_uart.h" +#include "hci_transport.h" +PW_EXTERN_C_END namespace pw::bluetooth { class Mimxrt595Controller final : public pw::bluetooth::Controller { - // Sets a function that will be called with HCI event packets received from // the controller. This should be called before `Initialize` or else incoming // packets will be dropped. The lifetime of data passed to `func` is only @@ -36,7 +46,7 @@ class Mimxrt595Controller final : public pw::bluetooth::Controller { // initialization. After a fatal error, this object is invalid. `Close` should // be called to ensure a safe clean up. void Initialize(Callback complete_callback, - Callback error_callback) override; + Callback error_callback) override; // Closes the controller interface, resetting all state. `callback` will be // called when closure is complete. After this method is called, this object @@ -67,9 +77,9 @@ class Mimxrt595Controller final : public pw::bluetooth::Controller { // ALREADY_EXISTS - a SCO connection is already configured // INTERNAL - an internal error occurred void ConfigureSco(ScoCodingFormat coding_format, - ScoEncoding encoding, - ScoSampleRate sample_rate, - Callback callback) override; + ScoEncoding encoding, + ScoSampleRate sample_rate, + Callback callback) override; // Releases the resources held by an active SCO connection. This should be // called when a SCO connection is closed. `ConfigureSco` must be called @@ -90,12 +100,41 @@ class Mimxrt595Controller final : public pw::bluetooth::Controller { void EncodeVendorCommand( VendorCommandParameters parameters, Callback>)> callback) override; -private: - void bt_ready_cb(int err); - - Callback initialize_complete_callback_; - Callback initialize_error_callback_; + private: + enum PacketType : uint8_t { + kHciCommand = 0x01, + kHciAclData = 0x02, + kHciScoData = 0x03, + kHciEventData = 0x04, + kHciIsoData = 0x05, + }; + + typedef struct _hci_uart_meta_data_ { + std::byte* data; + size_t dataSize; + } hci_uart_meta_data; + + static void hci_uart_transmit_cb(hal_uart_handle_t handle, + hal_uart_status_t status, + void* userData); + void hci_uart_write_data(std::byte* buf, uint16_t length); + void hci_uart_send_data(PacketType type, unsigned char* buf, uint16_t length); + pw::Status hci_uart_init(); + Callback error_callback_; + DataFunction event_function_; + DataFunction acl_function_; + + hci_uart_meta_data hci_uart_rx; + pw::Vector hci_uart_rx_buf; + pw::Vector hci_uart_tx_buf; + uint16_t hci_uart_rx_bytes_ptr; + pw::sync::ThreadNotification hci_uart_cond; + HT_PARSE ht; + UART_HANDLE_DEFINE(hci_uart_handle); + pw::sync::InterruptSpinLock hci_uart_tx_queue_mutex; + pw::InlineQueue>, 16> + hci_uart_tx_queue; }; -} +} // namespace pw::bluetooth diff --git a/pw_build_mcuxpresso/py/pw_build_mcuxpresso/components.py b/pw_build_mcuxpresso/py/pw_build_mcuxpresso/components.py index a3b7b7421..65df249ba 100644 --- a/pw_build_mcuxpresso/py/pw_build_mcuxpresso/components.py +++ b/pw_build_mcuxpresso/py/pw_build_mcuxpresso/components.py @@ -333,7 +333,9 @@ def _parse_sources( # in this manifest, relative path to ethermind isn't from base path, but from manifest path. # In case of some components, project relative path points to not existing file, but in case of other # files, it is correct. - fixup_component_ids = ["middleware.edgefast_bluetooth.ble.ethermind.lib.cm33.MIMXRT595S", + fixup_component_ids = [ + "middleware.edgefast_bluetooth.ble.ethermind.lib.cm33.MIMXRT595S", + "middleware.edgefast_bluetooth.btble.ethermind.lib.cm33.MIMXRT595S", "middleware.edgefast_bluetooth.config.ethermind.MIMXRT595S"] if base_path is not None and base_path == pathlib.Path("../../wireless/ethermind"): if component_id in fixup_component_ids: diff --git a/targets/mimxrt595_evk_freertos/boot.cc b/targets/mimxrt595_evk_freertos/boot.cc index 7957d22d6..d56677f71 100644 --- a/targets/mimxrt595_evk_freertos/boot.cc +++ b/targets/mimxrt595_evk_freertos/boot.cc @@ -14,20 +14,20 @@ #include "pw_boot/boot.h" +#include "FreeRTOS.h" #include "board.h" #include "clock_config.h" +#include "controller_hci_uart.h" +#include "fsl_clock.h" +#include "fsl_debug_console.h" +#include "fsl_power.h" #include "peripherals.h" #include "pin_mux.h" #include "pw_boot_cortex_m/boot.h" #include "pw_preprocessor/compiler.h" #include "pw_sys_io_mcuxpresso/init.h" -#include "FreeRTOS.h" #include "pw_system/init.h" #include "task.h" -#include "fsl_clock.h" -#include "fsl_debug_console.h" -#include "controller_hci_uart.h" -#include "fsl_power.h" #include "usb_host_config.h" #include "usb_phy.h" #include "usb_host.h" @@ -36,7 +36,7 @@ #include "pw_malloc/malloc.h" #endif // PW_MALLOC_ACTIVE -#define CONTROLLER_ID kUSB_ControllerIp3516Hs0 +#define CONTROLLER_ID kUSB_ControllerIp3516Hs0 void pw_boot_PreStaticMemoryInit() { // Call CMSIS SystemInit code. @@ -63,109 +63,109 @@ void pw_boot_PreStaticConstructorInit() { #define USB_HOST_INTERRUPT_PRIORITY (3U) #endif /*work as debug console with M.2, work as bt usart with non-M.2*/ -#define APP_DEBUG_UART_TYPE kSerialPort_Uart -#define APP_DEBUG_UART_BASEADDR (uint32_t) USART12 +#define APP_DEBUG_UART_TYPE kSerialPort_Uart +#define APP_DEBUG_UART_BASEADDR (uint32_t)USART12 #define APP_DEBUG_UART_INSTANCE 12U #define APP_DEBUG_UART_CLK_FREQ CLOCK_GetFlexcommClkFreq(12) -#define APP_DEBUG_UART_FRG_CLK \ - (const clock_frg_clk_config_t){12U, clock_frg_clk_config_t::kCLOCK_FrgPllDiv, 255U, 0U} /*!< Select FRG0 mux as frg_pll */ +#define APP_DEBUG_UART_FRG_CLK \ + (const clock_frg_clk_config_t){ \ + 12U, clock_frg_clk_config_t::kCLOCK_FrgPllDiv, 255U, 0U} \ + /*!< Select FRG0 mux as frg_pll */ #define APP_DEBUG_UART_CLK_ATTACH kFRG_to_FLEXCOMM12 -#define APP_UART_IRQ_HANDLER FLEXCOMM12_IRQHandler -#define APP_UART_IRQ FLEXCOMM12_IRQn -#define APP_DEBUG_UART_BAUDRATE 115200 - -int controller_hci_uart_get_configuration(controller_hci_uart_config_t *config) -{ - if (NULL == config) - { - return -1; - } - config->clockSrc = BOARD_BT_UART_CLK_FREQ; - config->defaultBaudrate = 115200u; - config->runningBaudrate = BOARD_BT_UART_BAUDRATE; - config->instance = BOARD_BT_UART_INSTANCE; - config->enableRxRTS = 1u; - config->enableTxCTS = 1u; - return 0; +#define APP_UART_IRQ_HANDLER FLEXCOMM12_IRQHandler +#define APP_UART_IRQ FLEXCOMM12_IRQn +#define APP_DEBUG_UART_BAUDRATE 115200 + +int controller_hci_uart_get_configuration( + controller_hci_uart_config_t* config) { + if (config == nullptr) { + return -1; + } + config->clockSrc = BOARD_BT_UART_CLK_FREQ; + config->defaultBaudrate = 115200u; + config->runningBaudrate = BOARD_BT_UART_BAUDRATE; + config->instance = BOARD_BT_UART_INSTANCE; + config->enableRxRTS = 1u; + config->enableTxCTS = 1u; + return 0; } -void USB_HostClockInit(void) -{ - uint8_t usbClockDiv = 1; - uint32_t usbClockFreq; - usb_phy_config_struct_t phyConfig = { - BOARD_USB_PHY_D_CAL, - BOARD_USB_PHY_TXCAL45DP, - BOARD_USB_PHY_TXCAL45DM, - }; - - /* Make sure USDHC ram buffer and usb1 phy has power up */ - POWER_DisablePD(kPDRUNCFG_APD_USBHS_SRAM); - POWER_DisablePD(kPDRUNCFG_PPD_USBHS_SRAM); - POWER_ApplyPD(); - - RESET_PeripheralReset(kUSBHS_PHY_RST_SHIFT_RSTn); - RESET_PeripheralReset(kUSBHS_DEVICE_RST_SHIFT_RSTn); - RESET_PeripheralReset(kUSBHS_HOST_RST_SHIFT_RSTn); - RESET_PeripheralReset(kUSBHS_SRAM_RST_SHIFT_RSTn); - - /* enable usb ip clock */ - CLOCK_EnableUsbHs0HostClock(kOSC_CLK_to_USB_CLK, usbClockDiv); - /* save usb ip clock freq*/ - usbClockFreq = g_xtalFreq / usbClockDiv; - CLOCK_SetClkDiv(kCLOCK_DivPfc1Clk, 4); - /* enable usb ram clock */ - CLOCK_EnableClock(kCLOCK_UsbhsSram); - /* enable USB PHY PLL clock, the phy bus clock (480MHz) source is same with USB IP */ - CLOCK_EnableUsbHs0PhyPllClock(kOSC_CLK_to_USB_CLK, usbClockFreq); - - /* USB PHY initialization */ - USB_EhciPhyInit(CONTROLLER_ID, BOARD_XTAL_SYS_CLK_HZ, &phyConfig); +void USB_HostClockInit(void) { + uint8_t usbClockDiv = 1; + uint32_t usbClockFreq; + usb_phy_config_struct_t phyConfig = { + BOARD_USB_PHY_D_CAL, + BOARD_USB_PHY_TXCAL45DP, + BOARD_USB_PHY_TXCAL45DM, + }; + + /* Make sure USDHC ram buffer and usb1 phy has power up */ + POWER_DisablePD(kPDRUNCFG_APD_USBHS_SRAM); + POWER_DisablePD(kPDRUNCFG_PPD_USBHS_SRAM); + POWER_ApplyPD(); + + RESET_PeripheralReset(kUSBHS_PHY_RST_SHIFT_RSTn); + RESET_PeripheralReset(kUSBHS_DEVICE_RST_SHIFT_RSTn); + RESET_PeripheralReset(kUSBHS_HOST_RST_SHIFT_RSTn); + RESET_PeripheralReset(kUSBHS_SRAM_RST_SHIFT_RSTn); + + /* enable usb ip clock */ + CLOCK_EnableUsbHs0HostClock(kOSC_CLK_to_USB_CLK, usbClockDiv); + /* save usb ip clock freq*/ + usbClockFreq = g_xtalFreq / usbClockDiv; + CLOCK_SetClkDiv(kCLOCK_DivPfc1Clk, 4); + /* enable usb ram clock */ + CLOCK_EnableClock(kCLOCK_UsbhsSram); + /* enable USB PHY PLL clock, the phy bus clock (480MHz) source is same with + * USB IP */ + CLOCK_EnableUsbHs0PhyPllClock(kOSC_CLK_to_USB_CLK, usbClockFreq); + + /* USB PHY initialization */ + USB_EhciPhyInit(CONTROLLER_ID, BOARD_XTAL_SYS_CLK_HZ, &phyConfig); #if ((defined FSL_FEATURE_USBHSH_USB_RAM) && (FSL_FEATURE_USBHSH_USB_RAM > 0U)) - for (int i = 0; i < (FSL_FEATURE_USBHSH_USB_RAM >> 2); i++) - { - ((uint32_t *)FSL_FEATURE_USBHSH_USB_RAM_BASE_ADDRESS)[i] = 0U; - } + for (int i = 0; i < (FSL_FEATURE_USBHSH_USB_RAM >> 2); i++) { + ((uint32_t*)FSL_FEATURE_USBHSH_USB_RAM_BASE_ADDRESS)[i] = 0U; + } #endif - /* enable usb1 device clock */ - CLOCK_EnableClock(kCLOCK_UsbhsDevice); - USBHSH->PORTMODE &= ~USBHSH_PORTMODE_DEV_ENABLE_MASK; - /* Wait until dev_needclk de-asserts */ - while (SYSCTL0->USB0CLKSTAT & SYSCTL0_USB0CLKSTAT_DEV_NEED_CLKST_MASK) - { - __ASM("nop"); - } - /* disable usb1 device clock */ - CLOCK_DisableClock(kCLOCK_UsbhsDevice); + /* enable usb1 device clock */ + CLOCK_EnableClock(kCLOCK_UsbhsDevice); + USBHSH->PORTMODE &= ~USBHSH_PORTMODE_DEV_ENABLE_MASK; + /* Wait until dev_needclk de-asserts */ + while (SYSCTL0->USB0CLKSTAT & SYSCTL0_USB0CLKSTAT_DEV_NEED_CLKST_MASK) { + __ASM("nop"); + } + /* disable usb1 device clock */ + CLOCK_DisableClock(kCLOCK_UsbhsDevice); } -void USB_HostIsrEnable(void) -{ - uint8_t irqNumber; +void USB_HostIsrEnable(void) { + uint8_t irqNumber; - uint8_t usbHOSTEhciIrq[] = USBHSH_IRQS; - irqNumber = usbHOSTEhciIrq[CONTROLLER_ID - kUSB_ControllerIp3516Hs0]; - /* USB_HOST_CONFIG_EHCI */ + uint8_t usbHOSTEhciIrq[] = USBHSH_IRQS; + irqNumber = usbHOSTEhciIrq[CONTROLLER_ID - kUSB_ControllerIp3516Hs0]; + /* USB_HOST_CONFIG_EHCI */ - /* Install isr, set priority, and enable IRQ. */ - NVIC_SetPriority((IRQn_Type)irqNumber, USB_HOST_INTERRUPT_PRIORITY); + /* Install isr, set priority, and enable IRQ. */ + NVIC_SetPriority((IRQn_Type)irqNumber, USB_HOST_INTERRUPT_PRIORITY); - EnableIRQ((IRQn_Type)irqNumber); + EnableIRQ((IRQn_Type)irqNumber); } -void APP_InitAppDebugConsole(void) -{ - uint32_t uartClkSrcFreq; +void APP_InitAppDebugConsole(void) { + uint32_t uartClkSrcFreq; - /* attach FRG0 clock to FLEXCOMM12 (debug console) */ - auto debug_uart_cfg = APP_DEBUG_UART_FRG_CLK; - CLOCK_SetFRGClock(&debug_uart_cfg); - CLOCK_AttachClk(APP_DEBUG_UART_CLK_ATTACH); + /* attach FRG0 clock to FLEXCOMM12 (debug console) */ + auto debug_uart_cfg = APP_DEBUG_UART_FRG_CLK; + CLOCK_SetFRGClock(&debug_uart_cfg); + CLOCK_AttachClk(APP_DEBUG_UART_CLK_ATTACH); - uartClkSrcFreq = APP_DEBUG_UART_CLK_FREQ; + uartClkSrcFreq = APP_DEBUG_UART_CLK_FREQ; - DbgConsole_Init(APP_DEBUG_UART_INSTANCE, APP_DEBUG_UART_BAUDRATE, APP_DEBUG_UART_TYPE, uartClkSrcFreq); + DbgConsole_Init(APP_DEBUG_UART_INSTANCE, + APP_DEBUG_UART_BAUDRATE, + APP_DEBUG_UART_TYPE, + uartClkSrcFreq); } void pw_boot_PreMainInit() { @@ -177,6 +177,7 @@ void pw_boot_PreMainInit() { BOARD_InitBootPins(); BOARD_InitBootClocks(); + BOARD_InitI3CPins(); APP_InitAppDebugConsole(); /* attach FRG0 clock to FLEXCOMM0 */ diff --git a/third_party/mcuxpresso/BUILD.bazel b/third_party/mcuxpresso/BUILD.bazel index 3d3529098..55689703b 100644 --- a/third_party/mcuxpresso/BUILD.bazel +++ b/third_party/mcuxpresso/BUILD.bazel @@ -82,11 +82,12 @@ mcuxpresso_sdk( "platform.drivers.common.MIMXRT595S", "platform.drivers.cache_cache64.MIMXRT595S", "platform.drivers.flash_config.evkmimxrt595.MIMXRT595S", + "platform.drivers.i3c.MIMXRT595S", "utility.debug_console.MIMXRT595S", "device.MIMXRT595S_CMSIS.MIMXRT595S", "middleware.wifi.fwdnld_intf_abs.MIMXRT595S", "middleware.edgefast_bluetooth.wifi_nxp.controller.base.MIMXRT595S", - "middleware.edgefast_bluetooth.ble.ethermind.cm33.MIMXRT595S", + "middleware.edgefast_bluetooth.btble.ethermind.cm33.MIMXRT595S", "middleware.usb.device_controller_ip3511hs.MIMXRT595S", "middleware.usb.phy.MIMXRT595S", "middleware.usb.device.controller.driver.MIMXRT595S", @@ -126,6 +127,14 @@ mcuxpresso_sdk( "-Wno-sign-compare", "-Wno-shadow", "-Wno-unused-function", + "-Wno-type-limits", + "-Wno-array-bounds", + "-Wno-stringop-truncation", + "-Wno-format-overflow", + "-Wno-stringop-overflow", + "-Wno-implicit-fallthrough", + "-Wno-nonnull", + "-Wno-cast-qual", "-include", "$(execpath @pigweed//third_party/mcuxpresso:config/app_bluetooth_config.h)" ], deps = [ diff --git a/third_party/mcuxpresso/config/app_bluetooth_config.h b/third_party/mcuxpresso/config/app_bluetooth_config.h index 7e248af53..3da4d712f 100644 --- a/third_party/mcuxpresso/config/app_bluetooth_config.h +++ b/third_party/mcuxpresso/config/app_bluetooth_config.h @@ -49,25 +49,19 @@ #define SD_TIMING_MAX kSD_TimingDDR50Mode #endif /*#define WIFI_IW612_BOARD_MURATA_2EL_M2*/ -/* Select witch beacon application to start */ -#define BEACON_APP 1 -#define IBEACON_APP 0 -#define EDDYSTONE 0 - #define CONFIG_BT_PERIPHERAL 1 -#define CONFIG_BT_PHY_UPDATE 1 -#define CONFIG_BT_AUTO_PHY_UPDATE 1 -#define CONFIG_BT_DATA_LEN_UPDATE 1 -#define CONFIG_BT_AUTO_DATA_LEN_UPDATE 1 -#if (defined EDDYSTONE) && (EDDYSTONE) -#define CONFIG_BT_SETTINGS 1 -#define CONFIG_BT_KEYS_OVERWRITE_OLDEST 1 -#endif -#if defined(IBEACON_APP) && (IBEACON_APP == 1) -#define CONFIG_BT_DEVICE_NAME "ibeacon" -#elif defined(EDDYSTONE) && (EDDYSTONE == 1) -#define CONFIG_BT_DEVICE_NAME "eddystone" -#elif defined(BEACON_APP) && (BEACON_APP == 1) -#define CONFIG_BT_DEVICE_NAME "beacon" +#define CONFIG_BT_CENTRAL 1 +#define CONFIG_BT_BREDR 1 +#define CONFIG_BT_SMP 1 +#define CONFIG_BT_A2DP 1 +#define CONFIG_BT_A2DP_SINK 1 +#define CONFIG_BT_SETTINGS 0 + + +#if (defined(CONFIG_BT_SMP) && (CONFIG_BT_SMP > 0U)) + #define CONFIG_BT_RX_STACK_SIZE 2500 +#else + #define CONFIG_BT_RX_STACK_SIZE 1024 #endif + #include "edgefast_bluetooth_config.h" diff --git a/third_party/mcuxpresso/mcuxpresso_sdk.bzl b/third_party/mcuxpresso/mcuxpresso_sdk.bzl index 4770d6405..10168c904 100644 --- a/third_party/mcuxpresso/mcuxpresso_sdk.bzl +++ b/third_party/mcuxpresso/mcuxpresso_sdk.bzl @@ -213,11 +213,11 @@ mcuxpresso_sdk = rule( ), "_libraries": attr.string_list( default = [ - "libethermind_ble_core.a", - "libethermind_ble_gatt.a", - "libethermind_ble_protocol.a", - "libethermind_ble_util.a", - "libethermind_ble_ga.a", + "libethermind_bt_core.a", + "libethermind_bt_gatt.a", + "libethermind_bt_protocol.a", + "libethermind_bt_util.a", + "libethermind_bt_ga.a", ], ), "_mcuxpresso_sdk_builder": attr.label(