pw_uart#

Core interfaces for UART communication

Unstable C++

Pigweed’s pw_uart module provides a set of interfaces for communicating via UART.

Overview#

pw_uart defines core methods for UART communication. This serves as a blueprint for concrete UART implementations. You will need to write the backend code tailored to your specific hardware device to interact with the UART peripheral.

The interface consists of these main classes:

  • UartBase - Base class which provides basic enable/disable and configuration control, but no communication.

  • Uart - Extends pw::uart::UartBase to provide blocking Read and Write APIs.

  • UartNonBlocking - Extends pw::uart::UartBase to provide non-blocking (callback-based) Read and Write APIs.

  • UartBlockingAdapter - Provides the blocking Uart interface on top of a UartNonBlocking device.

  • UartStream - Provides the pw::stream::NonSeekableReaderWriter (pw_stream) interface on top of a Uart device.

classDiagram namespace uart { class UartBase class Uart class UartNonBlocking class UartBlockingAdapter class UartStream } namespace stream { class NonSeekableReaderWriter } UartBase <|-- Uart : extends UartBase <|-- UartNonBlocking : extends Uart <|-- UartBlockingAdapter : implements UartNonBlocking --> UartBlockingAdapter NonSeekableReaderWriter <|-- UartStream : implements Uart --> UartStream

Get started#

Add @pigweed//pw_uart to the deps list in your Bazel target:

cc_library("...") {
  # ...
  deps = [
    # ...
    "@pigweed//pw_uart",
    # ...
  ]
}

This assumes that your Bazel WORKSPACE has a repository named @pigweed that points to the upstream Pigweed repository.

Add $dir_pw_uart to the deps list in your pw_executable() build target:

pw_executable("...") {
  # ...
  deps = [
    # ...
    "$dir_pw_uart",
    # ...
  ]
}

Add pw_uart to your pw_add_library or similar CMake target:

pw_add_library(my_library STATIC
  HEADERS
    ...
  PRIVATE_DEPS
    # ...
    pw_uart
    # ...
)

API reference#

Warning

Drivers should not implement both Uart and UartNonBlocking interfaces.

Drivers which support non-blocking (callback) behavior should implement UartNonBlocking. Applications that require the blocking Uart interface can use the UartBlockingAdapter.

UartBase#

class UartBase#

The common abstract base class of the UART interface.

The UartBase interface provides basic method for enabling and configuring a UART. Methods for actually communicating via the UART are on the Uart and UartNonBlocking child classes.

Subclassed by pw::uart::Uart, pw::uart::UartNonBlocking

Public Functions

inline Status Enable()#

Initializes the UART module, sets it into the default state as determined by the concrete UART implementation. This function should be a no-op if the UART module is in an enabled state.

This may change the power state of the UART module, configure the interface parameters, enable the associated pins, setup the internal TX and RX buffers, etc…

Returns:

Code

Description

OK

The UART module has been successfully initialized.

INTERNAL

Internal errors within the hardware abstraction layer.

inline Status Disable()#

Disables the UART module. Disabling the UART shuts down communication and prevents the microcontroller from sending or receiving data through the UART port.

This is usually done to save power. Interrupt handlers should also be disabled.

Returns:

Code

Description

OK

The UART module has been successfully initialized.

INTERNAL

Internal errors within the hardware abstraction layer.

inline Status SetBaudRate(uint32_t baud_rate)#

Configures the UART communication baud rate.

This function sets the communication speed (baud rate) for the UART. Whether the baud rate can be changed while the UART is enabled depends on the specific implementation.

Returns:

Code

Description

OK

The UART has been successfully initialized.

FAILED_PRECONDITION

The device is enabled and does not support changing settings on the fly.

INTERNAL

Internal errors within the hardware abstraction layer.

inline Status SetFlowControl(bool enable)#

Configures the UART hardware flow control enable.

This function sets the hardware flow control enable for the UART. Whether the flow control setting rate can be changed while the UART is enabled depends on the specific implementation.

Returns:

Code

Description

OK

The UART has been successfully initialized.

FAILED_PRECONDITION

The device is enabled and does not support changing settings on the fly.

UNIMPLEMENTED

The device does not support flow control.

INTERNAL

Internal errors within the hardware abstraction layer.

inline size_t ConservativeReadAvailable()#

Returns the number of bytes currently available for reading.

This function checks the receive buffer to determine how many bytes of data are ready to be read.

Returns:

The number of bytes available for reading. When no data is available or in case of an error this function returns 0.

inline Status ClearPendingReceiveBytes()#

Empties the UART’s receive buffer and discards any unread data.

This function removes all data from the receive buffer, resetting the buffer to an empty state. This is useful for situations where you want to disregard any previously received data and resynchronize.

Returns:

Code

Description

OK

The operation was successful.

May return other implementation-specific status codes.

Uart#

class Uart : public pw::uart::UartBase#

Represents an abstract UART interface.

The Uart interface provides a basic set of methods for performing blocking UART communication.

