Skip to content

Commit 8b3a422

Browse files
committed
feat: tx buf stream push
1 parent 2b8d122 commit 8b3a422

File tree

1 file changed

+46
-44
lines changed

1 file changed

+46
-44
lines changed

esp-hal/src/dma/buffers.rs

Lines changed: 46 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1517,66 +1517,68 @@ impl DmaTxStreamBufView {
15171517
head.iter()
15181518
.chain(tail)
15191519
.take_while(|d| d.owner() == Owner::Cpu)
1520-
.map(|d| d.len())
1520+
.map(|d| d.size())
15211521
.sum::<usize>()
15221522
- self.descriptor_offset
15231523
}
15241524

15251525
/// Pushes a buffer into the stream buffer.
15261526
/// Returns the number of bytes pushed.
15271527
pub fn push(&mut self, buf: &[u8]) -> usize {
1528+
let bytes_to_fill = buf.len().min(self.available_bytes());
1529+
let buf = &buf[..bytes_to_fill];
1530+
1531+
fn truncate_by(n: usize, by: usize) -> usize {
1532+
(n >= by).then_some(n - by).unwrap_or(n)
1533+
}
1534+
1535+
let n_chunks = self.buf.descriptors.len();
15281536
let chunk_size = self.buf.descriptors[0].size();
1529-
let n_descs = self.buf.descriptors.len();
1537+
let dma_size = self.buf.buffer.len();
1538+
let dma_start = self.descriptor_idx * chunk_size + self.descriptor_offset;
1539+
let dma_end = truncate_by(dma_start + buf.len(), dma_size);
15301540

1531-
// Prepare descriptors and reorganize link list
1532-
let buf_start = chunk_size * self.descriptor_idx + self.descriptor_offset;
1533-
let desc_start = self.descriptor_idx;
1534-
let mut buf_idx = 0;
1535-
loop {
1536-
let d = &mut self.buf.descriptors[self.descriptor_idx];
1537-
if d.owner() == Owner::Dma {
1538-
break;
1539-
}
1541+
if dma_start < dma_end {
1542+
self.buf.buffer[dma_start..dma_end].copy_from_slice(buf);
1543+
} else {
1544+
self.buf.buffer[dma_start..].copy_from_slice(&buf[..dma_size - dma_start]);
1545+
self.buf.buffer[..dma_end].copy_from_slice(&buf[dma_size - dma_start..]);
1546+
}
15401547

1541-
let desc_remain = d.len() - self.descriptor_offset;
1542-
if buf_idx + desc_remain >= buf.len() {
1543-
self.descriptor_offset += desc_remain;
1548+
let descs = (self.descriptor_idx..n_chunks).chain(0..self.descriptor_idx);
1549+
let mut offset = self.descriptor_offset;
1550+
let mut bytes_filled = 0;
1551+
1552+
for d in descs {
1553+
let desc = &mut self.buf.descriptors[d];
1554+
let bytes_in_d = desc.size() - offset;
1555+
if bytes_in_d + bytes_filled > buf.len() {
1556+
// I will have empty space in `desc`
1557+
self.descriptor_idx = d;
1558+
self.descriptor_offset = offset + buf.len() - bytes_filled;
15441559
break;
15451560
}
1546-
buf_idx += desc_remain;
1547-
1548-
d.next = null_mut();
1549-
let prev = self.descriptor_idx.checked_sub(1).unwrap_or(n_descs - 1);
1550-
self.buf.descriptors[prev].next = d;
1561+
// fill `desc` with data from `buf`
1562+
bytes_filled += bytes_in_d;
1563+
offset = 0;
15511564

1552-
self.descriptor_idx += 1;
1553-
if self.descriptor_idx > n_descs {
1554-
self.descriptor_idx = 0;
1565+
desc.set_owner(Owner::Dma);
1566+
desc.set_length(desc.size());
1567+
desc.set_suc_eof(true);
1568+
let p = d.checked_sub(1).unwrap_or(n_chunks - 1);
1569+
if p != d {
1570+
let [prev, desc] = self.buf.descriptors.get_disjoint_mut([p, d]).unwrap();
1571+
desc.next = null_mut();
1572+
prev.next = desc;
15551573
}
1556-
self.descriptor_offset = 0;
15571574
}
1558-
let buf_end = chunk_size * self.descriptor_idx + self.descriptor_offset;
1559-
let desc_end = self.descriptor_idx;
15601575

1561-
// Actually copy buffers
1562-
if buf_start < buf_end {
1563-
self.buf.buffer[buf_start..buf_end].copy_from_slice(&buf[..buf_end - buf_start]);
1564-
self.buf.descriptors[desc_start..desc_end]
1565-
.iter_mut()
1566-
.for_each(|d| d.set_owner(Owner::Dma));
1567-
buf_end - buf_start
1568-
} else {
1569-
let buf_len = self.buf.buffer.len();
1570-
self.buf.buffer[buf_start..].copy_from_slice(&buf[..buf_len - buf_start]);
1571-
self.buf.buffer[..buf_end].copy_from_slice(&buf[buf_len - buf_start..]);
1572-
self.buf.descriptors[desc_start..]
1573-
.iter_mut()
1574-
.for_each(|d| d.set_owner(Owner::Dma));
1575-
self.buf.descriptors[..desc_end]
1576-
.iter_mut()
1577-
.for_each(|d| d.set_owner(Owner::Dma));
1578-
buf_len + buf_end - buf_start
1579-
}
1576+
info!(
1577+
"self.descriptor_idx: {}, self.descriptor_offset: {}, dma_start: {}, dma_end: {}",
1578+
self.descriptor_idx, self.descriptor_offset, dma_start, dma_end
1579+
);
1580+
1581+
bytes_to_fill
15801582
}
15811583
}
15821584

0 commit comments

Comments
 (0)