• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 not safe to call any Uart methods 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 not safe to call any Uart methods 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 not safe to call any Uart methods 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   /// * The callback must be moved and stored prior to its invocation.
231   /// * Do not hold a lock when invoking the callback.
232   ///
233   /// @param rx_buffer  The buffer to read data into.
234   /// @param min_bytes  Minimum bytes to read.
235   /// @param callback   A callback to invoke when the transaction is completed.
236   ///                   @param status  OK: The operation was successful and the
237   ///                                  buffer has been filled with at least
238   ///                                  `min_bytes` with data.
239   ///                                  CANCELLED: The operation was cancelled
240   ///                                  via CancelRead().
241   ///                                  May return other implementation-specific
242   ///                                  status codes.
243   ///                   @param buffer  buffer.size() returns the number of
244   ///                                  bytes successfully read into the buffer.
245   /// @returns @rst
246   ///
247   /// .. pw-status-codes::
248   ///
249   ///    OK: The operation was successful started.
250   ///    UNAVAILABLE: Another Read() transaction is currently in progress.
251   ///
252   /// May return other implementation-specific status codes.
253   ///
254   /// @endrst
255   virtual Status DoRead(
256       ByteSpan rx_buffer,
257       size_t min_bytes,
258       Function<void(Status status, ConstByteSpan buffer)>&& callback) = 0;
259 
260   /// Cancels a current read in progress.
261   ///
262   /// This virtual function will cancel a read in progress. The read's callback
263   /// will be called with status=CANCELLED.
264   ///
265   /// @returns @rst
266   ///
267   ///    true: The operation was successfully canceled a transaction in progress
268   ///          and the callback will be invoked with status=CANCELLED.
269   ///    false: There were no transactions in progress and nothing was
270   ///           cancelled. No callback will be invoked.
271   ///
272   /// May return other implementation-specific status codes.
273   ///
274   /// @endrst
275   virtual bool DoCancelRead() = 0;
276 
277   /// Writes data from a provided buffer to the UART.
278   ///
279   /// This virtual function attempts to write data from the provided byte
280   /// buffer (`tx_buffer`).
281   /// This virtual function will return immediately. `callback` will be invoked
282   /// when either the buffer fully written, or an error occurs.
283   /// Implementation Notes:
284   /// * The callback may be called in ISR context.
285   /// * The callback must be moved and stored prior to its invocation.
286   /// * Do not hold a lock when invoking the callback.
287   ///
288   /// @param tx_buffer  The buffer to write to the UART.
289   /// @param callback   A callback to invoke when the transaction is completed.
290   ///                   @param status  status.size() returns the number of bytes
291   ///                                  successfully written from `tx_buffer`.
292   ///                   @param status  OK: The operation was successful and the
293   ///                                  entire buffer has been written.
294   ///                                  CANCELLED: The operation was cancelled
295   ///                                  via CancelWrite().
296   ///                                  May return other implementation-specific
297   ///                                  status codes.
298   /// @returns @rst
299   ///
300   /// .. pw-status-codes::
301   ///
302   ///    OK: The operation was successful started.
303   ///    UNAVAILABLE: Another Write() transaction is currently in progress.
304   ///
305   /// May return other implementation-specific status codes.
306   ///
307   /// @endrst
308   virtual Status DoWrite(ConstByteSpan tx_buffer,
309                          Function<void(StatusWithSize status)>&& callback) = 0;
310 
311   /// Cancel a current write in progress.
312   ///
313   /// This virtual function will cancel a write in progress. The write's
314   /// callback will be invoked with status=CANCELLED.
315   ///
316   /// @returns @rst
317   ///
318   ///    true: The operation was successfully canceled a transaction in progress
319   ///          and the callback will be invoked with status=CANCELLED.
320   ///    false: There were no transactions in progress and nothing was
321   ///           cancelled. No callback will be invoked.
322   ///
323   /// May return other implementation-specific status codes.
324   ///
325   /// @endrst
326   virtual bool DoCancelWrite() = 0;
327 
328   /// Ensures all queued data in the UART has been transmitted and the hardware
329   /// FIFO is empty.
330   ///
331   /// This function ensures that all data enqueued before calling this function
332   /// has been transmitted. Any data enqueued after this function completes will
333   /// be transmitted immediately.
334   ///
335   /// @param callback   A callback to invoke when the flush is completed.
336   ///                   @param status  OK: The operation was successful and the
337   ///                                  transmit FIFO is empty.
338   ///                                  CANCELLED: The operation was cancelled
339   ///                                  via CancelFlushOutput().
340   ///                                  May return other implementation-specific
341   ///                                  status codes.
342   ///
343   /// @returns @rst
344   ///
345   /// .. pw-status-codes::
346   ///
347   ///    OK: The operation was successfully started.
348   ///    UNAVAILABLE: Another Write() or FlushOutput() operation is currently
349   ///    in progress.
350   ///
351   /// May return other implementation-specific status codes.
352   ///
353   /// @endrst
DoFlushOutput(Function<void (Status status)> &&)354   virtual Status DoFlushOutput(Function<void(Status status)>&& /*callback*/) {
355     return Status::Unimplemented();
356   }
357 
358   /// Cancels a pending FlushOutput() operation.
359   ///
360   /// This function will cancel an output flush in progress. The DoFlushOutput
361   /// callback will be called with status=CANCELLED.
362   ///
363   /// @returns @rst
364   ///
365   ///    true: The operation was successfully canceled a transaction in progress
366   ///          and the callback will be invoked with status=CANCELLED.
367   ///    false: There were no transactions in progress and nothing was
368   ///           cancelled. No callback will be invoked.
369   ///
370   /// @endrst
DoCancelFlushOutput()371   virtual bool DoCancelFlushOutput() { return false; }
372 };
373 
374 }  // namespace pw::uart
375