Subclassed by pw::uart::UartBlockingAdapter

Public Functions

inline StatusWithSize ReadAtLeast(ByteSpan rx_buffer, size_t min_bytes)#

Reads data from the UART into a provided buffer.

This function blocks until min_bytes have been read into rx_buffer.

Parameters:
  • rx_buffer – The buffer to read data into.

  • min_bytes – The minimum number of bytes to read before returning.

Returns:

Code

Description

OK

The operation was successful.

May return other implementation-specific status codes.

inline StatusWithSize ReadExactly(ByteSpan rx_buffer)#

Reads data from the UART into a provided buffer.

This function blocks until the entire buffer has been filled.

Parameters:

rx_buffer – The buffer to read data into.

Returns:

Code

Description

OK

The operation was successful.

May return other implementation-specific status codes.

inline Status Read(ByteSpan rx_buffer)#

Deprecated: Prefer ReadExactly in new code.

Reads data from the UART into a provided buffer.

This function blocks until the entire buffer has been filled.

Parameters:

rx_buffer – The buffer to read data into.

Returns:

Code

Description

OK

The operation was successful.

May return other implementation-specific status codes.

inline StatusWithSize TryReadAtLeastFor(ByteSpan rx_buffer, size_t min_bytes, chrono::SystemClock::duration timeout)#

Reads data from the UART into a provided buffer.

This function blocks until either min_bytes have been read into buffer or the specified timeout has elapsed, whichever occurs first.

Parameters:
  • rx_buffer – The buffer to read data into.

  • min_bytes – The minimum number of bytes to read before returning.

  • timeout – The maximum time to wait for data to be read. If zero, the function will immediately return with at least one hardware read operation attempt.

Returns:

Code

Description

OK

The operation was successful and the entire buffer has been filled with data.

DEADLINE_EXCEEDED

The operation timed out before the entire buffer could be filled.

May return other implementation-specific status codes.

inline StatusWithSize TryReadExactlyFor(ByteSpan rx_buffer, chrono::SystemClock::duration timeout)#

Reads data from the UART into a provided buffer.

This function blocks until either rx_buffer.size() bytes have been read into buffer or the specified timeout has elapsed, whichever occurs first.

Parameters:
  • rx_buffer – The buffer to read data into.

  • timeout – The maximum time to wait for data to be read. If zero, the function will immediately return with at least one hardware read operation attempt.

Returns:

Code

Description

OK

The operation was successful and the entire buffer has been filled with data.

DEADLINE_EXCEEDED

The operation timed out before the entire buffer could be filled.

May return other implementation-specific status codes.

inline StatusWithSize TryReadFor(ByteSpan rx_buffer, chrono::SystemClock::duration timeout)#

Deprecated: Prefer TryReadExactlyFor in new code. Reads data from the UART into a provided buffer.

This function blocks until either rx_buffer.size() bytes have been read into buffer or the specified timeout has elapsed, whichever occurs first.

Parameters:
  • rx_buffer – The buffer to read data into.

  • timeout – The maximum time to wait for data to be read. If zero, the function will immediately return with at least one hardware read operation attempt.

Returns:

Code

Description

OK

The operation was successful and the entire buffer has been filled with data.

DEADLINE_EXCEEDED

The operation timed out before the entire buffer could be filled.

May return other implementation-specific status codes.

inline Status Write(ConstByteSpan tx_buffer)#

Writes data from the provided buffer to the UART. The function blocks until the entire buffer has been written.

Parameters:

tx_buffer – - The buffer to write data from.

Returns:

Code

Description

OK

The operation was successful.

May return other implementation-specific status codes.

inline StatusWithSize TryWriteFor(ConstByteSpan tx_buffer, chrono::SystemClock::duration timeout)#

Writes data from the provided buffer to the UART. The function blocks until either the entire buffer has been written or the specified timeout has elapsed, whichever occurs first.

Parameters:
  • tx_buffer – The buffer to write data from.

  • timeout – The maximum time to wait for data to be written. If zero, the function will immediately return with at least one hardware write operation attempt.

Returns:

Code

Description

OK

The operation was successful and the entire buffer has been written.

DEADLINE_EXCEEDED

The operation timed out before the entire buffer could be written.

May return other implementation-specific status codes.

inline Status FlushOutput()#

Blocks until all queued data in the UART has been transmitted and the FIFO is empty.

This function ensures that all data enqueued before calling this function has been transmitted. Any data enqueued after calling this function will be transmitted immediately.

Returns:

Code

Description

OK

The operation was successful.

May return other implementation-specific status codes.

UartNonBlocking#

class UartNonBlocking : public pw::uart::UartBase#

Represents an abstract UART interface.

The UartNonBlocking interface provides a basic set of methods for performing Non-Blocking UART communication.

Public Functions

inline Status ReadExactly(ByteSpan rx_buffer, Function<void(Status status, ConstByteSpan buffer)> &&callback)#

