libs/kaptan-dma: add DMA transmit contracts

This commit is contained in:
Onur Özkan committed 2026-07-19 22:39:55 +03:00
1 parent 6d9cadfa8f
commit 1712f1284a
2 files changed
+83

No files matched your search

+10
View File
@@ -0,0 +1,10 @@
[package]
name = "kaptan-dma"
edition.workspace = true
license.workspace = true
repository.workspace = true
rust-version.workspace = true
version.workspace = true
[lints]
workspace = true
+73
View File
@@ -0,0 +1,73 @@
//! 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 board-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<DmaReadableBuffer<'a>, 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>;
}