Skip to main content

DmaEngine

Struct DmaEngine 

Source
pub struct DmaEngine<const RX: usize, const TX: usize, const BUF: usize> { /* private fields */ }
Expand description

DMA engine with statically allocated buffers.

§Const generics

  • RX: number of RX descriptors/buffers
  • TX: number of TX descriptors/buffers
  • BUF: buffer size per descriptor (bytes)

Implementations§

Source§

impl<const RX: usize, const TX: usize, const BUF: usize> DmaEngine<RX, TX, BUF>

Source

pub const fn new() -> Self

Create a new DMA engine (all zeroed, not yet initialized).

Source

pub fn init(&mut self) -> (u32, u32)

Initialize descriptor chains.

Sets up chained descriptors: each points to its buffer and the next descriptor. The last descriptor chains back to the first (circular).

Returns (rx_base_addr, tx_base_addr) for programming DMA registers.

Source

pub fn is_initialized(&self) -> bool

Check if initialized.

Source

pub const fn memory_usage() -> usize

Calculate total static memory usage in bytes.

Source

pub fn can_transmit(&self, len: usize) -> bool

Check if there’s room to transmit a frame of given length.

Source

pub fn tx_available(&self) -> usize

Count available (CPU-owned) TX descriptors starting from current.

Source

pub fn transmit(&mut self, data: &[u8]) -> Result<usize, EmacError>

Submit a frame for transmission. Returns number of bytes sent.

For frames larger than BUF, uses multiple descriptors (scatter-gather). Descriptors are given to DMA in reverse order to prevent a race where the DMA starts processing before all descriptors are ready.

Source

pub fn tx_reclaim(&mut self) -> usize

Reclaim completed TX descriptors (return from DMA to CPU ownership).

Returns the number of descriptors reclaimed.

Source

pub fn rx_available(&self) -> bool

Check if there is something for receive to do on the current descriptor. Returns true when:

  • the current descriptor is CPU-owned and carries an error flag (CRC, overflow, etc.) — receive will recycle it as part of its error path, so the driver still needs to be woken; or
  • a complete (possibly multi-descriptor) frame is available, as determined by peek_frame_length.

Two earlier implementations both had bugs:

  1. !current.is_owned() && current.is_last() missed multi- descriptor frames whose head wasn’t itself LAST.
  2. peek_frame_length().is_some() fixed (1) but missed error frames (peek declines to report a length for them), so the embassy-net driver never called receive to flush a CRC-failed frame — RX would wedge as the ring filled with untouched error descriptors.
Source

pub fn receive(&mut self, buffer: &mut [u8]) -> Result<Option<usize>, EmacError>

Receive a frame into the provided buffer.

Returns the number of bytes received, or None if no frame is ready. For single-descriptor frames, copies payload from the RX buffer. For multi-descriptor frames, copies from each descriptor’s buffer.

Source

pub fn peek_frame_length(&self) -> Option<usize>

Get the length of the next available frame without consuming it.

Source

pub fn rx_free_count(&self) -> usize

Count free RX descriptors (owned by DMA, ready to receive).

Source

pub fn reset(&mut self) -> (u32, u32)

Reset all descriptors to initial state.

Re-initializes the chains and returns base addresses.

Source

pub fn rx_ring_base(&self) -> u32

RX ring base address (for debugging).

Source

pub fn tx_ring_base(&self) -> u32

TX ring base address (for debugging).

Source

pub fn rx_current_index(&self) -> usize

Current RX ring index.

Source

pub fn tx_current_index(&self) -> usize

Current TX ring index.

Trait Implementations§

Source§

impl<const RX: usize, const TX: usize, const BUF: usize> Default for DmaEngine<RX, TX, BUF>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<const RX: usize, const TX: usize, const BUF: usize> Send for DmaEngine<RX, TX, BUF>

Source§

impl<const RX: usize, const TX: usize, const BUF: usize> Sync for DmaEngine<RX, TX, BUF>

Auto Trait Implementations§

§

impl<const RX: usize, const TX: usize, const BUF: usize> !Freeze for DmaEngine<RX, TX, BUF>

§

impl<const RX: usize, const TX: usize, const BUF: usize> !RefUnwindSafe for DmaEngine<RX, TX, BUF>

§

impl<const RX: usize, const TX: usize, const BUF: usize> Unpin for DmaEngine<RX, TX, BUF>

§

impl<const RX: usize, const TX: usize, const BUF: usize> UnsafeUnpin for DmaEngine<RX, TX, BUF>

§

impl<const RX: usize, const TX: usize, const BUF: usize> UnwindSafe for DmaEngine<RX, TX, BUF>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.