Reads exactly rx_buffer.size() bytes from the UART into the provided buffer.

This function calls callback after the entirety of rx_buffer is filled with data. This may be called from interrupt context. The callback may be called in ISR context. It is safe to call Read/Write from the callback context.

Parameters:
  • rx_buffer – The buffer to read data into.

  • callback – A callback to invoke when the transaction is completed.

  • status – OK: The operation was successful and the entire buffer has been filled with data. CANCELLED: The operation was cancelled via CancelRead(). May return other implementation-specific status codes.

  • buffer – buffer.size() returns the number of bytes successfully read into the buffer. If status=OK, the buffer is identical to rx_buffer

Returns:

Code

Description

OK

The operation was successfully started. UNAVAILABLE: Another Read() transaction is currently in progress.

May return other implementation-specific status codes.

inline Status ReadAtLeast(ByteSpan rx_buffer, size_t min_bytes, Function<void(Status status, ConstByteSpan buffer)> &&callback)#

Reads at least min_bytes and at most rx_buffer.size() bytes from the UART into the provided buffer.

This function calls callback after rx_buffer is filled with at least min_bytes of data. This may be called from interrupt context. The callback may be called in ISR context. It is safe to call Read/Write from the callback context.

Parameters:
  • rx_buffer – The buffer to read data into.

  • min_bytes – Minimum bytes to read.

  • callback – A callback to invoke when the transaction is completed.

  • status – OK: The operation was successful and the buffer has been filled with at least min_bytes with data. CANCELLED: The operation was cancelled via CancelRead(). May return other implementation-specific status codes.

  • buffer – buffer.size() returns the number of bytes successfully read into the buffer.

Returns:

Code

Description

OK

The operation was successfully started. UNAVAILABLE: Another Read() transaction is currently in progress.

May return other implementation-specific status codes.

inline bool CancelRead()#

Cancel a current read in progress.

This function will cancel a read in progress. The read’s callback will be invoked with status=CANCELLED.

Returns:

true: The operation was successfully canceled a transaction in progress

and the callback will be invoked with status=CANCELLED.

false: There were no transactions in progress and nothing was

cancelled. No callback will be invoked.

inline Status Write(ConstByteSpan tx_buffer, Function<void(StatusWithSize status)> &&callback)#

Writes data from a provided buffer to the UART.

This function calls callback after the entirety of tx_buffer is written to the UART. This may be called from interrupt context. The callback may be called in ISR context. It is safe to call Read/Write from the callback context.

Parameters:
  • tx_buffer – The buffer to write to the UART.

  • callback – A callback to invoke when the transaction is completed.

  • status – status.size() returns the number of bytes successfully written from tx_buffer. OK: The operation was successful and the entire buffer has been written. CANCELLED: The operation was cancelled via CancelWrite(). May return other implementation-specific status codes.

Returns:

Code

Description

OK

The operation was successfully started. UNAVAILABLE: Another Write() transaction is currently in progress.

May return other implementation-specific status codes.

inline bool CancelWrite()#

Cancel a current write in progress.

This function will cancel a write in progress. The write’s callback will be called with status=CANCELLED.

Returns:

true: The operation was successfully canceled a transaction in progress

and the callback will be invoked with status=CANCELLED.

false: There were no transactions in progress and nothing was

cancelled. No callback will be invoked.

inline Status FlushOutput(Function<void(Status status)> &&callback)#

Ensures all queued data in the UART has been transmitted and the hardware FIFO is empty.

This function ensures that all data enqueued before calling this function has been transmitted. Any data enqueued after this function completes will be transmitted immediately.

Parameters:
  • callback – A callback to invoke when the flush is completed.

  • status – OK: The operation was successful and the transmit FIFO is empty. CANCELLED: The operation was cancelled via CancelFlushOutput(). May return other implementation-specific status codes.

Returns:

Code

Description

OK

The operation was successfully started. UNAVAILABLE: Another Write() or FlushOutput() operation is currently in progress.

May return other implementation-specific status codes.

inline bool CancelFlushOutput()#

Cancels a pending FlushOutput() operation.

This function will cancel an output flush in progress. The FlushOutput callback will be called with status=CANCELLED.

Returns:

true: The operation was successfully canceled a transaction in progress

and the callback will be invoked with status=CANCELLED.

false: There were no transactions in progress and nothing was

cancelled. No callback will be invoked.

UartBlockingAdapter#

class UartBlockingAdapter : public pw::uart::Uart#

UartBlockingAdapter provides the blocking Uart interface on top of a UartNonBlocking device.

Public Functions

inline UartBlockingAdapter(UartNonBlocking &uart)#

Constructs a UartBlockingAdapter for a UartNonBlocking device.

UartStream#

class UartStream : public pw::stream::NonSeekableReaderWriter#

UartStream implements the pw::stream::NonSeekableReaderWriter interface on top of a Uart device.

Public Functions

inline UartStream(Uart &uart)#

Constructs a UartStream for a Uart device.