Skip to content

Commit eefa1d1

Browse files
committed
refactor: use push_with to simplify dealing with circular buffer
1 parent 7027327 commit eefa1d1

File tree

1 file changed

+28
-31
lines changed

1 file changed

+28
-31
lines changed

esp-hal/src/dma/buffers.rs

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1526,51 +1526,29 @@ impl DmaTxStreamBufView {
15261526

15271527
/// Pushes a buffer into the stream buffer.
15281528
/// Returns the number of bytes pushed.
1529-
pub fn push(&mut self, buf: &[u8]) -> usize {
1530-
let bytes = self.available_bytes();
1531-
let bytes_to_fill = buf.len().min(bytes);
1532-
let buf = &buf[..bytes_to_fill];
1533-
if buf.is_empty() {
1534-
return 0;
1535-
}
1536-
1537-
fn truncate_by(n: usize, by: usize) -> usize {
1538-
if n >= by { n - by } else { n }
1539-
}
1540-
1541-
let n_chunks = self.buf.descriptors.len();
1529+
pub fn push_with(&mut self, f: impl FnOnce(&mut [u8]) -> usize) -> usize {
15421530
let chunk_size = self.buf.descriptors[0].size();
1543-
let dma_size = self.buf.buffer.len();
15441531
let dma_start = self.descriptor_idx * chunk_size + self.descriptor_offset;
1545-
let dma_end = truncate_by(dma_start + buf.len(), dma_size);
1546-
1547-
if dma_start < dma_end {
1548-
self.buf.buffer[dma_start..dma_end].copy_from_slice(buf);
1549-
} else {
1550-
self.buf.buffer[dma_start..].copy_from_slice(&buf[..dma_size - dma_start]);
1551-
self.buf.buffer[..dma_end].copy_from_slice(&buf[dma_size - dma_start..]);
1552-
}
1532+
let bytes_pushed = f(&mut self.buf.buffer[dma_start..]);
15531533

1554-
let descs = (self.descriptor_idx..n_chunks).chain(0..self.descriptor_idx);
15551534
let mut bytes_filled = 0;
1556-
1557-
for d in descs {
1535+
for d in (self.descriptor_idx..self.buf.descriptors.len()).chain(core::iter::once(0)) {
15581536
let desc = &mut self.buf.descriptors[d];
15591537
let bytes_in_d = desc.size() - self.descriptor_offset;
1560-
if bytes_in_d + bytes_filled > buf.len() {
1561-
// I will have empty space in `desc`
1538+
// There is at least one byte left in `desc`.
1539+
if bytes_in_d + bytes_filled > bytes_pushed {
15621540
self.descriptor_idx = d;
1563-
self.descriptor_offset = self.descriptor_offset + buf.len() - bytes_filled;
1541+
self.descriptor_offset = self.descriptor_offset + bytes_pushed - bytes_filled;
15641542
break;
15651543
}
1566-
// fill `desc` with data from `buf`
15671544
bytes_filled += bytes_in_d;
15681545
self.descriptor_offset = 0;
15691546

1547+
// Put the current descriptor at the end of the list
15701548
desc.set_owner(Owner::Dma);
15711549
desc.set_length(desc.size());
15721550
desc.set_suc_eof(true);
1573-
let p = d.checked_sub(1).unwrap_or(n_chunks - 1);
1551+
let p = d.checked_sub(1).unwrap_or(self.buf.descriptors.len() - 1);
15741552
if p != d {
15751553
let [prev, desc] = self.buf.descriptors.get_disjoint_mut([p, d]).unwrap();
15761554
desc.next = null_mut();
@@ -1579,7 +1557,26 @@ impl DmaTxStreamBufView {
15791557
}
15801558
}
15811559

1582-
bytes_to_fill
1560+
bytes_pushed
1561+
}
1562+
1563+
/// Pushes a buffer into the stream buffer.
1564+
/// Returns the number of bytes pushed.
1565+
pub fn push(&mut self, data: &[u8]) -> usize {
1566+
let mut remaining = data.len();
1567+
let mut offset = 0;
1568+
1569+
while self.available_bytes() >= remaining && remaining > 0 {
1570+
let written = self.push_with(|buffer| {
1571+
let len = usize::min(buffer.len(), data.len() - offset);
1572+
buffer[..len].copy_from_slice(&data[offset..][..len]);
1573+
len
1574+
});
1575+
offset += written;
1576+
remaining -= written;
1577+
}
1578+
1579+
offset
15831580
}
15841581
}
15851582

0 commit comments

Comments
 (0)