diff --git a/hal/src/rtl872x/usart_hal.cpp b/hal/src/rtl872x/usart_hal.cpp index acd31451d7..54354a9516 100644 --- a/hal/src/rtl872x/usart_hal.cpp +++ b/hal/src/rtl872x/usart_hal.cpp @@ -288,6 +288,7 @@ class Usart { txBuffer_.reset(); curTxCount_ = 0; transmitting_ = false; + busy_ = false; receiving_ = false; state_ = HAL_USART_STATE_DISABLED; return SYSTEM_ERROR_NONE; @@ -300,6 +301,7 @@ class Usart { dataInFlight(true /* commit */); CHECK(disable(false)); transmitting_ = false; + busy_ = false; receiving_ = 0; rxBuffer_.prune(); txBuffer_.reset(); @@ -339,12 +341,12 @@ class Usart { ssize_t flush() { CHECK_TRUE(isEnabled(), SYSTEM_ERROR_INVALID_STATE); while (true) { - while (transmitting_) { + while (transmitting_ || busy_) { // FIXME: busy loop } { AtomicBlock atomic(this); - if (!isEnabled() || txBuffer_.empty()) { + if ((!isEnabled() || txBuffer_.empty()) && !busy_) { break; } } @@ -470,6 +472,7 @@ class Usart { if (event & HAL_USART_PVT_EVENT_WRITABLE) { if (space() <= 0) { TxLock lk(this); + xEventGroupClearBits(evGroup_, HAL_USART_PVT_EVENT_WRITABLE); UART_INTConfig(uartInstance, RUART_IER_ETBEI, ENABLE); // Temporarily disable TX DMA, otherwise, the TX FIFO won't be empty until all data is transferred by DMA. UART_TXDMACmd(uartInstance, DISABLE); @@ -572,6 +575,9 @@ class Usart { } else { UART_TXDMACmd(uartInstance, ENABLE); BaseType_t yield = pdFALSE; + if (!uart->transmitting_) { + uart->busy_ = false; // All bytes sent if no new DMA transfers are in progress + } if (xEventGroupSetBitsFromISR(uart->evGroup_, HAL_USART_PVT_EVENT_WRITABLE, &yield) != pdFAIL) { portYIELD_FROM_ISR(yield); } @@ -618,6 +624,7 @@ class Usart { curTxCount_(0), state_(HAL_USART_STATE_DISABLED), transmitting_(false), + busy_(false), receiving_(false), configured_(false), index_(index), @@ -831,6 +838,8 @@ class Usart { curTxCount_ = consumable; GDMA_Init(txDmaInitStruct_.GDMA_Index, txDmaInitStruct_.GDMA_ChNum, &txDmaInitStruct_); GDMA_Cmd(txDmaInitStruct_.GDMA_Index, txDmaInitStruct_.GDMA_ChNum, ENABLE); + busy_ = true; + UART_INTConfig(uartInstance, RUART_IER_ETBEI, ENABLE); } else { // LOG UART doesn't support DMA transmission consumable = std::min(MAX_UART_FIFO_SIZE, consumable); @@ -982,6 +991,7 @@ class Usart { volatile hal_usart_state_t state_; volatile bool transmitting_; + volatile bool busy_; volatile bool receiving_; bool configured_;