[2/3] DMA Move API: Move DMA descriptors to peripheral drivers (#1719)

Co-authored-by: Dominic Fischer <git@dominicfischer.me>
This commit is contained in:
Dominic Fischer 2024-06-26 15:31:41 +01:00 committed by GitHub
parent e46e80b8c1
commit 7753551671
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 650 additions and 566 deletions

View File

@ -27,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- esp-hal-embassy: make executor code optional (but default) again
- Improved interrupt latency on RISC-V based chips (#1679)
- `esp_wifi::initialize` no longer requires running maximum CPU clock, instead check it runs above 80MHz. (#1688)
- Move DMA descriptors from DMA Channel to each individual peripheral driver. (#1719)
### Removed
- uart: Removed `configure_pins` methods (#1592)

View File

@ -225,6 +225,8 @@ pub mod dma {
AesPeripheral,
Channel,
ChannelTypes,
DescriptorChain,
DmaDescriptor,
DmaPeripheral,
DmaTransferTxRx,
RxPrivate,
@ -259,6 +261,8 @@ pub mod dma {
pub aes: super::Aes<'d>,
pub(crate) channel: Channel<'d, C, crate::Blocking>,
tx_chain: DescriptorChain,
rx_chain: DescriptorChain,
}
pub trait WithDmaAes<'d, C>
@ -266,7 +270,12 @@ pub mod dma {
C: ChannelTypes,
C::P: AesPeripheral,
{
fn with_dma(self, channel: Channel<'d, C, crate::Blocking>) -> AesDma<'d, C>;
fn with_dma(
self,
channel: Channel<'d, C, crate::Blocking>,
tx_descriptors: &'static mut [DmaDescriptor],
rx_descriptors: &'static mut [DmaDescriptor],
) -> AesDma<'d, C>;
}
impl<'d, C> WithDmaAes<'d, C> for crate::aes::Aes<'d>
@ -274,10 +283,20 @@ pub mod dma {
C: ChannelTypes,
C::P: AesPeripheral,
{
fn with_dma(self, mut channel: Channel<'d, C, crate::Blocking>) -> AesDma<'d, C> {
fn with_dma(
self,
mut channel: Channel<'d, C, crate::Blocking>,
tx_descriptors: &'static mut [DmaDescriptor],
rx_descriptors: &'static mut [DmaDescriptor],
) -> AesDma<'d, C> {
channel.tx.init_channel(); // no need to call this for both, TX and RX
AesDma { aes: self, channel }
AesDma {
aes: self,
channel,
tx_chain: DescriptorChain::new(tx_descriptors),
rx_chain: DescriptorChain::new(rx_descriptors),
}
}
}
@ -321,6 +340,10 @@ pub mod dma {
fn tx(&mut self) -> &mut Self::TX {
&mut self.channel.tx
}
fn chain(&mut self) -> &mut DescriptorChain {
&mut self.tx_chain
}
}
impl<'d, C> DmaSupportRx for AesDma<'d, C>
@ -333,6 +356,10 @@ pub mod dma {
fn rx(&mut self) -> &mut Self::RX {
&mut self.channel.rx
}
fn chain(&mut self) -> &mut DescriptorChain {
&mut self.rx_chain
}
}
impl<'d, C> AesDma<'d, C>
@ -413,24 +440,18 @@ pub mod dma {
self.channel.rx.is_done();
unsafe {
self.tx_chain
.fill_for_tx(false, write_buffer_ptr, write_buffer_len)?;
self.channel
.tx
.prepare_transfer_without_start(
self.dma_peripheral(),
false,
write_buffer_ptr,
write_buffer_len,
)
.prepare_transfer_without_start(self.dma_peripheral(), &self.tx_chain)
.and_then(|_| self.channel.tx.start_transfer())?;
self.rx_chain
.fill_for_rx(false, read_buffer_ptr, read_buffer_len)?;
self.channel
.rx
.prepare_transfer_without_start(
false,
self.dma_peripheral(),
read_buffer_ptr,
read_buffer_len,
)
.prepare_transfer_without_start(self.dma_peripheral(), &self.rx_chain)
.and_then(|_| self.channel.rx.start_transfer())?;
}
self.enable_dma(true);

View File

@ -494,8 +494,6 @@ macro_rules! impl_channel {
pub fn configure<'a>(
self,
burst_mode: bool,
tx_descriptors: &'a mut [DmaDescriptor],
rx_descriptors: &'a mut [DmaDescriptor],
priority: DmaPriority,
) -> crate::dma::Channel<'a, Channel<$num>, crate::Blocking> {
let mut tx_impl = ChannelTxImpl {};
@ -504,12 +502,9 @@ macro_rules! impl_channel {
let mut rx_impl = ChannelRxImpl {};
rx_impl.init(burst_mode, priority);
let tx_chain = DescriptorChain::new(tx_descriptors);
let rx_chain = DescriptorChain::new(rx_descriptors);
crate::dma::Channel {
tx: ChannelTx::new(tx_chain, tx_impl, burst_mode),
rx: ChannelRx::new(rx_chain, rx_impl, burst_mode),
tx: ChannelTx::new(tx_impl, burst_mode),
rx: ChannelRx::new(rx_impl, burst_mode),
phantom: PhantomData,
}
}
@ -522,8 +517,6 @@ macro_rules! impl_channel {
pub fn configure_for_async<'a>(
self,
burst_mode: bool,
tx_descriptors: &'a mut [DmaDescriptor],
rx_descriptors: &'a mut [DmaDescriptor],
priority: DmaPriority,
) -> crate::dma::Channel<'a, Channel<$num>, $crate::Async> {
let mut tx_impl = ChannelTxImpl {};
@ -532,14 +525,11 @@ macro_rules! impl_channel {
let mut rx_impl = ChannelRxImpl {};
rx_impl.init(burst_mode, priority);
let tx_chain = DescriptorChain::new(tx_descriptors);
let rx_chain = DescriptorChain::new(rx_descriptors);
<Channel<$num> as ChannelTypes>::Binder::set_isr($async_handler);
crate::dma::Channel {
tx: ChannelTx::new(tx_chain, tx_impl, burst_mode),
rx: ChannelRx::new(rx_chain, rx_impl, burst_mode),
tx: ChannelTx::new(tx_impl, burst_mode),
rx: ChannelRx::new(rx_impl, burst_mode),
phantom: PhantomData,
}
}

View File

@ -31,17 +31,15 @@
//! let mosi = io.pins.gpio4;
//! let cs = io.pins.gpio5;
//!
//! let (tx_buffer, mut tx_descriptors, rx_buffer, mut rx_descriptors) =
//! let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) =
//! dma_buffers!(32000);
//!
//! let mut spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)
//! .with_pins(Some(sclk), Some(mosi), Some(miso), Some(cs))
//! .with_dma(dma_channel.configure(
//! false,
//! &mut tx_descriptors,
//! &mut rx_descriptors,
//! DmaPriority::Priority0,
//! ));
//! ), tx_descriptors, rx_descriptors);
//! # }
//! ```
//!
@ -143,21 +141,23 @@ const CHUNK_SIZE: usize = 4092;
/// ## Usage
/// ```rust,ignore
/// // TX and RX buffers are 32000 bytes - passing only one parameter makes TX and RX the same size
/// let (tx_buffer, mut tx_descriptors, rx_buffer, mut rx_descriptors) = dma_buffers!(32000, 32000);
/// let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) = dma_buffers!(32000, 32000);
/// ```
#[macro_export]
macro_rules! dma_buffers {
($tx_size:expr, $rx_size:expr) => {{
static mut TX_BUFFER: [u8; $tx_size] = [0u8; $tx_size];
static mut RX_BUFFER: [u8; $rx_size] = [0u8; $rx_size];
let tx_descriptors = [$crate::dma::DmaDescriptor::EMPTY; ($tx_size + 4091) / 4092];
let rx_descriptors = [$crate::dma::DmaDescriptor::EMPTY; ($rx_size + 4091) / 4092];
static mut TX_DESCRIPTORS: [$crate::dma::DmaDescriptor; ($tx_size + 4091) / 4092] =
[$crate::dma::DmaDescriptor::EMPTY; ($tx_size + 4091) / 4092];
static mut RX_DESCRIPTORS: [$crate::dma::DmaDescriptor; ($rx_size + 4091) / 4092] =
[$crate::dma::DmaDescriptor::EMPTY; ($rx_size + 4091) / 4092];
unsafe {
(
&mut TX_BUFFER,
tx_descriptors,
&mut TX_DESCRIPTORS,
&mut RX_BUFFER,
rx_descriptors,
&mut RX_DESCRIPTORS,
)
}
}};
@ -165,14 +165,16 @@ macro_rules! dma_buffers {
($size:expr) => {{
static mut TX_BUFFER: [u8; $size] = [0u8; $size];
static mut RX_BUFFER: [u8; $size] = [0u8; $size];
let tx_descriptors = [$crate::dma::DmaDescriptor::EMPTY; ($size + 4091) / 4092];
let rx_descriptors = [$crate::dma::DmaDescriptor::EMPTY; ($size + 4091) / 4092];
static mut TX_DESCRIPTORS: [$crate::dma::DmaDescriptor; ($size + 4091) / 4092] =
[$crate::dma::DmaDescriptor::EMPTY; ($size + 4091) / 4092];
static mut RX_DESCRIPTORS: [$crate::dma::DmaDescriptor; ($size + 4091) / 4092] =
[$crate::dma::DmaDescriptor::EMPTY; ($size + 4091) / 4092];
unsafe {
(
&mut TX_BUFFER,
tx_descriptors,
&mut TX_DESCRIPTORS,
&mut RX_BUFFER,
rx_descriptors,
&mut RX_DESCRIPTORS,
)
}
}};
@ -183,7 +185,7 @@ macro_rules! dma_buffers {
/// ## Usage
/// ```rust,ignore
/// // TX and RX buffers are 32000 bytes - passing only one parameter makes TX and RX the same size
/// let (tx_buffer, mut tx_descriptors, rx_buffer, mut rx_descriptors) =
/// let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) =
/// dma_circular_buffers!(32000, 32000);
/// ```
#[macro_export]
@ -204,14 +206,16 @@ macro_rules! dma_circular_buffers {
3
};
let tx_descriptors = [$crate::dma::DmaDescriptor::EMPTY; tx_descriptor_len];
let rx_descriptors = [$crate::dma::DmaDescriptor::EMPTY; rx_descriptor_len];
static mut TX_DESCRIPTORS: [$crate::dma::DmaDescriptor; tx_descriptor_len] =
[$crate::dma::DmaDescriptor::EMPTY; tx_descriptor_len];
static mut RX_DESCRIPTORS: [$crate::dma::DmaDescriptor; rx_descriptor_len] =
[$crate::dma::DmaDescriptor::EMPTY; rx_descriptor_len];
unsafe {
(
&mut TX_BUFFER,
tx_descriptors,
&mut TX_DESCRIPTORS,
&mut RX_BUFFER,
rx_descriptors,
&mut RX_DESCRIPTORS,
)
}
}};
@ -226,14 +230,16 @@ macro_rules! dma_circular_buffers {
3
};
let tx_descriptors = [$crate::dma::DmaDescriptor::EMPTY; descriptor_len];
let rx_descriptors = [$crate::dma::DmaDescriptor::EMPTY; descriptor_len];
static mut TX_DESCRIPTORS: [$crate::dma::DmaDescriptor; descriptor_len] =
[$crate::dma::DmaDescriptor::EMPTY; descriptor_len];
static mut RX_DESCRIPTORS: [$crate::dma::DmaDescriptor; descriptor_len] =
[$crate::dma::DmaDescriptor::EMPTY; descriptor_len];
unsafe {
(
&mut TX_BUFFER,
tx_descriptors,
&mut TX_DESCRIPTORS,
&mut RX_BUFFER,
rx_descriptors,
&mut RX_DESCRIPTORS,
)
}
}};
@ -244,20 +250,24 @@ macro_rules! dma_circular_buffers {
/// ## Usage
/// ```rust,ignore
/// // Create TX and RX descriptors for transactions up to 32000 bytes - passing only one parameter assumes TX and RX are the same size
/// let (mut tx_descriptors, mut rx_descriptors) = dma_descriptors!(32000, 32000);
/// let (tx_descriptors, rx_descriptors) = dma_descriptors!(32000, 32000);
/// ```
#[macro_export]
macro_rules! dma_descriptors {
($tx_size:expr, $rx_size:expr) => {{
let tx_descriptors = [$crate::dma::DmaDescriptor::EMPTY; ($tx_size + 4091) / 4092];
let rx_descriptors = [$crate::dma::DmaDescriptor::EMPTY; ($rx_size + 4091) / 4092];
(tx_descriptors, rx_descriptors)
static mut TX_DESCRIPTORS: [$crate::dma::DmaDescriptor; ($tx_size + 4091) / 4092] =
[$crate::dma::DmaDescriptor::EMPTY; ($tx_size + 4091) / 4092];
static mut RX_DESCRIPTORS: [$crate::dma::DmaDescriptor; ($rx_size + 4091) / 4092] =
[$crate::dma::DmaDescriptor::EMPTY; ($rx_size + 4091) / 4092];
unsafe { (&mut TX_DESCRIPTORS, &mut RX_DESCRIPTORS) }
}};
($size:expr) => {{
let tx_descriptors = [$crate::dma::DmaDescriptor::EMPTY; ($size + 4091) / 4092];
let rx_descriptors = [$crate::dma::DmaDescriptor::EMPTY; ($size + 4091) / 4092];
(tx_descriptors, rx_descriptors)
static mut TX_DESCRIPTORS: [$crate::dma::DmaDescriptor; ($size + 4091) / 4092] =
[$crate::dma::DmaDescriptor::EMPTY; ($size + 4091) / 4092];
static mut RX_DESCRIPTORS: [$crate::dma::DmaDescriptor; ($size + 4091) / 4092] =
[$crate::dma::DmaDescriptor::EMPTY; ($size + 4091) / 4092];
unsafe { (&mut TX_DESCRIPTORS, &mut RX_DESCRIPTORS) }
}};
}
@ -266,7 +276,7 @@ macro_rules! dma_descriptors {
/// ## Usage
/// ```rust,ignore
/// // Create TX and RX descriptors for transactions up to 32000 bytes - passing only one parameter assumes TX and RX are the same size
/// let (mut tx_descriptors, mut rx_descriptors) = dma_circular_descriptors!(32000, 32000);
/// let (tx_descriptors, rx_descriptors) = dma_circular_descriptors!(32000, 32000);
/// ```
#[macro_export]
macro_rules! dma_circular_descriptors {
@ -283,9 +293,11 @@ macro_rules! dma_circular_descriptors {
3
};
let tx_descriptors = [$crate::dma::DmaDescriptor::EMPTY; tx_descriptor_len];
let rx_descriptors = [$crate::dma::DmaDescriptor::EMPTY; rx_descriptor_len];
(tx_descriptors, rx_descriptors)
static mut TX_DESCRIPTORS: [$crate::dma::DmaDescriptor; tx_descriptor_len] =
[$crate::dma::DmaDescriptor::EMPTY; tx_descriptor_len];
static mut RX_DESCRIPTORS: [$crate::dma::DmaDescriptor; rx_descriptor_len] =
[$crate::dma::DmaDescriptor::EMPTY; rx_descriptor_len];
unsafe { (&mut TX_DESCRIPTORS, &mut RX_DESCRIPTORS) }
}};
($size:expr) => {{
@ -295,9 +307,11 @@ macro_rules! dma_circular_descriptors {
3
};
let tx_descriptors = [$crate::dma::DmaDescriptor::EMPTY; descriptor_len];
let rx_descriptors = [$crate::dma::DmaDescriptor::EMPTY; descriptor_len];
(tx_descriptors, rx_descriptors)
static mut TX_DESCRIPTORS: [$crate::dma::DmaDescriptor; descriptor_len] =
[$crate::dma::DmaDescriptor::EMPTY; descriptor_len];
static mut RX_DESCRIPTORS: [$crate::dma::DmaDescriptor; descriptor_len] =
[$crate::dma::DmaDescriptor::EMPTY; descriptor_len];
unsafe { (&mut TX_DESCRIPTORS, &mut RX_DESCRIPTORS) }
}};
}
@ -444,12 +458,12 @@ pub trait Tx: TxPrivate {}
pub trait PeripheralMarker {}
#[doc(hidden)]
pub struct DescriptorChain<'a> {
pub(crate) descriptors: &'a mut [DmaDescriptor],
pub struct DescriptorChain {
pub(crate) descriptors: &'static mut [DmaDescriptor],
}
impl<'a> DescriptorChain<'a> {
pub fn new(descriptors: &'a mut [DmaDescriptor]) -> Self {
impl DescriptorChain {
pub fn new(descriptors: &'static mut [DmaDescriptor]) -> Self {
Self { descriptors }
}
@ -621,33 +635,31 @@ impl<'a> DescriptorChain<'a> {
pub(crate) struct TxCircularState {
write_offset: usize,
write_descr_ptr: *mut DmaDescriptor,
available: usize,
pub(crate) available: usize,
last_seen_handled_descriptor_ptr: *mut DmaDescriptor,
buffer_start: *const u8,
buffer_len: usize,
first_desc_ptr: *mut DmaDescriptor,
}
impl TxCircularState {
fn new(
write_descr_ptr: *mut DmaDescriptor,
last_seen_handled_descriptor_ptr: *mut DmaDescriptor,
buffer_start: *const u8,
buffer_len: usize,
) -> Self {
pub(crate) fn new(chain: &mut DescriptorChain) -> Self {
Self {
write_offset: 0,
write_descr_ptr,
write_descr_ptr: chain.first_mut(),
available: 0,
last_seen_handled_descriptor_ptr,
buffer_start,
buffer_len,
last_seen_handled_descriptor_ptr: chain.first_mut(),
buffer_start: chain.descriptors[0].buffer as _,
buffer_len: chain.descriptors.iter().map(|d| d.len()).sum(),
first_desc_ptr: chain.first_mut(),
}
}
fn update<T, R>(&mut self, channel: &T, chain: &mut DescriptorChain)
pub(crate) fn update<T>(&mut self, channel: &T)
where
T: TxChannel<R>,
R: RegisterAccess,
T: TxPrivate,
{
if channel.descriptors_handled() {
channel.reset_descriptors_handled();
@ -664,7 +676,7 @@ impl TxCircularState {
}
} else {
unsafe {
while !((*ptr).next.is_null() || (*ptr).next == chain.first_mut()) {
while !((*ptr).next.is_null() || (*ptr).next == self.first_desc_ptr) {
let dw0 = ptr.read_volatile();
self.available += dw0.len();
ptr = ptr.offset(1);
@ -675,8 +687,8 @@ impl TxCircularState {
self.available += dw0.len();
// in circular mode we need to honor the now available bytes at start
if (*ptr).next == chain.first_mut() {
ptr = chain.first_mut();
if (*ptr).next == self.first_desc_ptr {
ptr = self.first_desc_ptr;
while ptr < descr_address {
let dw0 = ptr.read_volatile();
self.available += dw0.len();
@ -695,7 +707,7 @@ impl TxCircularState {
self.write_offset = (self.write_offset + segment_len) % self.buffer_len;
self.write_descr_ptr = if next_descriptor.is_null() {
chain.first_mut()
self.first_desc_ptr
} else {
next_descriptor
}
@ -706,7 +718,7 @@ impl TxCircularState {
}
}
fn push(&mut self, chain: &mut DescriptorChain, data: &[u8]) -> Result<usize, DmaError> {
pub(crate) fn push(&mut self, data: &[u8]) -> Result<usize, DmaError> {
let avail = self.available;
if avail < data.len() {
@ -716,7 +728,7 @@ impl TxCircularState {
let mut remaining = data.len();
let mut offset = 0;
while self.available >= remaining && remaining > 0 {
let written = self.push_with(chain, |buffer| {
let written = self.push_with(|buffer| {
let len = usize::min(buffer.len(), data.len() - offset);
buffer[..len].copy_from_slice(&data[offset..][..len]);
len
@ -728,9 +740,8 @@ impl TxCircularState {
Ok(data.len())
}
fn push_with(
pub(crate) fn push_with(
&mut self,
chain: &mut DescriptorChain,
f: impl FnOnce(&mut [u8]) -> usize,
) -> Result<usize, DmaError> {
let written = unsafe {
@ -746,7 +757,7 @@ impl TxCircularState {
let dw0 = self.write_descr_ptr.read_volatile();
let segment_len = dw0.len();
self.write_descr_ptr = if dw0.next.is_null() {
chain.first_mut()
self.first_desc_ptr
} else {
dw0.next
};
@ -768,24 +779,26 @@ impl TxCircularState {
pub(crate) struct RxCircularState {
read_descr_ptr: *mut DmaDescriptor,
available: usize,
pub(crate) available: usize,
last_seen_handled_descriptor_ptr: *mut DmaDescriptor,
last_descr_ptr: *mut DmaDescriptor,
}
impl RxCircularState {
fn new(read_descr_ptr: *mut DmaDescriptor) -> Self {
pub(crate) fn new(chain: &mut DescriptorChain) -> Self {
Self {
read_descr_ptr,
read_descr_ptr: chain.first_mut(),
available: 0,
last_seen_handled_descriptor_ptr: core::ptr::null_mut(),
last_descr_ptr: chain.last_mut(),
}
}
fn update(&mut self, chain: &mut DescriptorChain) {
pub(crate) fn update(&mut self) {
if self.last_seen_handled_descriptor_ptr.is_null() {
// initially start at last descriptor (so that next will be the first
// descriptor)
self.last_seen_handled_descriptor_ptr = chain.last_mut();
self.last_seen_handled_descriptor_ptr = self.last_descr_ptr;
}
let mut current_in_descr_ptr =
@ -802,7 +815,7 @@ impl RxCircularState {
}
}
fn pop(&mut self, data: &mut [u8]) -> Result<usize, DmaError> {
pub(crate) fn pop(&mut self, data: &mut [u8]) -> Result<usize, DmaError> {
let len = data.len();
let mut avail = self.available;
@ -847,42 +860,6 @@ impl RxCircularState {
self.available = avail;
Ok(len - remaining_buffer.len())
}
fn drain_buffer(
&mut self,
chain: &DescriptorChain,
mut dst: &mut [u8],
) -> Result<usize, DmaError> {
let mut len = 0;
let mut idx = 0;
loop {
let descriptor = &chain.descriptors[idx];
let chunk_len = dst.len().min(descriptor.len());
if chunk_len == 0 {
break;
}
let buffer_ptr = descriptor.buffer;
let next_dscr = descriptor.next;
// Copy data to destination
let (dst_chunk, dst_remaining) = dst.split_at_mut(chunk_len);
dst = dst_remaining;
dst_chunk
.copy_from_slice(unsafe { core::slice::from_raw_parts(buffer_ptr, chunk_len) });
len += chunk_len;
if next_dscr.is_null() {
break;
}
idx += 3;
}
Ok(len)
}
}
/// The functions here are not meant to be used outside the HAL
@ -894,10 +871,8 @@ pub trait RxPrivate: crate::private::Sealed {
unsafe fn prepare_transfer_without_start(
&mut self,
circular: bool,
peri: DmaPeripheral,
data: *mut u8,
len: usize,
chain: &DescriptorChain,
) -> Result<(), DmaError>;
fn start_transfer(&mut self) -> Result<(), DmaError>;
@ -920,12 +895,6 @@ pub trait RxPrivate: crate::private::Sealed {
fn unlisten_eof(&self);
fn available(&mut self) -> usize;
fn pop(&mut self, data: &mut [u8]) -> Result<usize, DmaError>;
fn drain_buffer(&mut self, dst: &mut [u8]) -> Result<usize, DmaError>;
/// Descriptor error detected
fn has_error(&self) -> bool;
@ -1010,11 +979,9 @@ where
T: RxChannel<R>,
R: RegisterAccess,
{
pub(crate) chain: DescriptorChain<'a>,
pub(crate) burst_mode: bool,
pub(crate) rx_impl: T,
pub(crate) circular_state: Option<RxCircularState>,
pub(crate) _phantom: PhantomData<R>,
pub(crate) _phantom: PhantomData<&'a R>,
}
impl<'a, T, R> ChannelRx<'a, T, R>
@ -1022,12 +989,10 @@ where
T: RxChannel<R>,
R: RegisterAccess,
{
fn new(chain: DescriptorChain<'a>, rx_impl: T, burst_mode: bool) -> Self {
fn new(rx_impl: T, burst_mode: bool) -> Self {
Self {
chain,
burst_mode,
rx_impl,
circular_state: None,
_phantom: PhantomData,
}
}
@ -1058,21 +1023,19 @@ where
unsafe fn prepare_transfer_without_start(
&mut self,
circular: bool,
peri: DmaPeripheral,
data: *mut u8,
len: usize,
chain: &DescriptorChain,
) -> Result<(), DmaError> {
if self.burst_mode && (len % 4 != 0 || data as u32 % 4 != 0) {
if self.burst_mode
&& chain
.descriptors
.iter()
.any(|d| d.len() % 4 != 0 || d.buffer as u32 % 4 != 0)
{
return Err(DmaError::InvalidAlignment);
}
self.chain.fill_for_rx(circular, data, len)?;
self.circular_state = Some(RxCircularState::new(self.chain.first_mut()));
self.rx_impl
.prepare_transfer_without_start(&self.chain, peri)
self.rx_impl.prepare_transfer_without_start(chain, peri)
}
fn start_transfer(&mut self) -> Result<(), DmaError> {
@ -1107,22 +1070,6 @@ where
R::init_channel();
}
fn available(&mut self) -> usize {
let state = self.circular_state.as_mut().unwrap();
state.update(&mut self.chain);
state.available
}
fn pop(&mut self, data: &mut [u8]) -> Result<usize, DmaError> {
let state = self.circular_state.as_mut().unwrap();
state.pop(data)
}
fn drain_buffer(&mut self, dst: &mut [u8]) -> Result<usize, DmaError> {
let state = self.circular_state.as_mut().unwrap();
state.drain_buffer(&self.chain, dst)
}
fn is_listening_eof(&self) -> bool {
R::is_listening_in_eof()
}
@ -1203,9 +1150,7 @@ pub trait TxPrivate: crate::private::Sealed {
unsafe fn prepare_transfer_without_start(
&mut self,
peri: DmaPeripheral,
circular: bool,
data: *const u8,
len: usize,
chain: &DescriptorChain,
) -> Result<(), DmaError>;
fn start_transfer(&mut self) -> Result<(), DmaError>;
@ -1234,18 +1179,18 @@ pub trait TxPrivate: crate::private::Sealed {
fn unlisten_out_descriptor_error(&self);
fn available(&mut self) -> usize;
fn has_error(&self) -> bool;
fn push(&mut self, data: &[u8]) -> Result<usize, DmaError>;
fn push_with(&mut self, f: impl FnOnce(&mut [u8]) -> usize) -> Result<usize, DmaError>;
fn clear_interrupts(&self);
#[cfg(feature = "async")]
fn waker() -> &'static embassy_sync::waitqueue::AtomicWaker;
fn descriptors_handled(&self) -> bool;
fn reset_descriptors_handled(&self);
fn last_out_dscr_address(&self) -> usize;
}
#[doc(hidden)]
@ -1330,12 +1275,10 @@ where
T: TxChannel<R>,
R: RegisterAccess,
{
pub(crate) chain: DescriptorChain<'a>,
#[allow(unused)]
pub(crate) burst_mode: bool,
pub(crate) tx_impl: T,
pub(crate) circular_state: Option<TxCircularState>,
pub(crate) _phantom: PhantomData<R>,
pub(crate) _phantom: PhantomData<(&'a (), R)>,
}
impl<'a, T, R> ChannelTx<'a, T, R>
@ -1343,12 +1286,10 @@ where
T: TxChannel<R>,
R: RegisterAccess,
{
fn new(chain: DescriptorChain<'a>, tx_impl: T, burst_mode: bool) -> Self {
fn new(tx_impl: T, burst_mode: bool) -> Self {
Self {
chain,
burst_mode,
tx_impl,
circular_state: None,
_phantom: PhantomData,
}
}
@ -1384,21 +1325,9 @@ where
unsafe fn prepare_transfer_without_start(
&mut self,
peri: DmaPeripheral,
circular: bool,
data: *const u8,
len: usize,
chain: &DescriptorChain,
) -> Result<(), DmaError> {
self.chain.fill_for_tx(circular, data, len)?;
self.circular_state = Some(TxCircularState::new(
self.chain.first_mut(),
self.chain.first_mut(),
data,
len,
));
self.tx_impl
.prepare_transfer_without_start(&self.chain, peri)
self.tx_impl.prepare_transfer_without_start(chain, peri)
}
fn start_transfer(&mut self) -> Result<(), DmaError> {
@ -1429,24 +1358,6 @@ where
self.tx_impl.is_done()
}
fn available(&mut self) -> usize {
let state = self.circular_state.as_mut().unwrap();
state.update(&self.tx_impl, &mut self.chain);
state.available
}
fn push(&mut self, data: &[u8]) -> Result<usize, DmaError> {
let state = self.circular_state.as_mut().unwrap();
state.update(&self.tx_impl, &mut self.chain);
state.push(&mut self.chain, data)
}
fn push_with(&mut self, f: impl FnOnce(&mut [u8]) -> usize) -> Result<usize, DmaError> {
let state = self.circular_state.as_mut().unwrap();
state.update(&self.tx_impl, &mut self.chain);
state.push_with(&mut self.chain, f)
}
fn is_listening_eof(&self) -> bool {
R::is_listening_out_eof()
}
@ -1483,6 +1394,18 @@ where
fn clear_interrupts(&self) {
R::clear_out_interrupts();
}
fn descriptors_handled(&self) -> bool {
self.tx_impl.descriptors_handled()
}
fn reset_descriptors_handled(&self) {
self.tx_impl.reset_descriptors_handled()
}
fn last_out_dscr_address(&self) -> usize {
self.tx_impl.last_out_dscr_address()
}
}
#[doc(hidden)]
@ -1655,12 +1578,16 @@ pub(crate) mod dma_private {
type TX: Tx;
fn tx(&mut self) -> &mut Self::TX;
fn chain(&mut self) -> &mut DescriptorChain;
}
pub trait DmaSupportRx: DmaSupport {
type RX: Rx;
fn rx(&mut self) -> &mut Self::RX;
fn chain(&mut self) -> &mut DescriptorChain;
}
}
@ -2024,6 +1951,7 @@ where
I: dma_private::DmaSupportTx,
{
instance: &'a mut I,
state: TxCircularState,
}
impl<'a, I> DmaTransferTxCircular<'a, I>
@ -2032,17 +1960,20 @@ where
{
#[allow(unused)] // currently used by peripherals not available on all chips
pub(crate) fn new(instance: &'a mut I) -> Self {
Self { instance }
let state = TxCircularState::new(instance.chain());
Self { instance, state }
}
/// Amount of bytes which can be pushed.
pub fn available(&mut self) -> usize {
self.instance.tx().available()
self.state.update(self.instance.tx());
self.state.available
}
/// Push bytes into the DMA buffer.
pub fn push(&mut self, data: &[u8]) -> Result<usize, DmaError> {
self.instance.tx().push(data)
self.state.update(self.instance.tx());
self.state.push(data)
}
/// Push bytes into the DMA buffer via the given closure.
@ -2050,7 +1981,8 @@ where
/// The closure *might* get called with a slice which is smaller than the
/// total available buffer.
pub fn push_with(&mut self, f: impl FnOnce(&mut [u8]) -> usize) -> Result<usize, DmaError> {
self.instance.tx().push_with(f)
self.state.update(self.instance.tx());
self.state.push_with(f)
}
/// Stop the DMA transfer
@ -2083,6 +2015,7 @@ where
I: dma_private::DmaSupportRx,
{
instance: &'a mut I,
state: RxCircularState,
}
impl<'a, I> DmaTransferRxCircular<'a, I>
@ -2091,7 +2024,8 @@ where
{
#[allow(unused)] // currently used by peripherals not available on all chips
pub(crate) fn new(instance: &'a mut I) -> Self {
Self { instance }
let state = RxCircularState::new(instance.chain());
Self { instance, state }
}
/// Amount of bytes which can be popped.
@ -2099,7 +2033,8 @@ where
/// It's expected to call this before trying to [DmaTransferRxCircular::pop]
/// data.
pub fn available(&mut self) -> usize {
self.instance.rx().available()
self.state.update();
self.state.available
}
/// Get available data.
@ -2111,7 +2046,8 @@ where
/// Fails with [DmaError::BufferTooSmall] if the given buffer is too small
/// to hold all available data
pub fn pop(&mut self, data: &mut [u8]) -> Result<usize, DmaError> {
self.instance.rx().pop(data)
self.state.update();
self.state.pop(data)
}
}

View File

@ -387,8 +387,6 @@ macro_rules! ImplSpiChannel {
pub fn configure<'a>(
self,
burst_mode: bool,
tx_descriptors: &'a mut [DmaDescriptor],
rx_descriptors: &'a mut [DmaDescriptor],
priority: DmaPriority,
) -> Channel<'a, [<Spi $num DmaChannel>], $crate::Blocking> {
let mut tx_impl = [<Spi $num DmaChannelTxImpl>] {};
@ -397,12 +395,9 @@ macro_rules! ImplSpiChannel {
let mut rx_impl = [<Spi $num DmaChannelRxImpl>] {};
rx_impl.init(burst_mode, priority);
let tx_chain = DescriptorChain::new(tx_descriptors);
let rx_chain = DescriptorChain::new(rx_descriptors);
Channel {
tx: ChannelTx::new(tx_chain, tx_impl, burst_mode),
rx: ChannelRx::new(rx_chain, rx_impl, burst_mode),
tx: ChannelTx::new(tx_impl, burst_mode),
rx: ChannelRx::new(rx_impl, burst_mode),
phantom: PhantomData,
}
}
@ -415,8 +410,6 @@ macro_rules! ImplSpiChannel {
pub fn configure_for_async<'a>(
self,
burst_mode: bool,
tx_descriptors: &'a mut [DmaDescriptor],
rx_descriptors: &'a mut [DmaDescriptor],
priority: DmaPriority,
) -> Channel<'a, [<Spi $num DmaChannel>], $crate::Async> {
let mut tx_impl = [<Spi $num DmaChannelTxImpl>] {};
@ -425,14 +418,11 @@ macro_rules! ImplSpiChannel {
let mut rx_impl = [<Spi $num DmaChannelRxImpl>] {};
rx_impl.init(burst_mode, priority);
let tx_chain = DescriptorChain::new(tx_descriptors);
let rx_chain = DescriptorChain::new(rx_descriptors);
<[<Spi $num DmaChannel>] as ChannelTypes>::Binder::set_isr(super::asynch::interrupt::[< interrupt_handler_spi $num _dma >]);
Channel {
tx: ChannelTx::new(tx_chain, tx_impl, burst_mode),
rx: ChannelRx::new(rx_chain, rx_impl, burst_mode),
tx: ChannelTx::new(tx_impl, burst_mode),
rx: ChannelRx::new(rx_impl, burst_mode),
phantom: PhantomData,
}
}
@ -787,8 +777,6 @@ macro_rules! ImplI2sChannel {
pub fn configure<'a>(
self,
burst_mode: bool,
tx_descriptors: &'a mut [DmaDescriptor],
rx_descriptors: &'a mut [DmaDescriptor],
priority: DmaPriority,
) -> Channel<'a, [<I2s $num DmaChannel>], $crate::Blocking> {
let mut tx_impl = [<I2s $num DmaChannelTxImpl>] {};
@ -797,12 +785,9 @@ macro_rules! ImplI2sChannel {
let mut rx_impl = [<I2s $num DmaChannelRxImpl>] {};
rx_impl.init(burst_mode, priority);
let tx_chain = DescriptorChain::new(tx_descriptors);
let rx_chain = DescriptorChain::new(rx_descriptors);
Channel {
tx: ChannelTx::new(tx_chain, tx_impl, burst_mode),
rx: ChannelRx::new(rx_chain, rx_impl, burst_mode),
tx: ChannelTx::new(tx_impl, burst_mode),
rx: ChannelRx::new(rx_impl, burst_mode),
phantom: PhantomData,
}
}
@ -815,8 +800,6 @@ macro_rules! ImplI2sChannel {
pub fn configure_for_async<'a>(
self,
burst_mode: bool,
tx_descriptors: &'a mut [DmaDescriptor],
rx_descriptors: &'a mut [DmaDescriptor],
priority: DmaPriority,
) -> Channel<'a, [<I2s $num DmaChannel>], $crate::Async> {
let mut tx_impl = [<I2s $num DmaChannelTxImpl>] {};
@ -825,14 +808,11 @@ macro_rules! ImplI2sChannel {
let mut rx_impl = [<I2s $num DmaChannelRxImpl>] {};
rx_impl.init(burst_mode, priority);
let tx_chain = DescriptorChain::new(tx_descriptors);
let rx_chain = DescriptorChain::new(rx_descriptors);
<[<I2s $num DmaChannel>] as ChannelTypes>::Binder::set_isr(super::asynch::interrupt::[< interrupt_handler_i2s $num >]);
Channel {
tx: ChannelTx::new(tx_chain, tx_impl, burst_mode),
rx: ChannelRx::new(rx_chain, rx_impl, burst_mode),
tx: ChannelTx::new(tx_impl, burst_mode),
rx: ChannelRx::new(rx_impl, burst_mode),
phantom: PhantomData,
}
}

View File

@ -38,7 +38,7 @@
//! let dma = Dma::new(peripherals.DMA);
#![cfg_attr(any(esp32, esp32s2), doc = "let dma_channel = dma.i2s0channel;")]
#![cfg_attr(not(any(esp32, esp32s2)), doc = "let dma_channel = dma.channel0;")]
//! let (_, mut tx_descriptors, mut rx_buffer, mut rx_descriptors) =
//! let (_, tx_descriptors, mut rx_buffer, rx_descriptors) =
//! dma_buffers!(0, 4 * 4092);
//!
//! let i2s = I2s::new(
@ -48,10 +48,10 @@
//! 44100.Hz(),
//! dma_channel.configure(
//! false,
//! &mut tx_descriptors,
//! &mut rx_descriptors,
//! DmaPriority::Priority0,
//! ),
//! tx_descriptors,
//! rx_descriptors,
//! &clocks,
//! );
#![cfg_attr(not(esp32), doc = "let i2s = i2s.with_mclk(io.pins.gpio0);")]
@ -88,6 +88,8 @@ use crate::{
dma_private::{DmaSupport, DmaSupportRx, DmaSupportTx},
Channel,
ChannelTypes,
DescriptorChain,
DmaDescriptor,
DmaError,
DmaTransferRx,
DmaTransferRxCircular,
@ -302,12 +304,15 @@ where
CH: ChannelTypes,
DmaMode: Mode,
{
#[allow(clippy::too_many_arguments)]
fn new_internal(
_i2s: impl Peripheral<P = I> + 'd,
standard: Standard,
data_format: DataFormat,
sample_rate: impl Into<fugit::HertzU32>,
mut channel: Channel<'d, CH, DmaMode>,
tx_descriptors: &'static mut [DmaDescriptor],
rx_descriptors: &'static mut [DmaDescriptor],
clocks: &Clocks,
) -> Self {
// on ESP32-C3 / ESP32-S3 and later RX and TX are independent and
@ -330,11 +335,13 @@ where
i2s_tx: TxCreator {
register_access: PhantomData,
tx_channel: channel.tx,
descriptors: tx_descriptors,
phantom: PhantomData,
},
i2s_rx: RxCreator {
register_access: PhantomData,
rx_channel: channel.rx,
descriptors: rx_descriptors,
phantom: PhantomData,
},
phantom: PhantomData,
@ -385,12 +392,15 @@ where
{
/// Construct a new I2S peripheral driver instance for the first I2S
/// peripheral
#[allow(clippy::too_many_arguments)]
pub fn new(
i2s: impl Peripheral<P = I> + 'd,
standard: Standard,
data_format: DataFormat,
sample_rate: impl Into<fugit::HertzU32>,
channel: Channel<'d, CH, DmaMode>,
tx_descriptors: &'static mut [DmaDescriptor],
rx_descriptors: &'static mut [DmaDescriptor],
clocks: &Clocks,
) -> Self
where
@ -398,11 +408,21 @@ where
CH::P: I2sPeripheral + I2s0Peripheral,
DmaMode: Mode,
{
Self::new_internal(i2s, standard, data_format, sample_rate, channel, clocks)
Self::new_internal(
i2s,
standard,
data_format,
sample_rate,
channel,
tx_descriptors,
rx_descriptors,
clocks,
)
}
/// Construct a new I2S peripheral driver instance for the second I2S
/// peripheral
#[allow(clippy::too_many_arguments)]
#[cfg(any(esp32s3, esp32))]
pub fn new_i2s1(
i2s: impl Peripheral<P = I> + 'd,
@ -410,13 +430,24 @@ where
data_format: DataFormat,
sample_rate: impl Into<fugit::HertzU32>,
channel: Channel<'d, CH, DmaMode>,
tx_descriptors: &'static mut [DmaDescriptor],
rx_descriptors: &'static mut [DmaDescriptor],
clocks: &Clocks,
) -> Self
where
I: I2s1Instance,
CH::P: I2sPeripheral + I2s1Peripheral,
{
Self::new_internal(i2s, standard, data_format, sample_rate, channel, clocks)
Self::new_internal(
i2s,
standard,
data_format,
sample_rate,
channel,
tx_descriptors,
rx_descriptors,
clocks,
)
}
pub fn with_mclk<P: OutputPin>(self, pin: impl Peripheral<P = P> + 'd) -> Self {
@ -435,6 +466,7 @@ where
{
register_access: PhantomData<T>,
tx_channel: CH::Tx<'d>,
tx_chain: DescriptorChain,
phantom: PhantomData<DmaMode>,
}
@ -475,6 +507,10 @@ where
fn tx(&mut self) -> &mut Self::TX {
&mut self.tx_channel
}
fn chain(&mut self) -> &mut DescriptorChain {
&mut self.tx_chain
}
}
impl<'d, T, CH, DmaMode> I2sTx<'d, T, CH, DmaMode>
@ -483,10 +519,11 @@ where
CH: ChannelTypes,
DmaMode: Mode,
{
fn new(tx_channel: CH::Tx<'d>) -> Self {
fn new(tx_channel: CH::Tx<'d>, descriptors: &'static mut [DmaDescriptor]) -> Self {
Self {
register_access: PhantomData,
tx_channel,
tx_chain: DescriptorChain::new(descriptors),
phantom: PhantomData,
}
}
@ -501,8 +538,9 @@ where
// configure DMA outlink
unsafe {
self.tx_chain.fill_for_tx(false, ptr, data.len())?;
self.tx_channel
.prepare_transfer_without_start(T::get_dma_peripheral(), false, ptr, data.len())
.prepare_transfer_without_start(T::get_dma_peripheral(), &self.tx_chain)
.and_then(|_| self.tx_channel.start_transfer())?;
}
@ -535,8 +573,9 @@ where
// configure DMA outlink
unsafe {
self.tx_chain.fill_for_tx(circular, ptr, len)?;
self.tx_channel
.prepare_transfer_without_start(T::get_dma_peripheral(), circular, ptr, len)
.prepare_transfer_without_start(T::get_dma_peripheral(), &self.tx_chain)
.and_then(|_| self.tx_channel.start_transfer())?;
}
@ -608,6 +647,7 @@ where
{
register_access: PhantomData<T>,
rx_channel: CH::Rx<'d>,
rx_chain: DescriptorChain,
phantom: PhantomData<DmaMode>,
}
@ -648,6 +688,10 @@ where
fn rx(&mut self) -> &mut Self::RX {
&mut self.rx_channel
}
fn chain(&mut self) -> &mut DescriptorChain {
&mut self.rx_chain
}
}
impl<'d, T, CH, DmaMode> I2sRx<'d, T, CH, DmaMode>
@ -656,10 +700,11 @@ where
CH: ChannelTypes,
DmaMode: Mode,
{
fn new(rx_channel: CH::Rx<'d>) -> Self {
fn new(rx_channel: CH::Rx<'d>, descriptors: &'static mut [DmaDescriptor]) -> Self {
Self {
register_access: PhantomData,
rx_channel,
rx_chain: DescriptorChain::new(descriptors),
phantom: PhantomData,
}
}
@ -674,8 +719,9 @@ where
// configure DMA outlink
unsafe {
self.rx_chain.fill_for_rx(false, ptr, data.len())?;
self.rx_channel
.prepare_transfer_without_start(false, T::get_dma_peripheral(), ptr, data.len())
.prepare_transfer_without_start(T::get_dma_peripheral(), &self.rx_chain)
.and_then(|_| self.rx_channel.start_transfer())?;
}
@ -711,8 +757,9 @@ where
// configure DMA outlink
unsafe {
self.rx_chain.fill_for_rx(circular, ptr, len)?;
self.rx_channel
.prepare_transfer_without_start(circular, T::get_dma_peripheral(), ptr, len)
.prepare_transfer_without_start(T::get_dma_peripheral(), &self.rx_chain)
.and_then(|_| self.rx_channel.start_transfer())?;
}
@ -797,7 +844,7 @@ mod private {
use crate::peripherals::{i2s1::RegisterBlock, I2S1};
use crate::{
clock::Clocks,
dma::{ChannelTypes, DmaPeripheral},
dma::{ChannelTypes, DmaDescriptor, DmaPeripheral},
gpio::{InputPin, InputSignal, OutputPin, OutputSignal},
interrupt::InterruptHandler,
into_ref,
@ -815,6 +862,7 @@ mod private {
{
pub register_access: PhantomData<T>,
pub tx_channel: CH::Tx<'d>,
pub descriptors: &'static mut [DmaDescriptor],
pub(crate) phantom: PhantomData<DmaMode>,
}
@ -825,7 +873,7 @@ mod private {
DmaMode: Mode,
{
pub fn build(self) -> I2sTx<'d, T, CH, DmaMode> {
I2sTx::new(self.tx_channel)
I2sTx::new(self.tx_channel, self.descriptors)
}
pub fn with_bclk<P>(self, pin: impl crate::peripheral::Peripheral<P = P> + 'd) -> Self
@ -867,6 +915,7 @@ mod private {
{
pub register_access: PhantomData<T>,
pub rx_channel: CH::Rx<'d>,
pub descriptors: &'static mut [DmaDescriptor],
pub(crate) phantom: PhantomData<DmaMode>,
}
@ -877,7 +926,7 @@ mod private {
DmaMode: Mode,
{
pub fn build(self) -> I2sRx<'d, T, CH, DmaMode> {
I2sRx::new(self.rx_channel)
I2sRx::new(self.rx_channel, self.descriptors)
}
pub fn with_bclk<P>(self, pin: impl crate::peripheral::Peripheral<P = P> + 'd) -> Self
@ -2082,7 +2131,9 @@ pub mod asynch {
dma::{
asynch::{DmaRxDoneChFuture, DmaRxFuture, DmaTxDoneChFuture, DmaTxFuture},
ChannelTypes,
RxCircularState,
RxPrivate,
TxCircularState,
TxPrivate,
},
Async,
@ -2119,12 +2170,10 @@ pub mod asynch {
let future = DmaTxFuture::new(&mut self.tx_channel);
unsafe {
future.tx.prepare_transfer_without_start(
T::get_dma_peripheral(),
false,
ptr,
len,
)?;
self.tx_chain.fill_for_tx(false, ptr, len)?;
future
.tx
.prepare_transfer_without_start(T::get_dma_peripheral(), &self.tx_chain)?;
}
future.tx.start_transfer()?;
@ -2150,8 +2199,9 @@ pub mod asynch {
// configure DMA outlink
unsafe {
self.tx_chain.fill_for_tx(true, ptr, len)?;
self.tx_channel
.prepare_transfer_without_start(T::get_dma_peripheral(), true, ptr, len)
.prepare_transfer_without_start(T::get_dma_peripheral(), &self.tx_chain)
.and_then(|_| self.tx_channel.start_transfer())?;
}
@ -2160,8 +2210,10 @@ pub mod asynch {
// start: set I2S_TX_START
T::tx_start();
let state = TxCircularState::new(&mut self.tx_chain);
Ok(I2sWriteDmaTransferAsync {
i2s_tx: self,
state,
_buffer: words,
})
}
@ -2176,6 +2228,7 @@ pub mod asynch {
CH: ChannelTypes,
{
i2s_tx: I2sTx<'d, T, CH, Async>,
state: TxCircularState,
_buffer: BUFFER,
}
@ -2188,7 +2241,8 @@ pub mod asynch {
/// Will wait for more than 0 bytes available.
pub async fn available(&mut self) -> Result<usize, Error> {
loop {
let res = self.i2s_tx.tx_channel.available();
self.state.update(&mut self.i2s_tx.tx_channel);
let res = self.state.available;
if res != 0 {
break Ok(res);
@ -2202,7 +2256,7 @@ pub mod asynch {
pub async fn push(&mut self, data: &[u8]) -> Result<usize, Error> {
let avail = self.available().await?;
let to_send = usize::min(avail, data.len());
Ok(self.i2s_tx.tx_channel.push(&data[..to_send])?)
Ok(self.state.push(&data[..to_send])?)
}
/// Push bytes into the DMA buffer via the given closure.
@ -2215,7 +2269,7 @@ pub mod asynch {
f: impl FnOnce(&mut [u8]) -> usize,
) -> Result<usize, Error> {
let _avail = self.available().await;
Ok(self.i2s_tx.tx_channel.push_with(f)?)
Ok(self.state.push_with(f)?)
}
}
@ -2256,12 +2310,10 @@ pub mod asynch {
// configure DMA outlink
unsafe {
future.rx().prepare_transfer_without_start(
false,
T::get_dma_peripheral(),
ptr,
len,
)?;
self.rx_chain.fill_for_rx(false, ptr, len)?;
future
.rx()
.prepare_transfer_without_start(T::get_dma_peripheral(), &self.rx_chain)?;
}
future.rx().start_transfer()?;
@ -2299,8 +2351,9 @@ pub mod asynch {
// configure DMA outlink
unsafe {
self.rx_chain.fill_for_rx(true, ptr, len)?;
self.rx_channel
.prepare_transfer_without_start(true, T::get_dma_peripheral(), ptr, len)
.prepare_transfer_without_start(T::get_dma_peripheral(), &self.rx_chain)
.and_then(|_| self.rx_channel.start_transfer())?;
}
@ -2313,8 +2366,10 @@ pub mod asynch {
#[cfg(esp32)]
T::rx_start(len);
let state = RxCircularState::new(&mut self.rx_chain);
Ok(I2sReadDmaTransferAsync {
i2s_rx: self,
state,
_buffer: words,
})
}
@ -2329,6 +2384,7 @@ pub mod asynch {
CH: ChannelTypes,
{
i2s_rx: I2sRx<'d, T, CH, Async>,
state: RxCircularState,
_buffer: BUFFER,
}
@ -2341,7 +2397,9 @@ pub mod asynch {
/// Will wait for more than 0 bytes available.
pub async fn available(&mut self) -> Result<usize, Error> {
loop {
let res = self.i2s_rx.rx_channel.available();
self.state.update();
let res = self.state.available;
if res != 0 {
break Ok(res);
@ -2355,7 +2413,7 @@ pub mod asynch {
pub async fn pop(&mut self, data: &mut [u8]) -> Result<usize, Error> {
let avail = self.available().await?;
let to_rcv = usize::min(avail, data.len());
Ok(self.i2s_rx.rx_channel.pop(&mut data[..to_rcv])?)
Ok(self.state.pop(&mut data[..to_rcv])?)
}
}
}

View File

@ -24,12 +24,10 @@
//! # let dma = Dma::new(peripherals.DMA);
//! # let channel = dma.channel0;
//!
//! # let (tx_buffer, mut tx_descriptors, _, mut rx_descriptors) = dma_buffers!(32678, 0);
//! # let (tx_buffer, tx_descriptors, _, rx_descriptors) = dma_buffers!(32678, 0);
//!
//! # let channel = channel.configure(
//! # false,
//! # &mut tx_descriptors,
//! # &mut rx_descriptors,
//! # DmaPriority::Priority0,
//! # );
//!
@ -49,10 +47,17 @@
//! );
//!
//! let lcd_cam = LcdCam::new(peripherals.LCD_CAM);
//! let mut camera =
//! Camera::new(lcd_cam.cam, channel.rx, data_pins, 20u32.MHz(), &clocks)
//! .with_master_clock(mclk_pin) // Remove this for slave mode.
//! .with_ctrl_pins(vsync_pin, href_pin, pclk_pin);
//! let mut camera = Camera::new(
//! lcd_cam.cam,
//! channel.rx,
//! rx_descriptors,
//! data_pins,
//! 20u32.MHz(),
//! &clocks
//! )
//! // Remove this for slave mode.
//! .with_master_clock(mclk_pin)
//! .with_ctrl_pins(vsync_pin, href_pin, pclk_pin);
//! # }
//! ```
@ -67,6 +72,8 @@ use crate::{
dma_private::{DmaSupport, DmaSupportRx},
ChannelRx,
ChannelTypes,
DescriptorChain,
DmaDescriptor,
DmaError,
DmaPeripheral,
DmaTransferRx,
@ -114,6 +121,7 @@ pub struct Cam<'d> {
pub struct Camera<'d, RX> {
lcd_cam: PeripheralRef<'d, LCD_CAM>,
rx_channel: RX,
rx_chain: DescriptorChain,
// 1 or 2
bus_width: usize,
}
@ -127,6 +135,7 @@ where
pub fn new<P: RxPins>(
cam: Cam<'d>,
mut channel: ChannelRx<'d, T, R>,
descriptors: &'static mut [DmaDescriptor],
_pins: P,
frequency: HertzU32,
clocks: &Clocks,
@ -195,6 +204,7 @@ where
Self {
lcd_cam,
rx_channel: channel,
rx_chain: DescriptorChain::new(descriptors),
bus_width: P::BUS_WIDTH,
}
}
@ -223,6 +233,10 @@ impl<'d, RX: Rx> DmaSupportRx for Camera<'d, RX> {
fn rx(&mut self) -> &mut Self::RX {
&mut self.rx_channel
}
fn chain(&mut self) -> &mut DescriptorChain {
&mut self.rx_chain
}
}
impl<'d, RX: Rx> Camera<'d, RX> {
@ -330,12 +344,10 @@ impl<'d, RX: Rx> Camera<'d, RX> {
assert_eq!(self.bus_width, size_of::<RXBUF::Word>());
unsafe {
self.rx_channel.prepare_transfer_without_start(
circular,
DmaPeripheral::LcdCam,
ptr as _,
len * size_of::<RXBUF::Word>(),
)?;
self.rx_chain
.fill_for_rx(circular, ptr as _, len * size_of::<RXBUF::Word>())?;
self.rx_channel
.prepare_transfer_without_start(DmaPeripheral::LcdCam, &self.rx_chain)?;
}
self.rx_channel.start_transfer()
}

View File

@ -22,12 +22,10 @@
//! # let dma = Dma::new(peripherals.DMA);
//! # let channel = dma.channel0;
//!
//! # let (tx_buffer, mut tx_descriptors, _, mut rx_descriptors) = dma_buffers!(32678, 0);
//! # let (tx_buffer, tx_descriptors, _, rx_descriptors) = dma_buffers!(32678, 0);
//!
//! # let channel = channel.configure(
//! # false,
//! # &mut tx_descriptors,
//! # &mut rx_descriptors,
//! # DmaPriority::Priority0,
//! # );
//!
@ -46,6 +44,7 @@
//! let mut i8080 = I8080::new(
//! lcd_cam.lcd,
//! channel.tx,
//! tx_descriptors,
//! tx_pins,
//! 20.MHz(),
//! Config::default(),
@ -68,6 +67,8 @@ use crate::{
dma_private::{DmaSupport, DmaSupportTx},
ChannelTx,
ChannelTypes,
DescriptorChain,
DmaDescriptor,
DmaError,
DmaPeripheral,
DmaTransferTx,
@ -92,6 +93,7 @@ use crate::{
pub struct I8080<'d, TX, P> {
lcd_cam: PeripheralRef<'d, LCD_CAM>,
tx_channel: TX,
tx_chain: DescriptorChain,
_pins: P,
}
@ -105,6 +107,7 @@ where
pub fn new(
lcd: Lcd<'d>,
mut channel: ChannelTx<'d, T, R>,
descriptors: &'static mut [DmaDescriptor],
mut pins: P,
frequency: HertzU32,
config: Config,
@ -248,6 +251,7 @@ where
Self {
lcd_cam,
tx_channel: channel,
tx_chain: DescriptorChain::new(descriptors),
_pins: pins,
}
}
@ -272,6 +276,10 @@ impl<'d, TX: Tx, P: TxPins> DmaSupportTx for I8080<'d, TX, P> {
fn tx(&mut self) -> &mut Self::TX {
&mut self.tx_channel
}
fn chain(&mut self) -> &mut DescriptorChain {
&mut self.tx_chain
}
}
impl<'d, TX: Tx, P: TxPins> I8080<'d, TX, P>
@ -462,12 +470,9 @@ impl<'d, TX: Tx, P> I8080<'d, TX, P> {
});
unsafe {
self.tx_channel.prepare_transfer_without_start(
DmaPeripheral::LcdCam,
false,
ptr,
len,
)?;
self.tx_chain.fill_for_tx(false, ptr, len)?;
self.tx_channel
.prepare_transfer_without_start(DmaPeripheral::LcdCam, &self.tx_chain)?;
}
self.tx_channel.start_transfer()?;
}

View File

@ -25,8 +25,8 @@
//! # let dma = Dma::new(peripherals.DMA);
//! # let dma_channel = dma.channel0;
//!
//! let (tx_buffer, mut tx_descriptors, _, mut rx_descriptors) =
//! dma_buffers!(32000, 0); let buffer = tx_buffer;
//! let (tx_buffer, tx_descriptors, _, _) = dma_buffers!(32000, 0);
//! let buffer = tx_buffer;
//!
//! // configure the data pins to use
//! let tx_pins = TxFourBits::new(io.pins.gpio1, io.pins.gpio2, io.pins.gpio3,
@ -39,10 +39,9 @@
//! peripherals.PARL_IO,
//! dma_channel.configure(
//! false,
//! &mut tx_descriptors,
//! &mut rx_descriptors,
//! DmaPriority::Priority0,
//! ),
//! tx_descriptors,
//! 1.MHz(),
//! &clocks,
//! )
@ -85,17 +84,16 @@
//! let mut rx_pins = RxFourBits::new(io.pins.gpio1, io.pins.gpio2,
//! io.pins.gpio3, io.pins.gpio4);
//!
//! let (_, mut tx_descriptors, rx_buffer, mut rx_descriptors) = dma_buffers!(0,
//! 32000); let mut buffer = rx_buffer;
//! let (_, _, rx_buffer, rx_descriptors) = dma_buffers!(0, 32000);
//! let mut buffer = rx_buffer;
//!
//! let parl_io = ParlIoRxOnly::new(
//! peripherals.PARL_IO,
//! dma_channel.configure(
//! false,
//! &mut tx_descriptors,
//! &mut rx_descriptors,
//! DmaPriority::Priority0,
//! ),
//! rx_descriptors,
//! 1.MHz(),
//! &clocks,
//! )
@ -127,6 +125,8 @@ use crate::{
dma_private::{DmaSupport, DmaSupportRx, DmaSupportTx},
Channel,
ChannelTypes,
DescriptorChain,
DmaDescriptor,
DmaError,
DmaPeripheral,
DmaTransferRx,
@ -944,6 +944,7 @@ where
Ok(ParlIoTx {
tx_channel: self.tx_channel,
tx_chain: DescriptorChain::new(self.descriptors),
phantom: PhantomData,
})
}
@ -976,6 +977,7 @@ where
Ok(ParlIoTx {
tx_channel: self.tx_channel,
tx_chain: DescriptorChain::new(self.descriptors),
phantom: PhantomData,
})
}
@ -988,6 +990,7 @@ where
DM: Mode,
{
tx_channel: CH::Tx<'d>,
tx_chain: DescriptorChain,
phantom: PhantomData<DM>,
}
@ -1026,6 +1029,7 @@ where
Ok(ParlIoRx {
rx_channel: self.rx_channel,
rx_chain: DescriptorChain::new(self.descriptors),
phantom: PhantomData,
})
}
@ -1056,6 +1060,7 @@ where
Ok(ParlIoRx {
rx_channel: self.rx_channel,
rx_chain: DescriptorChain::new(self.descriptors),
phantom: PhantomData,
})
}
@ -1068,6 +1073,7 @@ where
DM: Mode,
{
rx_channel: CH::Rx<'d>,
rx_chain: DescriptorChain,
phantom: PhantomData<DM>,
}
@ -1195,6 +1201,8 @@ where
pub fn new(
_parl_io: impl Peripheral<P = peripherals::PARL_IO> + 'd,
mut dma_channel: Channel<'d, CH, DM>,
tx_descriptors: &'static mut [DmaDescriptor],
rx_descriptors: &'static mut [DmaDescriptor],
frequency: HertzU32,
_clocks: &Clocks,
) -> Result<Self, Error> {
@ -1203,10 +1211,12 @@ where
Ok(Self {
tx: TxCreatorFullDuplex {
tx_channel: dma_channel.tx,
descriptors: tx_descriptors,
phantom: PhantomData,
},
rx: RxCreatorFullDuplex {
rx_channel: dma_channel.rx,
descriptors: rx_descriptors,
phantom: PhantomData,
},
})
@ -1268,6 +1278,7 @@ where
pub fn new(
_parl_io: impl Peripheral<P = peripherals::PARL_IO> + 'd,
mut dma_channel: Channel<'d, CH, DM>,
descriptors: &'static mut [DmaDescriptor],
frequency: HertzU32,
_clocks: &Clocks,
) -> Result<Self, Error> {
@ -1276,6 +1287,7 @@ where
Ok(Self {
tx: TxCreator {
tx_channel: dma_channel.tx,
descriptors,
phantom: PhantomData,
},
})
@ -1337,6 +1349,7 @@ where
pub fn new(
_parl_io: impl Peripheral<P = peripherals::PARL_IO> + 'd,
mut dma_channel: Channel<'d, CH, DM>,
descriptors: &'static mut [DmaDescriptor],
frequency: HertzU32,
_clocks: &Clocks,
) -> Result<Self, Error> {
@ -1345,6 +1358,7 @@ where
Ok(Self {
rx: RxCreator {
rx_channel: dma_channel.rx,
descriptors,
phantom: PhantomData,
},
})
@ -1475,8 +1489,9 @@ where
self.tx_channel.is_done();
unsafe {
self.tx_chain.fill_for_tx(false, ptr, len)?;
self.tx_channel
.prepare_transfer_without_start(DmaPeripheral::ParlIo, false, ptr, len)
.prepare_transfer_without_start(DmaPeripheral::ParlIo, &self.tx_chain)
.and_then(|_| self.tx_channel.start_transfer())?;
}
@ -1519,6 +1534,10 @@ where
fn tx(&mut self) -> &mut Self::TX {
&mut self.tx_channel
}
fn chain(&mut self) -> &mut DescriptorChain {
&mut self.tx_chain
}
}
impl<'d, CH, DM> ParlIoRx<'d, CH, DM>
@ -1548,13 +1567,14 @@ where
return Err(Error::MaxDmaTransferSizeExceeded);
}
Self::start_receive_bytes_dma(&mut self.rx_channel, ptr, len)?;
Self::start_receive_bytes_dma(&mut self.rx_channel, &mut self.rx_chain, ptr, len)?;
Ok(DmaTransferRx::new(self))
}
fn start_receive_bytes_dma(
rx_channel: &mut CH::Rx<'d>,
rx_chain: &mut DescriptorChain,
ptr: *mut u8,
len: usize,
) -> Result<(), Error> {
@ -1568,8 +1588,9 @@ where
Instance::set_rx_bytes(len as u16);
unsafe {
rx_chain.fill_for_rx(false, ptr, len)?;
rx_channel
.prepare_transfer_without_start(false, DmaPeripheral::ParlIo, ptr, len)
.prepare_transfer_without_start(DmaPeripheral::ParlIo, rx_chain)
.and_then(|_| rx_channel.start_transfer())?;
}
@ -1615,6 +1636,10 @@ where
fn rx(&mut self) -> &mut Self::RX {
&mut self.rx_channel
}
fn chain(&mut self) -> &mut DescriptorChain {
&mut self.rx_chain
}
}
/// Creates a TX channel
@ -1624,6 +1649,7 @@ where
DM: Mode,
{
tx_channel: CH::Tx<'d>,
descriptors: &'static mut [DmaDescriptor],
phantom: PhantomData<DM>,
}
@ -1634,6 +1660,7 @@ where
DM: Mode,
{
rx_channel: CH::Rx<'d>,
descriptors: &'static mut [DmaDescriptor],
phantom: PhantomData<DM>,
}
@ -1644,6 +1671,7 @@ where
DM: Mode,
{
tx_channel: CH::Tx<'d>,
descriptors: &'static mut [DmaDescriptor],
phantom: PhantomData<DM>,
}
@ -1654,6 +1682,7 @@ where
DM: Mode,
{
rx_channel: CH::Rx<'d>,
descriptors: &'static mut [DmaDescriptor],
phantom: PhantomData<DM>,
}
@ -1762,7 +1791,7 @@ pub mod asynch {
}
let future = DmaRxDoneChFuture::new(&mut self.rx_channel);
Self::start_receive_bytes_dma(future.rx, ptr, len)?;
Self::start_receive_bytes_dma(future.rx, &mut self.rx_chain, ptr, len)?;
future.await?;
Ok(())

View File

@ -75,7 +75,7 @@ use super::{
};
use crate::{
clock::Clocks,
dma::{DmaPeripheral, Rx, Tx},
dma::{DescriptorChain, DmaPeripheral, Rx, Tx},
gpio::{InputPin, InputSignal, OutputPin, OutputSignal},
interrupt::InterruptHandler,
peripheral::{Peripheral, PeripheralRef},
@ -845,6 +845,8 @@ pub mod dma {
dma_private::{DmaSupport, DmaSupportRx, DmaSupportTx},
Channel,
ChannelTypes,
DescriptorChain,
DmaDescriptor,
DmaTransferRx,
DmaTransferRxOwned,
DmaTransferTx,
@ -868,6 +870,8 @@ pub mod dma {
fn with_dma(
self,
channel: Channel<'d, C, DmaMode>,
tx_descriptors: &'static mut [DmaDescriptor],
rx_descriptors: &'static mut [DmaDescriptor],
) -> SpiDma<'d, crate::peripherals::SPI2, C, M, DmaMode>;
}
@ -882,6 +886,8 @@ pub mod dma {
fn with_dma(
self,
channel: Channel<'d, C, DmaMode>,
tx_descriptors: &'static mut [DmaDescriptor],
rx_descriptors: &'static mut [DmaDescriptor],
) -> SpiDma<'d, crate::peripherals::SPI3, C, M, DmaMode>;
}
@ -895,12 +901,16 @@ pub mod dma {
fn with_dma(
self,
mut channel: Channel<'d, C, DmaMode>,
tx_descriptors: &'static mut [DmaDescriptor],
rx_descriptors: &'static mut [DmaDescriptor],
) -> SpiDma<'d, crate::peripherals::SPI2, C, M, DmaMode> {
channel.tx.init_channel(); // no need to call this for both, TX and RX
SpiDma {
spi: self.spi,
channel,
tx_chain: DescriptorChain::new(tx_descriptors),
rx_chain: DescriptorChain::new(rx_descriptors),
_mode: PhantomData,
}
}
@ -917,12 +927,16 @@ pub mod dma {
fn with_dma(
self,
mut channel: Channel<'d, C, DmaMode>,
tx_descriptors: &'static mut [DmaDescriptor],
rx_descriptors: &'static mut [DmaDescriptor],
) -> SpiDma<'d, crate::peripherals::SPI3, C, M, DmaMode> {
channel.tx.init_channel(); // no need to call this for both, TX and RX
SpiDma {
spi: self.spi,
channel,
tx_chain: DescriptorChain::new(tx_descriptors),
rx_chain: DescriptorChain::new(rx_descriptors),
_mode: PhantomData,
}
}
@ -938,6 +952,8 @@ pub mod dma {
{
pub(crate) spi: PeripheralRef<'d, T>,
pub(crate) channel: Channel<'d, C, DmaMode>,
tx_chain: DescriptorChain,
rx_chain: DescriptorChain,
_mode: PhantomData<M>,
}
@ -1037,6 +1053,10 @@ pub mod dma {
fn tx(&mut self) -> &mut Self::TX {
&mut self.channel.tx
}
fn chain(&mut self) -> &mut DescriptorChain {
&mut self.tx_chain
}
}
impl<'d, T, C, M, DmaMode> DmaSupportRx for SpiDma<'d, T, C, M, DmaMode>
@ -1052,6 +1072,10 @@ pub mod dma {
fn rx(&mut self) -> &mut Self::RX {
&mut self.channel.rx
}
fn chain(&mut self) -> &mut DescriptorChain {
&mut self.rx_chain
}
}
impl<'d, T, C, M, DmaMode> SpiDma<'d, T, C, M, DmaMode>
@ -1107,8 +1131,13 @@ pub mod dma {
}
unsafe {
self.spi
.start_write_bytes_dma(ptr, len, &mut self.channel.tx, false)?;
self.spi.start_write_bytes_dma(
&mut self.tx_chain,
ptr,
len,
&mut self.channel.tx,
false,
)?;
}
Ok(())
}
@ -1158,8 +1187,13 @@ pub mod dma {
}
unsafe {
self.spi
.start_read_bytes_dma(ptr, len, &mut self.channel.rx, false)?;
self.spi.start_read_bytes_dma(
&mut self.rx_chain,
ptr,
len,
&mut self.channel.rx,
false,
)?;
}
Ok(())
@ -1218,6 +1252,8 @@ pub mod dma {
unsafe {
self.spi.start_transfer_dma(
&mut self.tx_chain,
&mut self.rx_chain,
write_ptr,
write_len,
read_ptr,
@ -1308,8 +1344,13 @@ pub mod dma {
}
unsafe {
self.spi
.start_read_bytes_dma(ptr, len, &mut self.channel.rx, false)?;
self.spi.start_read_bytes_dma(
&mut self.rx_chain,
ptr,
len,
&mut self.channel.rx,
false,
)?;
}
Ok(DmaTransferRx::new(self))
}
@ -1383,8 +1424,13 @@ pub mod dma {
}
unsafe {
self.spi
.start_write_bytes_dma(ptr, len, &mut self.channel.tx, false)?;
self.spi.start_write_bytes_dma(
&mut self.tx_chain,
ptr,
len,
&mut self.channel.tx,
false,
)?;
}
Ok(DmaTransferTx::new(self))
}
@ -1403,8 +1449,13 @@ pub mod dma {
type Error = super::Error;
fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> {
self.spi
.transfer_in_place_dma(words, &mut self.channel.tx, &mut self.channel.rx)
self.spi.transfer_in_place_dma(
&mut self.tx_chain,
&mut self.rx_chain,
words,
&mut self.channel.tx,
&mut self.channel.rx,
)
}
}
@ -1421,7 +1472,8 @@ pub mod dma {
type Error = super::Error;
fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
self.spi.write_bytes_dma(words, &mut self.channel.tx)?;
self.spi
.write_bytes_dma(&mut self.tx_chain, words, &mut self.channel.tx)?;
self.spi.flush()?;
Ok(())
}
@ -1496,6 +1548,7 @@ pub mod dma {
let mut future = crate::dma::asynch::DmaRxFuture::new(&mut self.channel.rx);
unsafe {
self.spi.start_read_bytes_dma(
&mut self.rx_chain,
words.as_mut_ptr(),
words.len(),
future.rx(),
@ -1512,6 +1565,7 @@ pub mod dma {
let mut future = crate::dma::asynch::DmaTxFuture::new(&mut self.channel.tx);
unsafe {
self.spi.start_write_bytes_dma(
&mut self.tx_chain,
chunk.as_ptr(),
chunk.len(),
future.tx(),
@ -1540,6 +1594,8 @@ pub mod dma {
unsafe {
self.spi.start_transfer_dma(
&mut self.tx_chain,
&mut self.rx_chain,
write.as_ptr().offset(write_idx),
write_len,
read.as_mut_ptr().offset(read_idx),
@ -1573,6 +1629,8 @@ pub mod dma {
unsafe {
self.spi.start_transfer_dma(
&mut self.tx_chain,
&mut self.rx_chain,
chunk.as_ptr(),
chunk.len(),
chunk.as_mut_ptr(),
@ -1670,19 +1728,32 @@ pub mod dma {
M: IsFullDuplex,
{
fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
self.spi
.transfer_dma(&[], words, &mut self.channel.tx, &mut self.channel.rx)?;
self.spi.transfer_dma(
&mut self.tx_chain,
&mut self.rx_chain,
&[],
words,
&mut self.channel.tx,
&mut self.channel.rx,
)?;
self.flush()
}
fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
self.spi.write_bytes_dma(words, &mut self.channel.tx)?;
self.spi
.write_bytes_dma(&mut self.tx_chain, words, &mut self.channel.tx)?;
self.flush()
}
fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> {
self.spi
.transfer_dma(write, read, &mut self.channel.tx, &mut self.channel.rx)?;
self.spi.transfer_dma(
&mut self.tx_chain,
&mut self.rx_chain,
write,
read,
&mut self.channel.tx,
&mut self.channel.rx,
)?;
self.flush()
}
@ -1694,6 +1765,8 @@ pub mod dma {
/// [`read`](SpiBus::read).
fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> {
self.spi.transfer_in_place_dma(
&mut self.tx_chain,
&mut self.rx_chain,
words,
&mut self.channel.tx,
&mut self.channel.rx,
@ -1857,6 +1930,8 @@ where
{
fn transfer_in_place_dma<'w>(
&mut self,
tx_chain: &mut DescriptorChain,
rx_chain: &mut DescriptorChain,
words: &'w mut [u8],
tx: &mut TX,
rx: &mut RX,
@ -1864,6 +1939,8 @@ where
for chunk in words.chunks_mut(MAX_DMA_SIZE) {
unsafe {
self.start_transfer_dma(
tx_chain,
rx_chain,
chunk.as_ptr(),
chunk.len(),
chunk.as_mut_ptr(),
@ -1882,6 +1959,8 @@ where
fn transfer_dma<'w>(
&mut self,
tx_chain: &mut DescriptorChain,
rx_chain: &mut DescriptorChain,
write_buffer: &'w [u8],
read_buffer: &'w mut [u8],
tx: &mut TX,
@ -1897,6 +1976,8 @@ where
unsafe {
self.start_transfer_dma(
tx_chain,
rx_chain,
write_buffer.as_ptr().offset(write_idx),
write_len,
read_buffer.as_mut_ptr().offset(read_idx),
@ -1921,6 +2002,8 @@ where
#[allow(clippy::too_many_arguments)]
unsafe fn start_transfer_dma(
&mut self,
tx_chain: &mut DescriptorChain,
rx_chain: &mut DescriptorChain,
write_buffer_ptr: *const u8,
write_buffer_len: usize,
read_buffer_ptr: *mut u8,
@ -1938,20 +2021,12 @@ where
self.update();
reset_dma_before_load_dma_dscr(reg_block);
tx.prepare_transfer_without_start(
self.dma_peripheral(),
false,
write_buffer_ptr,
write_buffer_len,
)
.and_then(|_| tx.start_transfer())?;
rx.prepare_transfer_without_start(
false,
self.dma_peripheral(),
read_buffer_ptr,
read_buffer_len,
)
.and_then(|_| rx.start_transfer())?;
tx_chain.fill_for_tx(false, write_buffer_ptr, write_buffer_len)?;
tx.prepare_transfer_without_start(self.dma_peripheral(), tx_chain)
.and_then(|_| tx.start_transfer())?;
rx_chain.fill_for_rx(false, read_buffer_ptr, read_buffer_len)?;
rx.prepare_transfer_without_start(self.dma_peripheral(), rx_chain)
.and_then(|_| rx.start_transfer())?;
self.clear_dma_interrupts();
reset_dma_before_usr_cmd(reg_block);
@ -1961,10 +2036,15 @@ where
Ok(())
}
fn write_bytes_dma<'w>(&mut self, words: &'w [u8], tx: &mut TX) -> Result<&'w [u8], Error> {
fn write_bytes_dma<'w>(
&mut self,
chain: &mut DescriptorChain,
words: &'w [u8],
tx: &mut TX,
) -> Result<&'w [u8], Error> {
for chunk in words.chunks(MAX_DMA_SIZE) {
unsafe {
self.start_write_bytes_dma(chunk.as_ptr(), chunk.len(), tx, false)?;
self.start_write_bytes_dma(chain, chunk.as_ptr(), chunk.len(), tx, false)?;
}
while !tx.is_done() {}
@ -1977,6 +2057,7 @@ where
#[cfg_attr(feature = "place-spi-driver-in-ram", ram)]
unsafe fn start_write_bytes_dma(
&mut self,
chain: &mut DescriptorChain,
ptr: *const u8,
len: usize,
tx: &mut TX,
@ -1991,8 +2072,9 @@ where
self.update();
reset_dma_before_load_dma_dscr(reg_block);
chain.fill_for_tx(false, ptr, len)?;
unsafe {
tx.prepare_transfer_without_start(self.dma_peripheral(), false, ptr, len)
tx.prepare_transfer_without_start(self.dma_peripheral(), chain)
.and_then(|_| tx.start_transfer())?;
}
@ -2010,6 +2092,7 @@ where
#[cfg_attr(feature = "place-spi-driver-in-ram", ram)]
unsafe fn start_read_bytes_dma(
&mut self,
chain: &mut DescriptorChain,
ptr: *mut u8,
len: usize,
rx: &mut RX,
@ -2024,7 +2107,8 @@ where
self.update();
reset_dma_before_load_dma_dscr(reg_block);
rx.prepare_transfer_without_start(false, self.dma_peripheral(), ptr, len)
chain.fill_for_rx(false, ptr, len)?;
rx.prepare_transfer_without_start(self.dma_peripheral(), chain)
.and_then(|_| rx.start_transfer())?;
self.clear_dma_interrupts();

View File

@ -33,7 +33,7 @@
//! let mosi = io.pins.gpio2;
//! let cs = io.pins.gpio3;
//!
//! let (tx_buffer, mut tx_descriptors, rx_buffer, mut rx_descriptors) =
//! let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) =
//! dma_buffers!(32000); let mut spi = Spi::new(
//! peripherals.SPI2,
//! sclk,
@ -44,10 +44,8 @@
//! )
//! .with_dma(dma_channel.configure(
//! false,
//! &mut tx_descriptors,
//! &mut rx_descriptors,
//! DmaPriority::Priority0,
//! ));
//! ), tx_descriptors, rx_descriptors);
//!
//! let mut send = tx_buffer;
//! let mut receive = rx_buffer;
@ -64,7 +62,7 @@ use core::marker::PhantomData;
use super::{Error, FullDuplexMode, SpiMode};
use crate::{
dma::{DmaPeripheral, Rx, Tx},
dma::{DescriptorChain, DmaPeripheral, Rx, Tx},
gpio::{InputPin, InputSignal, OutputPin, OutputSignal},
peripheral::{Peripheral, PeripheralRef},
peripherals::spi2::RegisterBlock,
@ -151,6 +149,8 @@ pub mod dma {
dma_private::{DmaSupport, DmaSupportRx, DmaSupportTx},
Channel,
ChannelTypes,
DescriptorChain,
DmaDescriptor,
DmaTransferRx,
DmaTransferTx,
DmaTransferTxRx,
@ -171,6 +171,8 @@ pub mod dma {
fn with_dma(
self,
channel: Channel<'d, C, DmaMode>,
tx_descriptors: &'static mut [DmaDescriptor],
rx_descriptors: &'static mut [DmaDescriptor],
) -> SpiDma<'d, crate::peripherals::SPI2, C, DmaMode>;
}
@ -184,6 +186,8 @@ pub mod dma {
fn with_dma(
self,
channel: Channel<'d, C, DmaMode>,
tx_descriptors: &'static mut [DmaDescriptor],
rx_descriptors: &'static mut [DmaDescriptor],
) -> SpiDma<'d, crate::peripherals::SPI3, C, DmaMode>;
}
@ -197,12 +201,16 @@ pub mod dma {
fn with_dma(
self,
mut channel: Channel<'d, C, DmaMode>,
tx_descriptors: &'static mut [DmaDescriptor],
rx_descriptors: &'static mut [DmaDescriptor],
) -> SpiDma<'d, crate::peripherals::SPI2, C, DmaMode> {
channel.tx.init_channel(); // no need to call this for both, TX and RX
SpiDma {
spi: self.spi,
channel,
tx_chain: DescriptorChain::new(tx_descriptors),
rx_chain: DescriptorChain::new(rx_descriptors),
}
}
}
@ -218,12 +226,16 @@ pub mod dma {
fn with_dma(
self,
mut channel: Channel<'d, C, DmaMode>,
tx_descriptors: &'static mut [DmaDescriptor],
rx_descriptors: &'static mut [DmaDescriptor],
) -> SpiDma<'d, crate::peripherals::SPI3, C, DmaMode> {
channel.tx.init_channel(); // no need to call this for both, TX and RX
SpiDma {
spi: self.spi,
channel,
tx_chain: DescriptorChain::new(tx_descriptors),
rx_chain: DescriptorChain::new(rx_descriptors),
}
}
}
@ -237,6 +249,8 @@ pub mod dma {
{
pub(crate) spi: PeripheralRef<'d, T>,
pub(crate) channel: Channel<'d, C, DmaMode>,
tx_chain: DescriptorChain,
rx_chain: DescriptorChain,
}
impl<'d, T, C, DmaMode> core::fmt::Debug for SpiDma<'d, T, C, DmaMode>
@ -283,6 +297,10 @@ pub mod dma {
fn tx(&mut self) -> &mut Self::TX {
&mut self.channel.tx
}
fn chain(&mut self) -> &mut DescriptorChain {
&mut self.tx_chain
}
}
impl<'d, T, C, DmaMode> DmaSupportRx for SpiDma<'d, T, C, DmaMode>
@ -297,6 +315,10 @@ pub mod dma {
fn rx(&mut self) -> &mut Self::RX {
&mut self.channel.rx
}
fn chain(&mut self) -> &mut DescriptorChain {
&mut self.rx_chain
}
}
impl<'d, T, C, DmaMode> SpiDma<'d, T, C, DmaMode>
@ -327,7 +349,7 @@ pub mod dma {
unsafe {
self.spi
.start_write_bytes_dma(ptr, len, &mut self.channel.tx)
.start_write_bytes_dma(&mut self.tx_chain, ptr, len, &mut self.channel.tx)
.map(move |_| DmaTransferTx::new(self))
}
}
@ -353,7 +375,7 @@ pub mod dma {
unsafe {
self.spi
.start_read_bytes_dma(ptr, len, &mut self.channel.rx)
.start_read_bytes_dma(&mut self.rx_chain, ptr, len, &mut self.channel.rx)
.map(move |_| DmaTransferRx::new(self))
}
}
@ -384,6 +406,8 @@ pub mod dma {
unsafe {
self.spi
.start_transfer_dma(
&mut self.tx_chain,
&mut self.rx_chain,
write_ptr,
write_len,
read_ptr,
@ -403,8 +427,11 @@ where
TX: Tx,
RX: Rx,
{
#[allow(clippy::too_many_arguments)]
unsafe fn start_transfer_dma(
&mut self,
tx_chain: &mut DescriptorChain,
rx_chain: &mut DescriptorChain,
write_buffer_ptr: *const u8,
write_buffer_len: usize,
read_buffer_ptr: *mut u8,
@ -421,19 +448,11 @@ where
reset_dma_before_load_dma_dscr(reg_block);
tx.prepare_transfer_without_start(
self.dma_peripheral(),
false,
write_buffer_ptr,
write_buffer_len,
)?;
tx_chain.fill_for_tx(false, write_buffer_ptr, write_buffer_len)?;
tx.prepare_transfer_without_start(self.dma_peripheral(), tx_chain)?;
rx.prepare_transfer_without_start(
false,
self.dma_peripheral(),
read_buffer_ptr,
read_buffer_len,
)?;
rx_chain.fill_for_rx(false, read_buffer_ptr, read_buffer_len)?;
rx.prepare_transfer_without_start(self.dma_peripheral(), rx_chain)?;
reset_dma_before_usr_cmd(reg_block);
@ -453,6 +472,7 @@ where
unsafe fn start_write_bytes_dma(
&mut self,
tx_chain: &mut DescriptorChain,
ptr: *const u8,
len: usize,
tx: &mut TX,
@ -465,7 +485,8 @@ where
reset_dma_before_load_dma_dscr(reg_block);
tx.prepare_transfer_without_start(self.dma_peripheral(), false, ptr, len)?;
tx_chain.fill_for_tx(false, ptr, len)?;
tx.prepare_transfer_without_start(self.dma_peripheral(), tx_chain)?;
reset_dma_before_usr_cmd(reg_block);
@ -484,6 +505,7 @@ where
unsafe fn start_read_bytes_dma(
&mut self,
rx_chain: &mut DescriptorChain,
ptr: *mut u8,
len: usize,
rx: &mut RX,
@ -495,7 +517,8 @@ where
self.enable_dma();
reset_dma_before_load_dma_dscr(reg_block);
rx.prepare_transfer_without_start(false, self.dma_peripheral(), ptr, len)?;
rx_chain.fill_for_rx(false, ptr, len)?;
rx.prepare_transfer_without_start(self.dma_peripheral(), rx_chain)?;
reset_dma_before_usr_cmd(reg_block);

View File

@ -50,19 +50,16 @@ async fn main(_spawner: Spawner) {
#[cfg(not(any(feature = "esp32", feature = "esp32s2")))]
let dma_channel = dma.channel0;
let (_, mut tx_descriptors, rx_buffer, mut rx_descriptors) = dma_buffers!(0, 4092 * 4);
let (_, tx_descriptors, rx_buffer, rx_descriptors) = dma_buffers!(0, 4092 * 4);
let i2s = I2s::new(
peripherals.I2S0,
Standard::Philips,
DataFormat::Data16Channel16,
44100u32.Hz(),
dma_channel.configure_for_async(
false,
&mut tx_descriptors,
&mut rx_descriptors,
DmaPriority::Priority0,
),
dma_channel.configure_for_async(false, DmaPriority::Priority0),
tx_descriptors,
rx_descriptors,
&clocks,
);

View File

@ -73,19 +73,16 @@ async fn main(_spawner: Spawner) {
#[cfg(not(any(feature = "esp32", feature = "esp32s2")))]
let dma_channel = dma.channel0;
let (tx_buffer, mut tx_descriptors, _, mut rx_descriptors) = dma_buffers!(32000, 0);
let (tx_buffer, tx_descriptors, _, rx_descriptors) = dma_buffers!(32000, 0);
let i2s = I2s::new(
peripherals.I2S0,
Standard::Philips,
DataFormat::Data16Channel16,
44100u32.Hz(),
dma_channel.configure_for_async(
false,
&mut tx_descriptors,
&mut rx_descriptors,
DmaPriority::Priority0,
),
dma_channel.configure_for_async(false, DmaPriority::Priority0),
tx_descriptors,
rx_descriptors,
&clocks,
);

View File

@ -37,7 +37,7 @@ async fn main(_spawner: Spawner) {
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
let (_, mut tx_descriptors, rx_buffer, mut rx_descriptors) = dma_buffers!(0, 32000);
let (_, _, rx_buffer, rx_descriptors) = dma_buffers!(0, 32000);
let dma = Dma::new(peripherals.DMA);
let dma_channel = dma.channel0;
@ -46,12 +46,8 @@ async fn main(_spawner: Spawner) {
let parl_io = ParlIoRxOnly::new(
peripherals.PARL_IO,
dma_channel.configure_for_async(
false,
&mut tx_descriptors,
&mut rx_descriptors,
DmaPriority::Priority0,
),
dma_channel.configure_for_async(false, DmaPriority::Priority0),
rx_descriptors,
1.MHz(),
&clocks,
)

View File

@ -48,7 +48,7 @@ async fn main(_spawner: Spawner) {
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
let (tx_buffer, mut tx_descriptors, _, mut rx_descriptors) = dma_buffers!(32000, 0);
let (tx_buffer, mut tx_descriptors, _, _) = dma_buffers!(32000, 0);
let dma = Dma::new(peripherals.DMA);
let dma_channel = dma.channel0;
@ -59,12 +59,8 @@ async fn main(_spawner: Spawner) {
let parl_io = ParlIoTxOnly::new(
peripherals.PARL_IO,
dma_channel.configure_for_async(
false,
&mut tx_descriptors,
&mut rx_descriptors,
DmaPriority::Priority0,
),
dma_channel.configure_for_async(false, DmaPriority::Priority0),
tx_descriptors,
1.MHz(),
&clocks,
)

View File

@ -61,16 +61,15 @@ async fn main(_spawner: Spawner) {
#[cfg(not(any(feature = "esp32", feature = "esp32s2")))]
let dma_channel = dma.channel0;
let (mut descriptors, mut rx_descriptors) = dma_descriptors!(32000);
let (descriptors, rx_descriptors) = dma_descriptors!(32000);
let mut spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)
.with_pins(Some(sclk), Some(mosi), Some(miso), Some(cs))
.with_dma(dma_channel.configure_for_async(
false,
&mut descriptors,
&mut rx_descriptors,
DmaPriority::Priority0,
));
.with_dma(
dma_channel.configure_for_async(false, DmaPriority::Priority0),
descriptors,
rx_descriptors,
);
let send_buffer = [0, 1, 2, 3, 4, 5, 6, 7];
loop {

View File

@ -43,7 +43,7 @@ fn main() -> ! {
#[cfg(not(any(feature = "esp32", feature = "esp32s2")))]
let dma_channel = dma.channel0;
let (_, mut tx_descriptors, mut rx_buffer, mut rx_descriptors) = dma_buffers!(0, 4 * 4092);
let (_, tx_descriptors, mut rx_buffer, rx_descriptors) = dma_buffers!(0, 4 * 4092);
// Here we test that the type is
// 1) reasonably simple (or at least this will flag changes that may make it
@ -54,12 +54,9 @@ fn main() -> ! {
Standard::Philips,
DataFormat::Data16Channel16,
44100.Hz(),
dma_channel.configure(
false,
&mut tx_descriptors,
&mut rx_descriptors,
DmaPriority::Priority0,
),
dma_channel.configure(false, DmaPriority::Priority0),
tx_descriptors,
rx_descriptors,
&clocks,
);

View File

@ -65,19 +65,16 @@ fn main() -> ! {
#[cfg(not(any(feature = "esp32", feature = "esp32s2")))]
let dma_channel = dma.channel0;
let (tx_buffer, mut tx_descriptors, _, mut rx_descriptors) = dma_buffers!(32000, 0);
let (tx_buffer, tx_descriptors, _, rx_descriptors) = dma_buffers!(32000, 0);
let i2s = I2s::new(
peripherals.I2S0,
Standard::Philips,
DataFormat::Data16Channel16,
44100.Hz(),
dma_channel.configure(
false,
&mut tx_descriptors,
&mut rx_descriptors,
DmaPriority::Priority0,
),
dma_channel.configure(false, DmaPriority::Priority0),
tx_descriptors,
rx_descriptors,
&clocks,
);

View File

@ -54,14 +54,9 @@ fn main() -> ! {
let dma = Dma::new(peripherals.DMA);
let channel = dma.channel0;
let (_, mut tx_descriptors, rx_buffer, mut rx_descriptors) = dma_buffers!(0, 32678);
let (_, _, rx_buffer, rx_descriptors) = dma_buffers!(0, 32678);
let channel = channel.configure(
false,
&mut tx_descriptors,
&mut rx_descriptors,
DmaPriority::Priority0,
);
let channel = channel.configure(false, DmaPriority::Priority0);
let cam_siod = io.pins.gpio4;
let cam_sioc = io.pins.gpio5;
@ -81,9 +76,16 @@ fn main() -> ! {
);
let lcd_cam = LcdCam::new(peripherals.LCD_CAM);
let mut camera = Camera::new(lcd_cam.cam, channel.rx, cam_data_pins, 20u32.MHz(), &clocks)
.with_master_clock(cam_xclk)
.with_ctrl_pins(cam_vsync, cam_href, cam_pclk);
let mut camera = Camera::new(
lcd_cam.cam,
channel.rx,
rx_descriptors,
cam_data_pins,
20u32.MHz(),
&clocks,
)
.with_master_clock(cam_xclk)
.with_ctrl_pins(cam_vsync, cam_href, cam_pclk);
let delay = Delay::new(&clocks);

View File

@ -56,14 +56,9 @@ fn main() -> ! {
let dma = Dma::new(peripherals.DMA);
let channel = dma.channel0;
let (tx_buffer, mut tx_descriptors, _, mut rx_descriptors) = dma_buffers!(32678, 0);
let (tx_buffer, tx_descriptors, _, _) = dma_buffers!(32678, 0);
let channel = channel.configure(
false,
&mut tx_descriptors,
&mut rx_descriptors,
DmaPriority::Priority0,
);
let channel = channel.configure(false, DmaPriority::Priority0);
let delay = Delay::new(&clocks);
@ -85,6 +80,7 @@ fn main() -> ! {
let mut i8080 = I8080::new(
lcd_cam.lcd,
channel.tx,
tx_descriptors,
tx_pins,
20.MHz(),
Config::default(),

View File

@ -30,7 +30,7 @@ fn main() -> ! {
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
let (_, mut tx_descriptors, rx_buffer, mut rx_descriptors) = dma_buffers!(0, 32000);
let (_, _, rx_buffer, rx_descriptors) = dma_buffers!(0, 32000);
let dma = Dma::new(peripherals.DMA);
let dma_channel = dma.channel0;
@ -39,12 +39,8 @@ fn main() -> ! {
let parl_io = ParlIoRxOnly::new(
peripherals.PARL_IO,
dma_channel.configure(
false,
&mut tx_descriptors,
&mut rx_descriptors,
DmaPriority::Priority0,
),
dma_channel.configure(false, DmaPriority::Priority0),
rx_descriptors,
1.MHz(),
&clocks,
)

View File

@ -41,7 +41,7 @@ fn main() -> ! {
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
let (tx_buffer, mut tx_descriptors, _, mut rx_descriptors) = dma_buffers!(32000, 0);
let (tx_buffer, tx_descriptors, _, _) = dma_buffers!(32000, 0);
let dma = Dma::new(peripherals.DMA);
let dma_channel = dma.channel0;
@ -52,12 +52,8 @@ fn main() -> ! {
let parl_io = ParlIoTxOnly::new(
peripherals.PARL_IO,
dma_channel.configure(
false,
&mut tx_descriptors,
&mut rx_descriptors,
DmaPriority::Priority0,
),
dma_channel.configure(false, DmaPriority::Priority0),
tx_descriptors,
1.MHz(),
&clocks,
)

View File

@ -76,7 +76,7 @@ fn main() -> ! {
#[cfg(not(any(feature = "esp32", feature = "esp32s2")))]
let dma_channel = dma.channel0;
let (tx_buffer, mut tx_descriptors, rx_buffer, mut rx_descriptors) = dma_buffers!(256, 320);
let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) = dma_buffers!(256, 320);
let mut spi = Spi::new_half_duplex(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)
.with_pins(
@ -87,12 +87,11 @@ fn main() -> ! {
Some(sio3),
Some(cs),
)
.with_dma(dma_channel.configure(
false,
&mut tx_descriptors,
&mut rx_descriptors,
DmaPriority::Priority0,
));
.with_dma(
dma_channel.configure(false, DmaPriority::Priority0),
tx_descriptors,
rx_descriptors,
);
let delay = Delay::new(&clocks);

View File

@ -54,16 +54,15 @@ fn main() -> ! {
#[cfg(not(any(feature = "esp32", feature = "esp32s2")))]
let dma_channel = dma.channel0;
let (tx_buffer, mut tx_descriptors, rx_buffer, mut rx_descriptors) = dma_buffers!(32000);
let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) = dma_buffers!(32000);
let mut spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)
.with_pins(Some(sclk), Some(mosi), Some(miso), Some(cs))
.with_dma(dma_channel.configure(
false,
&mut tx_descriptors,
&mut rx_descriptors,
DmaPriority::Priority0,
));
.with_dma(
dma_channel.configure(false, DmaPriority::Priority0),
tx_descriptors,
rx_descriptors,
);
let delay = Delay::new(&clocks);

View File

@ -74,7 +74,7 @@ fn main() -> ! {
}
}
let (tx_buffer, mut tx_descriptors, rx_buffer, mut rx_descriptors) = dma_buffers!(32000);
let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) = dma_buffers!(32000);
let mut spi = Spi::new(
peripherals.SPI2,
@ -84,12 +84,11 @@ fn main() -> ! {
slave_cs,
SpiMode::Mode0,
)
.with_dma(dma_channel.configure(
false,
&mut tx_descriptors,
&mut rx_descriptors,
DmaPriority::Priority0,
));
.with_dma(
dma_channel.configure(false, DmaPriority::Priority0),
tx_descriptors,
rx_descriptors,
);
let delay = Delay::new(&clocks);

View File

@ -38,15 +38,13 @@ mod tests {
let dma = Dma::new(peripherals.DMA);
let dma_channel = dma.channel0;
let (input, mut tx_descriptors, mut output, mut rx_descriptors) =
dma_buffers!(DMA_BUFFER_SIZE);
let (input, tx_descriptors, mut output, rx_descriptors) = dma_buffers!(DMA_BUFFER_SIZE);
let mut aes = Aes::new(peripherals.AES).with_dma(dma_channel.configure(
false,
&mut tx_descriptors,
&mut rx_descriptors,
DmaPriority::Priority0,
));
let mut aes = Aes::new(peripherals.AES).with_dma(
dma_channel.configure(false, DmaPriority::Priority0),
tx_descriptors,
rx_descriptors,
);
let keytext = "SUp4SeCp@sSw0rd".as_bytes();
let mut keybuf = [0_u8; 16];
@ -84,15 +82,13 @@ mod tests {
let dma = Dma::new(peripherals.DMA);
let dma_channel = dma.channel0;
let (input, mut tx_descriptors, mut output, mut rx_descriptors) =
dma_buffers!(DMA_BUFFER_SIZE);
let (input, tx_descriptors, mut output, rx_descriptors) = dma_buffers!(DMA_BUFFER_SIZE);
let mut aes = Aes::new(peripherals.AES).with_dma(dma_channel.configure(
false,
&mut tx_descriptors,
&mut rx_descriptors,
DmaPriority::Priority0,
));
let mut aes = Aes::new(peripherals.AES).with_dma(
dma_channel.configure(false, DmaPriority::Priority0),
tx_descriptors,
rx_descriptors,
);
let keytext = "SUp4SeCp@sSw0rd".as_bytes();
let mut keybuf = [0_u8; 16];
@ -129,15 +125,13 @@ mod tests {
let dma = Dma::new(peripherals.DMA);
let dma_channel = dma.channel0;
let (input, mut tx_descriptors, mut output, mut rx_descriptors) =
dma_buffers!(DMA_BUFFER_SIZE);
let (input, tx_descriptors, mut output, rx_descriptors) = dma_buffers!(DMA_BUFFER_SIZE);
let mut aes = Aes::new(peripherals.AES).with_dma(dma_channel.configure(
false,
&mut tx_descriptors,
&mut rx_descriptors,
DmaPriority::Priority0,
));
let mut aes = Aes::new(peripherals.AES).with_dma(
dma_channel.configure(false, DmaPriority::Priority0),
tx_descriptors,
rx_descriptors,
);
let keytext = "SUp4SeCp@sSw0rd".as_bytes();
let mut keybuf = [0_u8; 16];
@ -175,15 +169,13 @@ mod tests {
let dma = Dma::new(peripherals.DMA);
let dma_channel = dma.channel0;
let (input, mut tx_descriptors, mut output, mut rx_descriptors) =
dma_buffers!(DMA_BUFFER_SIZE);
let (input, tx_descriptors, mut output, rx_descriptors) = dma_buffers!(DMA_BUFFER_SIZE);
let mut aes = Aes::new(peripherals.AES).with_dma(dma_channel.configure(
false,
&mut tx_descriptors,
&mut rx_descriptors,
DmaPriority::Priority0,
));
let mut aes = Aes::new(peripherals.AES).with_dma(
dma_channel.configure(false, DmaPriority::Priority0),
tx_descriptors,
rx_descriptors,
);
let keytext = "SUp4SeCp@sSw0rd".as_bytes();
let mut keybuf = [0_u8; 16];

View File

@ -53,20 +53,16 @@ mod tests {
let dma = Dma::new(peripherals.DMA);
let dma_channel = dma.channel0;
let (tx_buffer, mut tx_descriptors, mut rx_buffer, mut rx_descriptors) =
dma_buffers!(16000, 16000);
let (tx_buffer, tx_descriptors, mut rx_buffer, rx_descriptors) = dma_buffers!(16000, 16000);
let i2s = I2s::new(
peripherals.I2S0,
Standard::Philips,
DataFormat::Data16Channel16,
16000.Hz(),
dma_channel.configure(
false,
&mut tx_descriptors,
&mut rx_descriptors,
DmaPriority::Priority0,
),
dma_channel.configure(false, DmaPriority::Priority0),
tx_descriptors,
rx_descriptors,
&clocks,
);

View File

@ -58,17 +58,15 @@ mod tests {
#[cfg(not(any(feature = "esp32", feature = "esp32s2")))]
let dma_channel = dma.channel0;
let (tx_buffer, mut tx_descriptors, rx_buffer, mut rx_descriptors) =
dma_buffers!(DMA_BUFFER_SIZE);
let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) = dma_buffers!(DMA_BUFFER_SIZE);
let mut spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)
.with_pins(Some(sclk), Some(mosi), Some(miso), Some(cs))
.with_dma(dma_channel.configure(
false,
&mut tx_descriptors,
&mut rx_descriptors,
DmaPriority::Priority0,
));
.with_dma(
dma_channel.configure(false, DmaPriority::Priority0),
tx_descriptors,
rx_descriptors,
);
// DMA buffer require a static life-time
let mut send = tx_buffer;
@ -101,16 +99,15 @@ mod tests {
#[cfg(not(any(feature = "esp32", feature = "esp32s2")))]
let dma_channel = dma.channel0;
let (tx_buffer, mut tx_descriptors, rx_buffer, mut rx_descriptors) = dma_buffers!(4, 2);
let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) = dma_buffers!(4, 2);
let mut spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)
.with_pins(Some(sclk), Some(mosi), Some(miso), Some(cs))
.with_dma(dma_channel.configure(
false,
&mut tx_descriptors,
&mut rx_descriptors,
DmaPriority::Priority0,
));
.with_dma(
dma_channel.configure(false, DmaPriority::Priority0),
tx_descriptors,
rx_descriptors,
);
// DMA buffer require a static life-time
let mut send = tx_buffer;
@ -145,17 +142,15 @@ mod tests {
#[cfg(not(any(feature = "esp32", feature = "esp32s2")))]
let dma_channel = dma.channel0;
let (tx_buffer, mut tx_descriptors, rx_buffer, mut rx_descriptors) =
dma_buffers!(DMA_BUFFER_SIZE);
let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) = dma_buffers!(DMA_BUFFER_SIZE);
let mut spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)
.with_pins(Some(sclk), Some(mosi), Some(miso), Some(cs))
.with_dma(dma_channel.configure(
false,
&mut tx_descriptors,
&mut rx_descriptors,
DmaPriority::Priority0,
));
.with_dma(
dma_channel.configure(false, DmaPriority::Priority0),
tx_descriptors,
rx_descriptors,
);
// DMA buffer require a static life-time
let mut send = tx_buffer;
@ -193,7 +188,7 @@ mod tests {
#[cfg(not(any(feature = "esp32", feature = "esp32s2")))]
let dma_channel = dma.channel0;
let (_, mut tx_descriptors, rx_buffer, mut rx_descriptors) = dma_buffers!(DMA_BUFFER_SIZE);
let (_, tx_descriptors, rx_buffer, rx_descriptors) = dma_buffers!(DMA_BUFFER_SIZE);
let tx_buffer = {
// using `static`, not `static mut`, places the array in .rodata
@ -203,12 +198,11 @@ mod tests {
let mut spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)
.with_pins(Some(sclk), Some(mosi), Some(miso), Some(cs))
.with_dma(dma_channel.configure(
false,
&mut tx_descriptors,
&mut rx_descriptors,
DmaPriority::Priority0,
));
.with_dma(
dma_channel.configure(false, DmaPriority::Priority0),
tx_descriptors,
rx_descriptors,
);
let mut receive = rx_buffer;
@ -242,7 +236,7 @@ mod tests {
#[cfg(not(any(feature = "esp32", feature = "esp32s2")))]
let dma_channel = dma.channel0;
let (tx_buffer, mut tx_descriptors, _, mut rx_descriptors) = dma_buffers!(DMA_BUFFER_SIZE);
let (tx_buffer, tx_descriptors, _, rx_descriptors) = dma_buffers!(DMA_BUFFER_SIZE);
let rx_buffer = {
// using `static`, not `static mut`, places the array in .rodata
@ -252,12 +246,11 @@ mod tests {
let mut spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)
.with_pins(Some(sclk), Some(mosi), Some(miso), Some(cs))
.with_dma(dma_channel.configure(
false,
&mut tx_descriptors,
&mut rx_descriptors,
DmaPriority::Priority0,
));
.with_dma(
dma_channel.configure(false, DmaPriority::Priority0),
tx_descriptors,
rx_descriptors,
);
let mut receive = rx_buffer;
assert!(matches!(
@ -290,17 +283,15 @@ mod tests {
#[cfg(not(any(feature = "esp32", feature = "esp32s2")))]
let dma_channel = dma.channel0;
let (tx_buffer, mut tx_descriptors, rx_buffer, mut rx_descriptors) =
dma_buffers!(DMA_BUFFER_SIZE);
let (tx_buffer, tx_descriptors, rx_buffer, rx_descriptors) = dma_buffers!(DMA_BUFFER_SIZE);
let spi = Spi::new(peripherals.SPI2, 100.kHz(), SpiMode::Mode0, &clocks)
.with_pins(Some(sclk), Some(mosi), Some(miso), Some(cs))
.with_dma(dma_channel.configure(
false,
&mut tx_descriptors,
&mut rx_descriptors,
DmaPriority::Priority0,
));
.with_dma(
dma_channel.configure(false, DmaPriority::Priority0),
tx_descriptors,
rx_descriptors,
);
// DMA buffer require a static life-time
let send = tx_buffer;