//! DMA memory ownership and non-blocking transfer contracts. //! //! Board/HAL code proves the memory region, cache policy, and peripheral route. //! Runtime code sees only prepared immutable TX ranges and terminal outcomes. #![no_std] /// A borrowed byte range prepared for a device-to-read DMA transfer. /// /// This is a capability rather than a general byte-slice wrapper. It exists /// only after a platform-selected policy proves DMA reachability and CPU-to-device /// visibility for the selected controller. pub struct DmaReadableBuffer<'a> { bytes: &'a [u8], } impl<'a> DmaReadableBuffer<'a> { /// Creates a DMA-read capability after platform-specific validation. /// /// # Safety /// /// - `bytes` is reachable by the selected DMA engine. /// - CPU writes to `bytes` are visible before transfer begins. /// - `bytes` remains addressable, immovable, and immutable until a terminal /// completion or a documented route-halt outcome releases ownership. pub const unsafe fn new_unchecked(bytes: &'a [u8]) -> Self { Self { bytes } } /// Returns the DMA-visible byte range. pub const fn bytes(&self) -> &'a [u8] { self.bytes } } /// Prepares CPU-owned bytes for a DMA transmit handoff. /// /// A cache-disabled board validates the RAM range. A cached board must clean /// the exact range and issue the required ordering barrier before returning. pub trait DmaTxBufferFactory { /// Platform-specific preparation failure. type Error; /// Validates and prepares a frame for device DMA reads. fn prepare<'a>(&mut self, bytes: &'a [u8]) -> Result, Self::Error>; } /// Terminal result reported by a DMA transmit interrupt handler. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum TxCompletion { /// The selected engine has no terminal event pending. NotPending, /// DMA reached the peripheral data-register endpoint. /// /// This does not prove that the final UART stop bit left the wire. Complete, /// The engine reported a terminal transfer fault. TransferFault, /// The route entered a halted state and requires explicit reinitialization. Halted, } /// Owns one non-blocking DMA-backed transmit route. /// /// The caller retains the prepared range until a terminal completion or fault. /// Implementations must not poll for a hardware state transition from this API. pub trait DmaTxEngine { /// Start-operation failure. type StartError; /// Starts one DMA transfer from a prepared readable buffer. fn start(&mut self, buffer: DmaReadableBuffer<'_>) -> Result<(), Self::StartError>; }