Skip to content

Commit

Permalink
Add NoDma I2C master async bus implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
tullom committed Mar 5, 2025
1 parent ccbbee7 commit a9ffcd8
Show file tree
Hide file tree
Showing 9 changed files with 306 additions and 145 deletions.
2 changes: 1 addition & 1 deletion examples/rt685s-evk/src/bin/dma-mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const TEST_LEN: usize = 16;

macro_rules! test_dma_channel {
($peripherals:expr, $instance:ident, $number:expr) => {
let ch = Dma::reserve_channel::<$instance>($peripherals.$instance);
let ch = Dma::reserve_channel::<$instance>($peripherals.$instance).unwrap();
dma_test(ch, $number).await;
};
}
Expand Down
2 changes: 1 addition & 1 deletion examples/rt685s-evk/src/bin/sha256-async.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ async fn main(_spawner: Spawner) {
let mut hash = [0u8; hasher::HASH_LEN];

info!("Initializing Hashcrypt");
let mut hashcrypt = Hashcrypt::new_async(p.HASHCRYPT, p.DMA0_CH30);
let mut hashcrypt = Hashcrypt::new_async(p.HASHCRYPT, p.DMA0_CH30).unwrap();

info!("Starting hashes");
// Data that fits into a single block
Expand Down
2 changes: 1 addition & 1 deletion examples/rt685s-evk/src/bin/sha256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ async fn main(_spawner: Spawner) {
let mut hash = [0u8; hasher::HASH_LEN];

info!("Initializing Hashcrypt");
let mut hashcrypt = Hashcrypt::new_blocking(p.HASHCRYPT);
let mut hashcrypt = Hashcrypt::new_blocking(p.HASHCRYPT).unwrap();

info!("Starting hashes");
// Data that fits into a single block
Expand Down
38 changes: 30 additions & 8 deletions src/dma/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub mod transfer;
use core::marker::PhantomData;
use core::ptr;

use embassy_hal_internal::impl_peripheral;
use embassy_hal_internal::interrupt::InterruptExt;
use embassy_sync::waitqueue::AtomicWaker;

Expand Down Expand Up @@ -145,16 +146,20 @@ struct DmaInfo {

impl<'d> Dma<'d> {
/// Reserves a DMA channel for exclusive use
pub fn reserve_channel<T: Instance>(_inner: impl Peripheral<P = T> + 'd) -> Channel<'d> {
Channel {
info: T::info(),
_lifetime: PhantomData,
pub fn reserve_channel<T: Instance>(_inner: impl Peripheral<P = T> + 'd) -> Option<Channel<'d>> {
if T::info().is_some() {
Some(Channel {
info: T::info().unwrap(),
_lifetime: PhantomData,
})
} else {
None
}
}
}

trait SealedInstance {
fn info() -> DmaInfo;
fn info() -> Option<DmaInfo>;
}

/// DMA instance trait
Expand All @@ -171,12 +176,12 @@ macro_rules! dma_channel_instance {
}

impl SealedInstance for peripherals::$instance {
fn info() -> DmaInfo {
DmaInfo {
fn info() -> Option<DmaInfo> {
Some(DmaInfo {
// SAFETY: safe from single executor
regs: unsafe { crate::pac::$controller::steal() },
ch_num: $number,
}
})
}
}
};
Expand Down Expand Up @@ -215,3 +220,20 @@ dma_channel_instance!(DMA0_CH29, Dma0, DMA0, 29);
dma_channel_instance!(DMA0_CH30, Dma0, DMA0, 30);
dma_channel_instance!(DMA0_CH31, Dma0, DMA0, 31);
dma_channel_instance!(DMA0_CH32, Dma0, DMA0, 32);

/// IMPORTANT: DO NOT USE unless you are aware of the performance implications of not using DMA.
/// NoDma should only be used when a Flexcomm doesn't support DMA, such as Flexcomm 15.
///
/// For other transport layers, like UART, NoDma is not supported.
pub struct NoDma;
impl_peripheral!(NoDma);

impl Instance for NoDma {
type Interrupt = crate::interrupt::typelevel::DMA0;
}

impl SealedInstance for NoDma {
fn info() -> Option<DmaInfo> {
None
}
}
21 changes: 17 additions & 4 deletions src/hashcrypt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ impl From<Algorithm> for u8 {
}
}

/// Hashcrypt Errors
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Error {
/// Unsupported Configuration
UnsupportedConfiguration,
}

impl<'d, M: Mode> Hashcrypt<'d, M> {
/// Instantiate new Hashcrypt peripheral
fn new_inner(peripheral: impl Peripheral<P = HASHCRYPT> + 'd, dma_ch: Option<dma::channel::Channel<'d>>) -> Self {
Expand Down Expand Up @@ -87,8 +95,8 @@ impl<'d, M: Mode> Hashcrypt<'d, M> {

impl<'d> Hashcrypt<'d, Blocking> {
/// Create a new instance
pub fn new_blocking(peripheral: impl Peripheral<P = HASHCRYPT> + 'd) -> Self {
Self::new_inner(peripheral, None)
pub fn new_blocking(peripheral: impl Peripheral<P = HASHCRYPT> + 'd) -> Result<Self, Error> {
Ok(Self::new_inner(peripheral, None))
}

/// Start a new SHA256 hash
Expand All @@ -103,8 +111,13 @@ impl<'d> Hashcrypt<'d, Async> {
pub fn new_async(
peripheral: impl Peripheral<P = HASHCRYPT> + 'd,
dma_ch: impl Peripheral<P = impl HashcryptDma> + 'd,
) -> Self {
Self::new_inner(peripheral, Some(dma::Dma::reserve_channel(dma_ch)))
) -> Result<Self, Error> {
let ch = dma::Dma::reserve_channel(dma_ch);
if ch.is_some() {
Ok(Self::new_inner(peripheral, ch))
} else {
Err(Error::UnsupportedConfiguration)
}
}

/// Start a new SHA256 hash
Expand Down
Loading

0 comments on commit a9ffcd8

Please sign in to comment.