Skip to content

Commit

Permalink
pw_uart_mcuxpresso: Implement FlushOutput for dma_uart_nonblocking
Browse files Browse the repository at this point in the history
Basic implementation of FlushOutput, equivalent to waiting for the write
request to complete.

Bug: 394313492
Change-Id: Ieaa38668c36b44dd13b5361962794c9720551d5b
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/267952
Lint: Lint 🤖 <[email protected]>
Reviewed-by: Austin Foxley <[email protected]>
Docs-Not-Needed: Austin Foxley <[email protected]>
Commit-Queue: Edward Shin <[email protected]>
  • Loading branch information
Edward Shin authored and CQ Bot Account committed Feb 25, 2025
1 parent 5eec1e4 commit 56fe85e
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 5 deletions.
43 changes: 38 additions & 5 deletions pw_uart_mcuxpresso/dma_uart_nonblocking.cc
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ Status DmaUartMcuxpressoNonBlocking::Init() {

rx_data_.request.valid = false;
tx_data_.request.valid = false;
tx_data_.flush_request.valid = false;

// Begin reading into the ring buffer.
TriggerReadDmaIntoRingBuffer();
Expand Down Expand Up @@ -525,6 +526,7 @@ void DmaUartMcuxpressoNonBlocking::TxRxCompletionCallback(status_t status) {
if (tx_data_.tx_idx == tx_data_.buffer.size_bytes()) {
tx_data_.request.callback(StatusWithSize(tx_data_.buffer.size_bytes()));
tx_data_.request.valid = false;
CompleteFlushRequest(OkStatus());
} else {
// No, set up a followup DMA.
PW_CHECK_INT_LT(tx_data_.tx_idx, tx_data_.buffer.size_bytes());
Expand Down Expand Up @@ -627,6 +629,8 @@ bool DmaUartMcuxpressoNonBlocking::DoCancelWrite() {
tx_data_.request.callback(StatusWithSize::Cancelled(bytes_transmitted));
tx_data_.request.valid = false;

CompleteFlushRequest(Status::Aborted());

return true;
}

Expand Down Expand Up @@ -699,13 +703,42 @@ Status DmaUartMcuxpressoNonBlocking::DoSetFlowControl(bool enable) {
return OkStatus();
}

// Unimplemented
bool DmaUartMcuxpressoNonBlocking::CompleteFlushRequest(Status status) {
if (!tx_data_.flush_request.valid) {
return false;
}

tx_data_.flush_request.callback(status);
tx_data_.flush_request.valid = false;
tx_data_.flush_request.callback = nullptr;

PW_DCHECK(USART_FIFOSTAT_TXEMPTY(config_.usart_base->FIFOSTAT));

return true;
}

Status DmaUartMcuxpressoNonBlocking::DoFlushOutput(
Function<void(Status status)>&& /*callback*/) {
return Status::Unimplemented();
Function<void(Status status)>&& callback) {
std::lock_guard lock(interrupt_lock_);

if (tx_data_.flush_request.valid) {
return Status::FailedPrecondition();
}

if (!tx_data_.request.valid) {
callback(OkStatus());
return OkStatus();
}

tx_data_.flush_request.callback = std::move(callback);
tx_data_.flush_request.valid = true;

return OkStatus();
}

// Unimplemented
bool DmaUartMcuxpressoNonBlocking::DoCancelFlushOutput() { return false; }
bool DmaUartMcuxpressoNonBlocking::DoCancelFlushOutput() {
std::lock_guard lock(interrupt_lock_);
return CompleteFlushRequest(Status::Cancelled());
}

} // namespace pw::uart
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ class DmaUartMcuxpressoNonBlocking final : public UartNonBlocking {
bool valid{}; // A request is in-flight
Function<void(StatusWithSize status)> callback;
} request{};
struct {
bool valid{};
Function<void(Status status)> callback;
} flush_request{};
};

enum class DmaRxTarget {
Expand Down Expand Up @@ -132,6 +136,9 @@ class DmaUartMcuxpressoNonBlocking final : public UartNonBlocking {

bool ClearRxDmaInterrupt() PW_EXCLUSIVE_LOCKS_REQUIRED(interrupt_lock_);

bool CompleteFlushRequest(Status status)
PW_EXCLUSIVE_LOCKS_REQUIRED(interrupt_lock_);

void TriggerReadDmaIntoRingBuffer()
PW_EXCLUSIVE_LOCKS_REQUIRED(interrupt_lock_);
void TriggerReadDmaIntoUserBuffer()
Expand Down

0 comments on commit 56fe85e

Please sign in to comment.