📚 USART Receiver Timeout (RTO): Hardware‑Based Packet Detection
1️⃣ What Problem Does RTO Solve?
UP to this point, we’ve had two ways to detect the end of a UART packet:
-
Terminator character (
\r) -
Software timeout using
SysTick
Both work, but both rely on software to decide when a packet is complete. The STM32 USART peripheral includes a hardware timeout detector that can automatically:
-
Count the time since the last received bit
-
Trigger an interrupt when the timeout expires
-
Tell you “the packet is done” without SysTick
This is essential for DMA reception, because DMA has no idea when a packet ends. RTO becomes the hardware mechanism that says:
“Stop receiving — the sender has gone silent.”
2️⃣ How RTO Works (Conceptual)
-
The USART has an internal counter that increments based on the baud rate clock.
-
The timeout value is stored in:
USARTx->RTOR
The timeout period is:
$\mathrm{Timeout\ (seconds)}=\frac{\mathrm{RTOR}}{\mathrm{BaudRate}}$
So for instance, if:
-
Baud = 115200 bits/s
-
RTOR = 115200 × 2
Then:
$\mathrm{Timeout}=\frac{230400}{115200}=2\mathrm{\ seconds}$
3️⃣ Why RTO Is Better Than SysTick for Real Protocols
SysTick timeout:
- Requires software counter
- Requires ISR logic
- Requires careful tuning
- Works even if USART is not configured for RTO
RTO timeout:
- Fully hardware‑driven
- No SysTick needed
- No software counter
- Interrupt fires only when inactivity is detected
- Perfect for DMA circular buffer reception
4️⃣ How to Configure RTO (Step‑by‑Step Explanation)
Students need a clear, minimal checklist:
- Set the timeout value
USART2->RTOR &= ~USART_RTOR_RTO_Msk; USART2->RTOR |= UART_RTO_VALUE; // UART_RTO_VALUE is the timeout in bits
- Enable the RTO feature
USART2->CR2 |= USART_CR2_RTOEN;
- Enable the RTO interrupt
</pre> USART2->CR1 |= USART_CR1_RTOIE; </pre>
- Handle the RTO interrupt
Inside the USART ISR:
if (USART2->ISR & USART_ISR_RTOF)
{
USART2->ICR |= USART_ICR_RTOCF; // Clear flag
packetComplete = 1;
}
-
Continue receiving bytes normally
-
Your UART_RxByte() call handles RXNE and clears the flag.
- What Happens Internally (Timing Diagram)
This is the mental model students need:
- A byte arrives → RTO counter resets
- Another byte arrives → counter resets
- No byte arrives → counter increments
- When counter reaches RTOR → RTOF flag set
- USART triggers interrupt → packet is complete
flowchart TD
%% --- Data Reception Path ---
A[Byte arrives at USART RX pin] --> B[USART hardware shifts byte]
B --> C[RXNE flag set]
C --> D[USART ISR triggered]
D --> E[Read RDR using UART_RxByte]
E --> F[Store byte in rxBuffer]
F --> G[Hardware resets RTO counter]
%% --- Timeout Path ---
subgraph USART Hardware Timeout Logic
H[No new bytes arriving]
H --> I[RTO counter increments based on baud clock]
I --> J{Counter >= RTOR?}
J -->|Yes| K[RTOF flag set]
K --> L[USART ISR triggered]
end
%% --- ISR Timeout Handling ---
L --> M[Clear RTOF flag]
M --> N[packetComplete = 1]
%% --- Main Loop ---
N --> O[Main loop processes packet]
O --> P[Clear buffer and reset index]
This is the hardware equivalent of your SysTick logic.
- Why RTO Matters for DMA (Preview for Next Lesson)
DMA receives bytes into a buffer without CPU involvement. But DMA cannot detect packet boundaries. RTO solves that:
- DMA fills the buffer
- RTO interrupt fires when sender stops
- CPU reads the DMA buffer up to the last write index
- CPU processes the packet
- DMA continues running
This is the industry‑standard pattern for UART‑DMA reception.
- How to Explain the Demo
010-UsartDemo_Tout_RTO
The demo shows:
- SysTick is no longer used
- RTO is configured
- RTO interrupt fires when inactivity occurs
- RXNE interrupt still stores bytes
- Main loop processes the packet