Skip to content

Commit 2b8d122

Browse files
committed
feat: tx stream buf
1 parent b0ae18d commit 2b8d122

File tree

1 file changed

+44
-7
lines changed

1 file changed

+44
-7
lines changed

esp-hal/src/dma/buffers.rs

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,6 +1160,7 @@ impl DmaRxStreamBuf {
11601160
}
11611161

11621162
// Check that the last descriptor can hold the excess
1163+
// FIXME: shouldn't this be `buffer.len() % chunk_size` ?
11631164
let excess = buffer.len() % descriptors.len();
11641165
if chunk_size + excess > 4095 {
11651166
return Err(DmaBufError::InsufficientDescriptors);
@@ -1415,12 +1416,44 @@ pub struct DmaTxStreamBuf {
14151416
impl DmaTxStreamBuf {
14161417
/// Creates a new [DmaTxStreamBuf] evenly distributing the buffer between
14171418
/// the provided descriptors.
1418-
pub fn new(descriptors: &'static mut [DmaDescriptor], buffer: &'static mut [u8]) -> Self {
1419-
Self {
1419+
pub fn new(
1420+
descriptors: &'static mut [DmaDescriptor],
1421+
buffer: &'static mut [u8],
1422+
) -> Result<Self, DmaBufError> {
1423+
match () {
1424+
_ if !is_slice_in_dram(descriptors) => Err(DmaBufError::UnsupportedMemoryRegion)?,
1425+
_ if !is_slice_in_dram(buffer) => Err(DmaBufError::UnsupportedMemoryRegion)?,
1426+
_ if descriptors.is_empty() => Err(DmaBufError::InsufficientDescriptors)?,
1427+
_ => (),
1428+
};
1429+
1430+
// Evenly distribute the buffer between the descriptors.
1431+
let chunk_size = Some(buffer.len() / descriptors.len())
1432+
.filter(|x| *x <= 4095)
1433+
.ok_or(DmaBufError::InsufficientDescriptors)?;
1434+
1435+
let mut chunks = buffer.chunks_exact_mut(chunk_size);
1436+
for (desc, chunk) in descriptors.iter_mut().zip(chunks.by_ref()) {
1437+
desc.buffer = chunk.as_mut_ptr();
1438+
desc.set_size(chunk.len());
1439+
}
1440+
let remainder = chunks.into_remainder();
1441+
1442+
if !remainder.is_empty() {
1443+
// Append any excess to the last descriptor.
1444+
let last_descriptor = descriptors.last_mut().unwrap();
1445+
let size = last_descriptor.size() + remainder.len();
1446+
if size > 4095 {
1447+
Err(DmaBufError::InsufficientDescriptors)?;
1448+
}
1449+
last_descriptor.set_size(size);
1450+
}
1451+
1452+
Ok(Self {
14201453
descriptors,
14211454
buffer,
14221455
burst: Default::default(),
1423-
}
1456+
})
14241457
}
14251458

14261459
/// Consume the buf, returning the descriptors and buffer.
@@ -1430,7 +1463,7 @@ impl DmaTxStreamBuf {
14301463
}
14311464

14321465
unsafe impl DmaTxBuffer for DmaTxStreamBuf {
1433-
type View = ();
1466+
type View = DmaTxStreamBufView;
14341467

14351468
fn prepare(&mut self) -> Preparation {
14361469
// Link up all the descriptors (but not in a circle).
@@ -1439,7 +1472,7 @@ unsafe impl DmaTxBuffer for DmaTxStreamBuf {
14391472
desc.next = next;
14401473
next = desc;
14411474

1442-
desc.reset_for_rx();
1475+
desc.reset_for_tx(desc.next.is_null());
14431476
}
14441477
Preparation {
14451478
start: self.descriptors.as_mut_ptr(),
@@ -1458,11 +1491,15 @@ unsafe impl DmaTxBuffer for DmaTxStreamBuf {
14581491
}
14591492

14601493
fn into_view(self) -> Self::View {
1461-
todo!()
1494+
DmaTxStreamBufView {
1495+
buf: self,
1496+
descriptor_idx: 0,
1497+
descriptor_offset: 0,
1498+
}
14621499
}
14631500

14641501
fn from_view(view: Self::View) -> Self {
1465-
todo!()
1502+
view.buf
14661503
}
14671504
}
14681505

0 commit comments

Comments
 (0)