xref: /aosp_15_r20/external/pigweed/pw_uart/public/pw_uart/blocking_adapter.h (revision 61c4878ac05f98d0ceed94b57d316916de578985)
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