Skip to content

Commit 834bf3c

Browse files
committed
test: use macros for creating DMA tx stream buffers
1 parent 24478a4 commit 834bf3c

File tree

6 files changed

+48
-79
lines changed

6 files changed

+48
-79
lines changed

esp-hal/src/dma/buffers.rs

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1431,7 +1431,7 @@ impl DmaRxStreamBufView {
14311431

14321432
/// DMA Streaming Transmit Buffer.
14331433
///
1434-
/// This is symmetric implementation to [DmaTxStreamBuf], used for continuously
1434+
/// This is symmetric implementation to [DmaRxStreamBuf], used for continuously
14351435
/// streaming data to a peripheral's FIFO.
14361436
///
14371437
/// The list starts out like so `A(full) -> B(full) -> C(full) -> D(full) -> NULL`.
@@ -1448,7 +1448,7 @@ impl DmaRxStreamBufView {
14481448
/// - `C(empty) -> D(full) -> A(full) -> B(full) -> NULL`
14491449
/// - `D(full) -> A(full) -> B(full) -> C(full) -> NULL`
14501450
///
1451-
/// If all the descriptors fill up, the [DmaTxInterrupt::TotalEof] interrupt will fire and DMA
1451+
/// If all the descriptors run out, the [DmaTxInterrupt::TotalEof] interrupt will fire and DMA
14521452
/// will stop writing, at which point it is up to you to resume/restart the transfer.
14531453
pub struct DmaTxStreamBuf {
14541454
descriptors: &'static mut [DmaDescriptor],
@@ -1506,15 +1506,26 @@ impl DmaTxStreamBuf {
15061506
(self.descriptors, self.buffer)
15071507
}
15081508

1509-
/// Fill the buffer with the given data before DMA transfer starts.
1509+
/// Push the buffer with the given data before DMA transfer starts.
15101510
///
15111511
/// Otherwise the streaming buffer will transfer garbage data to
15121512
/// DMA so that CPU has enough time to fill the buffer after transfer starts.
1513-
pub fn fill(&mut self, data: &[u8]) -> usize {
1514-
let n = self.buffer.len().min(data.len());
1515-
self.buffer[..n].copy_from_slice(&data[..n]);
1516-
self.pre_filled = Some(n);
1517-
n
1513+
pub fn push(&mut self, data: &[u8]) -> usize {
1514+
self.push_with(|buf| {
1515+
let len = buf.len().min(data.len());
1516+
buf[..len].copy_from_slice(&data[..len]);
1517+
len
1518+
})
1519+
}
1520+
1521+
/// Push the buffer with the given data before DMA transfer starts.
1522+
///
1523+
/// Returns the number of bytes filled.
1524+
pub fn push_with(&mut self, f: impl FnOnce(&mut [u8]) -> usize) -> usize {
1525+
let start = self.pre_filled.unwrap_or(0);
1526+
let bytes_pushed = f(&mut self.buffer[start..]);
1527+
self.pre_filled = Some(start + bytes_pushed);
1528+
bytes_pushed
15181529
}
15191530
}
15201531

@@ -1555,7 +1566,7 @@ unsafe impl DmaTxBuffer for DmaTxStreamBuf {
15551566
descriptor_idx: 0,
15561567
descriptor_offset: 0,
15571568
};
1558-
view.update_state(pre_filled);
1569+
view.advance(pre_filled);
15591570
view
15601571
}
15611572

@@ -1591,12 +1602,12 @@ impl DmaTxStreamBufView {
15911602
let dma_end = (dma_start + self.available_bytes()).min(self.buf.buffer.len());
15921603
let bytes_pushed = f(&mut self.buf.buffer[dma_start..dma_end]);
15931604

1594-
self.update_state(bytes_pushed);
1605+
self.advance(bytes_pushed);
15951606
bytes_pushed
15961607
}
15971608

1598-
/// Updates the view state on pushed with `bytes_pushed` many bytes.
1599-
fn update_state(&mut self, bytes_pushed: usize) {
1609+
/// Advances the first `n` bytes from the available data
1610+
fn advance(&mut self, bytes_pushed: usize) {
16001611
let mut bytes_filled = 0;
16011612
for d in (self.descriptor_idx..self.buf.descriptors.len()).chain(core::iter::once(0)) {
16021613
let desc = &mut self.buf.descriptors[d];

esp-hal/src/dma/mod.rs

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -77,30 +77,6 @@ use crate::{
7777
system::Cpu,
7878
};
7979

80-
trait Word: crate::private::Sealed {}
81-
82-
macro_rules! impl_word {
83-
($w:ty) => {
84-
impl $crate::private::Sealed for $w {}
85-
impl Word for $w {}
86-
};
87-
}
88-
89-
impl_word!(u8);
90-
impl_word!(u16);
91-
impl_word!(u32);
92-
impl_word!(i8);
93-
impl_word!(i16);
94-
impl_word!(i32);
95-
96-
impl<W, const S: usize> crate::private::Sealed for [W; S] where W: Word {}
97-
98-
impl<W, const S: usize> crate::private::Sealed for &[W; S] where W: Word {}
99-
100-
impl<W> crate::private::Sealed for &[W] where W: Word {}
101-
102-
impl<W> crate::private::Sealed for &mut [W] where W: Word {}
103-
10480
bitfield::bitfield! {
10581
/// DMA descriptor flags.
10682
#[derive(Clone, Copy, PartialEq, Eq)]

esp-hal/src/i2s/master.rs

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,9 @@
7676
//! ```rust, no_run
7777
//! # {before_snippet}
7878
//! # use esp_hal::i2s::master::{I2s, Channels, DataFormat, Config};
79-
//! # use esp_hal::dma_buffers_chunk_size;
80-
//! # use esp_hal::dma::DmaRxStreamBuf;
79+
//! # use esp_hal::dma_rx_stream_buffer;
8180
//! # {dma_channel}
82-
//! let (mut rx_buffer, rx_descriptors, _, _) = dma_buffers_chunk_size!(4 * 4092, 0, 4092);
81+
//! let rx_buffer = dma_rx_stream_buffer!(4 * 4092);
8382
//!
8483
//! let i2s = I2s::new(
8584
//! peripherals.I2S0,
@@ -97,10 +96,7 @@
9796
//! .with_din(peripherals.GPIO5)
9897
//! .build();
9998
//!
100-
//! let mut transfer = i2s_rx.read(
101-
//! DmaRxStreamBuf::new(rx_descriptors, rx_buffer).unwrap(),
102-
//! 4092,
103-
//! )?;
99+
//! let mut transfer = i2s_rx.read(rx_buffer, 4092)?;
104100
//!
105101
//! loop {
106102
//! let avail = transfer.available_bytes();
@@ -172,15 +168,6 @@ pub(crate) const I2S_LL_MCLK_DIVIDER_BIT_WIDTH: usize = 9;
172168

173169
pub(crate) const I2S_LL_MCLK_DIVIDER_MAX: usize = (1 << I2S_LL_MCLK_DIVIDER_BIT_WIDTH) - 1;
174170

175-
/// Data types that the I2S peripheral can work with.
176-
pub trait AcceptedWord: crate::private::Sealed {}
177-
impl AcceptedWord for u8 {}
178-
impl AcceptedWord for u16 {}
179-
impl AcceptedWord for u32 {}
180-
impl AcceptedWord for i8 {}
181-
impl AcceptedWord for i16 {}
182-
impl AcceptedWord for i32 {}
183-
184171
/// I2S Error
185172
#[derive(Debug, Clone, Copy, PartialEq)]
186173
#[cfg_attr(feature = "defmt", derive(defmt::Format))]

hil-test/src/bin/embassy_interrupt_spi_dma.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,10 @@ async fn interrupt_driven_task(spi: esp_hal::spi::master::SpiDma<'static, Blocki
5757
#[cfg(not(any(esp32, esp32s2, esp32s3)))]
5858
#[embassy_executor::task]
5959
async fn interrupt_driven_task(i2s_tx: esp_hal::i2s::master::I2s<'static, Blocking>) {
60-
use esp_hal::{dma::DmaTxStreamBuf, dma_buffers_chunk_size};
61-
let (_, _, tx_buffer, tx_descriptors) = dma_buffers_chunk_size!(128, 128, 128 / 3);
60+
use esp_hal::dma_tx_stream_buffer;
61+
let mut buf = dma_tx_stream_buffer!(128, 128 / 3);
6262

6363
let mut i2s_tx = i2s_tx.into_async().i2s_tx.build();
64-
let mut buf = DmaTxStreamBuf::new(tx_descriptors, tx_buffer).unwrap();
65-
6664
loop {
6765
let mut buffer: [u8; 8] = [0; 8];
6866

hil-test/src/bin/i2s.rs

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
use esp_hal::{
1414
Async,
1515
delay::Delay,
16-
dma::{DmaDescriptor, DmaTxStreamBuf},
16+
dma::DmaTxStreamBuf,
1717
gpio::{AnyPin, NoPin, Pin},
1818
i2s::master::{Channels, Config, DataFormat, I2s, I2sTx},
1919
peripherals::I2S0,
@@ -57,19 +57,16 @@ impl Iterator for SampleSource {
5757
}
5858

5959
#[embassy_executor::task]
60-
async fn writer(
61-
tx_buffer: &'static mut [u8],
62-
tx_descriptors: &'static mut [DmaDescriptor],
63-
i2s_tx: I2sTx<'static, Async>,
64-
) {
60+
async fn writer(mut tx_buffer: DmaTxStreamBuf, i2s_tx: I2sTx<'static, Async>) {
6561
let mut samples = SampleSource::new();
66-
for b in tx_buffer.iter_mut() {
67-
*b = samples.next().unwrap();
68-
}
62+
tx_buffer.push_with(|buf| {
63+
for b in buf.iter_mut() {
64+
*b = samples.next().unwrap();
65+
}
66+
buf.len()
67+
});
6968

70-
let mut tx_transfer = i2s_tx
71-
.write(DmaTxStreamBuf::new(tx_descriptors, tx_buffer).unwrap())
72-
.unwrap();
69+
let mut tx_transfer = i2s_tx.write(tx_buffer).unwrap();
7370

7471
loop {
7572
while tx_transfer.available_bytes() == 0 {
@@ -102,7 +99,12 @@ fn enable_loopback() {
10299

103100
#[embedded_test::tests(default_timeout = 3, executor = hil_test::Executor::new())]
104101
mod tests {
105-
use esp_hal::{dma::DmaRxStreamBuf, dma_buffers_chunk_size};
102+
use esp_hal::{
103+
dma::DmaRxStreamBuf,
104+
dma_buffers_chunk_size,
105+
dma_rx_stream_buffer,
106+
dma_tx_stream_buffer,
107+
};
106108

107109
use super::*;
108110

@@ -140,8 +142,8 @@ mod tests {
140142
let spawner = unsafe { embassy_executor::Spawner::for_current_executor().await };
141143

142144
// We need more than 3 descriptors for continuous transfer to work
143-
let (rx_buffer, rx_descriptors, tx_buffer, tx_descriptors) =
144-
esp_hal::dma_buffers_chunk_size!(BUFFER_SIZE, BUFFER_SIZE, BUFFER_SIZE / 3);
145+
let rx_buffer = dma_rx_stream_buffer!(BUFFER_SIZE, BUFFER_SIZE / 3);
146+
let tx_buffer = dma_tx_stream_buffer!(BUFFER_SIZE, BUFFER_SIZE / 3);
145147

146148
let i2s = I2s::new(
147149
ctx.i2s,
@@ -172,13 +174,8 @@ mod tests {
172174

173175
enable_loopback();
174176

175-
let mut rx_transfer = i2s_rx
176-
.read(
177-
DmaRxStreamBuf::new(rx_descriptors, rx_buffer).unwrap(),
178-
BUFFER_SIZE,
179-
)
180-
.unwrap();
181-
spawner.must_spawn(writer(tx_buffer, tx_descriptors, i2s_tx));
177+
let mut rx_transfer = i2s_rx.read(rx_buffer, BUFFER_SIZE).unwrap();
178+
spawner.must_spawn(writer(tx_buffer, i2s_tx));
182179

183180
let mut sample_idx = 0;
184181
let mut samples = SampleSource::new();

qa-test/src/bin/embassy_i2s_sound.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ async fn main(_spawner: Spawner) {
8787
let data =
8888
unsafe { core::slice::from_raw_parts(&SINE as *const _ as *const u8, SINE.len() * 2) };
8989

90-
let mut buffer = dma_loop_buffer!(64);
90+
let mut buffer = dma_loop_buffer!(128);
9191
buffer.copy_from_slice(data);
9292

9393
println!("Start");

0 commit comments

Comments
 (0)