mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-28 04:40:52 +00:00
[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:
parent
e46e80b8c1
commit
7753551671
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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])?)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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()?;
|
||||
}
|
||||
|
@ -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(())
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
);
|
||||
|
||||
|
@ -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,
|
||||
);
|
||||
|
||||
|
@ -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,
|
||||
)
|
||||
|
@ -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,
|
||||
)
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
);
|
||||
|
||||
|
@ -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,
|
||||
);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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(),
|
||||
|
@ -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,
|
||||
)
|
||||
|
@ -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,
|
||||
)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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];
|
||||
|
@ -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,
|
||||
);
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user