1 // Copyright 2024 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 15 #pragma once 16 17 #include "pw_sync/timed_thread_notification.h" 18 #include "pw_uart/uart.h" 19 #include "pw_uart/uart_non_blocking.h" 20 21 namespace pw::uart { 22 23 /// UartBlockingAdapter provides the blocking Uart interface on top of a 24 /// UartNonBlocking device. 25 class UartBlockingAdapter final : public Uart { 26 public: 27 /// Constructs a UartBlockingAdapter for a UartNonBlocking device. UartBlockingAdapter(UartNonBlocking & uart)28 UartBlockingAdapter(UartNonBlocking& uart) 29 : uart_(uart), rx_("rx"), tx_("tx") {} 30 ~UartBlockingAdapter() override; 31 32 private: 33 UartNonBlocking& uart_; 34 35 class Transfer { 36 public: Transfer(const char * what)37 Transfer(const char* what) : what_(what) {} 38 Start()39 void Start() { pending_ = true; } 40 void Complete(StatusWithSize result); Complete(Status status)41 void Complete(Status status) { Complete(StatusWithSize(status, 0)); } 42 [[nodiscard]] bool WaitForCompletion( 43 std::optional<chrono::SystemClock::duration> timeout); 44 void WaitForCompletion(); 45 StatusWithSize HandleTimeout(bool cancel_result); 46 pending()47 bool pending() const { return pending_; } result()48 StatusWithSize result() const { return result_; } 49 50 private: 51 const char* what_ = nullptr; 52 sync::TimedThreadNotification complete_; 53 StatusWithSize result_; 54 bool pending_ = false; 55 }; 56 57 Transfer rx_; 58 Transfer tx_; 59 60 // UartBase impl. DoEnable(bool enable)61 Status DoEnable(bool enable) override { 62 return enable ? uart_.Enable() : uart_.Disable(); 63 } 64 DoSetBaudRate(uint32_t baud_rate)65 Status DoSetBaudRate(uint32_t baud_rate) override { 66 return uart_.SetBaudRate(baud_rate); 67 } 68 DoSetFlowControl(bool enabled)69 Status DoSetFlowControl(bool enabled) override { 70 return uart_.SetFlowControl(enabled); 71 } 72 DoConservativeReadAvailable()73 size_t DoConservativeReadAvailable() override { 74 return uart_.ConservativeReadAvailable(); 75 } 76 DoClearPendingReceiveBytes()77 Status DoClearPendingReceiveBytes() override { 78 return uart_.ClearPendingReceiveBytes(); 79 } 80 81 // Uart impl. 82 StatusWithSize DoTryReadFor( 83 ByteSpan rx_buffer, 84 size_t min_bytes, 85 std::optional<chrono::SystemClock::duration> timeout) override; 86 87 StatusWithSize DoTryWriteFor( 88 ConstByteSpan tx_buffer, 89 std::optional<chrono::SystemClock::duration> timeout) override; 90 91 Status DoFlushOutput() override; 92 }; 93 94 } // namespace pw::uart 95