xref: /aosp_15_r20/external/pigweed/pw_uart/public/pw_uart/uart_non_blocking.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 <cstdint>
18 
19 #include "pw_bytes/span.h"
20 #include "pw_function/function.h"
21 #include "pw_status/status.h"
22 #include "pw_status/status_with_size.h"
23 #include "pw_uart/uart_base.h"
24 
25 namespace pw::uart {
26 
27 /// Represents an abstract UART interface.
28 ///
29 /// The `UartNonBlocking` interface provides a basic set of methods for
30 /// performing Non-Blocking UART communication.
31 
32 class UartNonBlocking : public UartBase {
33  public:
34   ~UartNonBlocking() override = default;
35 
36   /// Reads exactly `rx_buffer.size()` bytes from the UART into the provided
37   /// buffer.
38   ///
39   /// This function calls `callback` after the entirety of `rx_buffer` is filled
40   /// with data. This may be called from interrupt context.
41   /// The callback may be called in ISR context.
42   /// It is safe to call `Read`/`Write` from the callback context.
43   ///
44   /// @param rx_buffer  The buffer to read data into.
45   /// @param callback   A callback to invoke when the transaction is completed.
46   ///                   @param status  OK: The operation was successful and the
47   ///                                  entire buffer has been filled with data.
48   ///                                  CANCELLED: The operation was cancelled
49   ///                                  via CancelRead().
50   ///                                  May return other implementation-specific
51   ///                                  status codes.
52   ///                   @param buffer  buffer.size() returns the number of
53   ///                                  bytes successfully read into the buffer.
54   ///                                  If `status`=OK, the buffer is identical
55   ///                                  to rx_buffer
56   ///
57   /// @returns @rst
58   ///
59   /// .. pw-status-codes::
60   ///
61   ///    OK: The operation was successfully started.
62   ///    UNAVAILABLE: Another Read() transaction is currently in progress.
63   ///
64   /// May return other implementation-specific status codes.
65   ///
66   /// @endrst
ReadExactly(ByteSpan rx_buffer,Function<void (Status status,ConstByteSpan buffer)> && callback)67   Status ReadExactly(
68       ByteSpan rx_buffer,
69       Function<void(Status status, ConstByteSpan buffer)>&& callback) {
70     return DoRead(rx_buffer, rx_buffer.size(), std::move(callback));
71   }
72 
73   /// Reads at least `min_bytes` and at most `rx_buffer.size()` bytes from the
74   /// UART into the provided buffer.
75   ///
76   /// This function calls `callback` after `rx_buffer` is filled with at least
77   /// `min_bytes` of data. This may be called from interrupt context.
78   /// The callback may be called in ISR context.
79   /// It is safe to call `Read`/`Write` from the callback context.
80   ///
81   /// @param rx_buffer  The buffer to read data into.
82   /// @param min_bytes  Minimum bytes to read.
83   /// @param callback   A callback to invoke when the transaction is completed.
84   ///                   @param status  OK: The operation was successful and the
85   ///                                  buffer has been filled with at least
86   ///                                  `min_bytes` with data.
87   ///                                  CANCELLED: The operation was cancelled
88   ///                                  via CancelRead().
89   ///                                  May return other implementation-specific
90   ///                                  status codes.
91   ///                   @param buffer  buffer.size() returns the number of
92   ///                                  bytes successfully read into the buffer.
93   ///
94   /// @returns @rst
95   ///
96   /// .. pw-status-codes::
97   ///
98   ///    OK: The operation was successfully started.
99   ///    UNAVAILABLE: Another Read() transaction is currently in progress.
100   ///
101   /// May return other implementation-specific status codes.
102   ///
103   /// @endrst
ReadAtLeast(ByteSpan rx_buffer,size_t min_bytes,Function<void (Status status,ConstByteSpan buffer)> && callback)104   Status ReadAtLeast(
105       ByteSpan rx_buffer,
106       size_t min_bytes,
107       Function<void(Status status, ConstByteSpan buffer)>&& callback) {
108     return DoRead(rx_buffer, min_bytes, std::move(callback));
109   }
110 
111   /// Cancel a current read in progress.
112   ///
113   /// This function will cancel a read in progress. The read's callback will
114   /// be invoked with status=CANCELLED.
115   ///
116   /// @returns @rst
117   ///
118   ///    true: The operation was successfully canceled a transaction in progress
119   ///          and the callback will be invoked with status=CANCELLED.
120   ///    false: There were no transactions in progress and nothing was
121   ///           cancelled. No callback will be invoked.
122   ///
123   /// @endrst
CancelRead()124   bool CancelRead() { return DoCancelRead(); }
125 
126   /// Writes data from a provided buffer to the UART.
127   ///
128   /// This function calls `callback` after the entirety of `tx_buffer` is
129   /// written to the UART. This may be called from interrupt context.
130   /// The callback may be called in ISR context.
131   /// It is safe to call `Read`/`Write` from the callback context.
132   ///
133   /// @param tx_buffer  The buffer to write to the UART.
134   /// @param callback   A callback to invoke when the transaction is completed.
135   ///                   @param status  status.size() returns the number of bytes
136   ///                                  successfully written from `tx_buffer`.
137   ///                                  OK: The operation was successful and the
138   ///                                  entire buffer has been written.
139   ///                                  CANCELLED: The operation was cancelled
140   ///                                  via CancelWrite().
141   ///                                  May return other implementation-specific
142   ///                                  status codes.
143   ///
144   /// @returns @rst
145   ///
146   /// .. pw-status-codes::
147   ///
148   ///    OK: The operation was successfully started.
149   ///    UNAVAILABLE: Another Write() transaction is currently in progress.
150   ///
151   /// May return other implementation-specific status codes.
152   ///
153   /// @endrst
Write(ConstByteSpan tx_buffer,Function<void (StatusWithSize status)> && callback)154   Status Write(ConstByteSpan tx_buffer,
155                Function<void(StatusWithSize status)>&& callback) {
156     return DoWrite(tx_buffer, std::move(callback));
157   }
158 
159   /// Cancel a current write in progress.
160   ///
161   /// This function will cancel a write in progress. The write's callback will
162   /// be called with status=CANCELLED.
163   ///
164   /// @returns @rst
165   ///
166   ///    true: The operation was successfully canceled a transaction in progress
167   ///          and the callback will be invoked with status=CANCELLED.
168   ///    false: There were no transactions in progress and nothing was
169   ///           cancelled. No callback will be invoked.
170   ///
171   /// @endrst
CancelWrite()172   bool CancelWrite() { return DoCancelWrite(); }
173 
174   /// Ensures all queued data in the UART has been transmitted and the hardware
175   /// FIFO is empty.
176   ///
177   /// This function ensures that all data enqueued before calling this function
178   /// has been transmitted. Any data enqueued after this function completes will
179   /// be transmitted immediately.
180   ///
181   /// @param callback   A callback to invoke when the flush is completed.
182   ///                   @param status  OK: The operation was successful and the
183   ///                                  transmit FIFO is empty.
184   ///                                  CANCELLED: The operation was cancelled
185   ///                                  via CancelFlushOutput().
186   ///                                  May return other implementation-specific
187   ///                                  status codes.
188   ///
189   /// @returns @rst
190   ///
191   /// .. pw-status-codes::
192   ///
193   ///    OK: The operation was successfully started.
194   ///    UNAVAILABLE: Another Write() or FlushOutput() operation is currently
195   ///    in progress.
196   ///
197   /// May return other implementation-specific status codes.
198   ///
199   /// @endrst
FlushOutput(Function<void (Status status)> && callback)200   Status FlushOutput(Function<void(Status status)>&& callback) {
201     return DoFlushOutput(std::move(callback));
202   }
203 
204   /// Cancels a pending FlushOutput() operation.
205   ///
206   /// This function will cancel an output flush in progress. The FlushOutput
207   /// callback will be called with status=CANCELLED.
208   ///
209   /// @returns @rst
210   ///
211   ///    true: The operation was successfully canceled a transaction in progress
212   ///          and the callback will be invoked with status=CANCELLED.
213   ///    false: There were no transactions in progress and nothing was
214   ///           cancelled. No callback will be invoked.
215   ///
216   /// @endrst
CancelFlushOutput()217   bool CancelFlushOutput() { return DoCancelFlushOutput(); }
218 
219  private:
220   /// Reads at least `min_bytes` and at most `rx_buffer.size()` bytes from the
221   /// UART into the provided buffer.
222   ///
223   /// This virtual function attempts to read data into the provided byte buffer
224   /// (`rx_buffer`).
225   /// This virtual function will return immediately. `callback` will be invoked
226   /// when the buffer has been filled with at least `min_bytes`, or an error
227   /// occurs.
228   /// Implementation Notes:
229   /// * The callback may be called in ISR context.
230   /// * It is safe to call `DoRead`/`DoWrite` from the callback context.
231   /// * To prevent infinite recurssion the callback should never be called
232   ///   synchronously from `DoRead`.
233   /// * The callback must be moved and stored prior to its invocation.
234   /// * Do not hold a lock when invoking the callback.
235   ///
236   /// @param rx_buffer  The buffer to read data into.
237   /// @param min_bytes  Minimum bytes to read.
238   /// @param callback   A callback to invoke when the transaction is completed.
239   ///                   @param status  OK: The operation was successful and the
240   ///                                  buffer has been filled with at least
241   ///                                  `min_bytes` with data.
242   ///                                  CANCELLED: The operation was cancelled
243   ///                                  via CancelRead().
244   ///                                  May return other implementation-specific
245   ///                                  status codes.
246   ///                   @param buffer  buffer.size() returns the number of
247   ///                                  bytes successfully read into the buffer.
248   /// @returns @rst
249   ///
250   /// .. pw-status-codes::
251   ///
252   ///    OK: The operation was successful started.
253   ///    UNAVAILABLE: Another Read() transaction is currently in progress.
254   ///
255   /// May return other implementation-specific status codes.
256   ///
257   /// @endrst
258   virtual Status DoRead(
259       ByteSpan rx_buffer,
260       size_t min_bytes,
261       Function<void(Status status, ConstByteSpan buffer)>&& callback) = 0;
262 
263   /// Cancels a current read in progress.
264   ///
265   /// This virtual function will cancel a read in progress. The read's callback
266   /// will be called with status=CANCELLED.
267   ///
268   /// @returns @rst
269   ///
270   ///    true: The operation was successfully canceled a transaction in progress
271   ///          and the callback will be invoked with status=CANCELLED.
272   ///    false: There were no transactions in progress and nothing was
273   ///           cancelled. No callback will be invoked.
274   ///
275   /// May return other implementation-specific status codes.
276   ///
277   /// @endrst
278   virtual bool DoCancelRead() = 0;
279 
280   /// Writes data from a provided buffer to the UART.
281   ///
282   /// This virtual function attempts to write data from the provided byte
283   /// buffer (`tx_buffer`).
284   /// This virtual function will return immediately. `callback` will be invoked
285   /// when either the buffer fully written, or an error occurs.
286   /// Implementation Notes:
287   /// * The callback may be called in ISR context.
288   /// * It is safe to call `DoRead`/`DoWrite` from the callback context.
289   /// * To prevent infinite recurssion the callback should never be called
290   ///   synchronously from `DoRead`.
291   /// * The callback must be moved and stored prior to its invocation.
292   /// * Do not hold a lock when invoking the callback.
293   ///
294   /// @param tx_buffer  The buffer to write to the UART.
295   /// @param callback   A callback to invoke when the transaction is completed.
296   ///                   @param status  status.size() returns the number of bytes
297   ///                                  successfully written from `tx_buffer`.
298   ///                   @param status  OK: The operation was successful and the
299   ///                                  entire buffer has been written.
300   ///                                  CANCELLED: The operation was cancelled
301   ///                                  via CancelWrite().
302   ///                                  May return other implementation-specific
303   ///                                  status codes.
304   /// @returns @rst
305   ///
306   /// .. pw-status-codes::
307   ///
308   ///    OK: The operation was successful started.
309   ///    UNAVAILABLE: Another Write() transaction is currently in progress.
310   ///
311   /// May return other implementation-specific status codes.
312   ///
313   /// @endrst
314   virtual Status DoWrite(ConstByteSpan tx_buffer,
315                          Function<void(StatusWithSize status)>&& callback) = 0;
316 
317   /// Cancel a current write in progress.
318   ///
319   /// This virtual function will cancel a write in progress. The write's
320   /// callback will be invoked with status=CANCELLED.
321   ///
322   /// @returns @rst
323   ///
324   ///    true: The operation was successfully canceled a transaction in progress
325   ///          and the callback will be invoked with status=CANCELLED.
326   ///    false: There were no transactions in progress and nothing was
327   ///           cancelled. No callback will be invoked.
328   ///
329   /// May return other implementation-specific status codes.
330   ///
331   /// @endrst
332   virtual bool DoCancelWrite() = 0;
333 
334   /// Ensures all queued data in the UART has been transmitted and the hardware
335   /// FIFO is empty.
336   ///
337   /// This function ensures that all data enqueued before calling this function
338   /// has been transmitted. Any data enqueued after this function completes will
339   /// be transmitted immediately.
340   ///
341   /// @param callback   A callback to invoke when the flush is completed.
342   ///                   @param status  OK: The operation was successful and the
343   ///                                  transmit FIFO is empty.
344   ///                                  CANCELLED: The operation was cancelled
345   ///                                  via CancelFlushOutput().
346   ///                                  May return other implementation-specific
347   ///                                  status codes.
348   ///
349   /// @returns @rst
350   ///
351   /// .. pw-status-codes::
352   ///
353   ///    OK: The operation was successfully started.
354   ///    UNAVAILABLE: Another Write() or FlushOutput() operation is currently
355   ///    in progress.
356   ///
357   /// May return other implementation-specific status codes.
358   ///
359   /// @endrst
DoFlushOutput(Function<void (Status status)> &&)360   virtual Status DoFlushOutput(Function<void(Status status)>&& /*callback*/) {
361     return Status::Unimplemented();
362   }
363 
364   /// Cancels a pending FlushOutput() operation.
365   ///
366   /// This function will cancel an output flush in progress. The DoFlushOutput
367   /// callback will be called with status=CANCELLED.
368   ///
369   /// @returns @rst
370   ///
371   ///    true: The operation was successfully canceled a transaction in progress
372   ///          and the callback will be invoked with status=CANCELLED.
373   ///    false: There were no transactions in progress and nothing was
374   ///           cancelled. No callback will be invoked.
375   ///
376   /// @endrst
DoCancelFlushOutput()377   virtual bool DoCancelFlushOutput() { return false; }
378 };
379 
380 }  // namespace pw::uart
381