Skip to content

Commit aa8adee

Browse files
committed
STM32: USART: Make BufferedUartRx return all available bytes when they wrap around the internal buffer end
1 parent 818b3f7 commit aa8adee

File tree

2 files changed

+26
-14
lines changed

2 files changed

+26
-14
lines changed

embassy-stm32/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2222
- fix: handle address and data-length errors in OSPI
2323
- feat: Allow OSPI DMA writes larger than 64kB using chunking
2424
- feat: More ADC enums for g0 PAC, API change for oversampling, allow separate sample times
25+
- feat: derive Clone, Copy and defmt::Format for all SPI-related configs
2526
- feat: stm32/usart: add `eager_reads` option to control if buffered readers return as soon as possible or after more data is available ([#4668](https://github.com/embassy-rs/embassy/pull/4668))
27+
- feat: stm32/usart: add `de_assertion_time` and `de_deassertion_time` config options
28+
- change: stm32/uart: BufferedUartRx now returns all available bytes from the internal buffer
2629

2730
## 0.4.0 - 2025-08-26
2831

embassy-stm32/src/usart/buffered.rs

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -565,24 +565,30 @@ impl<'d> BufferedUartRx<'d> {
565565
poll_fn(move |cx| {
566566
let state = self.state;
567567
let mut rx_reader = unsafe { state.rx_buf.reader() };
568-
let data = rx_reader.pop_slice();
568+
let mut buf_len = 0;
569+
let mut data = rx_reader.pop_slice();
569570

570-
if !data.is_empty() {
571-
let len = data.len().min(buf.len());
572-
buf[..len].copy_from_slice(&data[..len]);
571+
while !data.is_empty() && buf_len < buf.len() {
572+
let data_len = data.len().min(buf.len() - buf_len);
573+
buf[buf_len..buf_len + data_len].copy_from_slice(&data[..data_len]);
574+
buf_len += data_len;
573575

574576
let do_pend = state.rx_buf.is_full();
575-
rx_reader.pop_done(len);
577+
rx_reader.pop_done(data_len);
576578

577579
if do_pend {
578580
self.info.interrupt.pend();
579581
}
580582

581-
return Poll::Ready(Ok(len));
583+
data = rx_reader.pop_slice();
582584
}
583585

584-
state.rx_waker.register(cx.waker());
585-
Poll::Pending
586+
if buf_len != 0 {
587+
Poll::Ready(Ok(buf_len))
588+
} else {
589+
state.rx_waker.register(cx.waker());
590+
Poll::Pending
591+
}
586592
})
587593
.await
588594
}
@@ -591,21 +597,24 @@ impl<'d> BufferedUartRx<'d> {
591597
loop {
592598
let state = self.state;
593599
let mut rx_reader = unsafe { state.rx_buf.reader() };
594-
let data = rx_reader.pop_slice();
600+
let mut buf_len = 0;
601+
let mut data = rx_reader.pop_slice();
595602

596-
if !data.is_empty() {
597-
let len = data.len().min(buf.len());
598-
buf[..len].copy_from_slice(&data[..len]);
603+
while !data.is_empty() && buf_len < buf.len() {
604+
let data_len = data.len().min(buf.len() - buf_len);
605+
buf[buf_len..buf_len + data_len].copy_from_slice(&data[..data_len]);
606+
buf_len += data_len;
599607

600608
let do_pend = state.rx_buf.is_full();
601-
rx_reader.pop_done(len);
609+
rx_reader.pop_done(data_len);
602610

603611
if do_pend {
604612
self.info.interrupt.pend();
605613
}
606614

607-
return Ok(len);
615+
data = rx_reader.pop_slice();
608616
}
617+
return Ok(buf_len);
609618
}
610619
}
611620

0 commit comments

Comments
 (0)