mirror of
https://github.com/embassy-rs/embassy.git
synced 2025-09-27 04:10:25 +00:00
stm32/dma: fix packing/unpacking not working.
This commit is contained in:
parent
00b2567fbf
commit
84cc949df6
@ -2,7 +2,6 @@
|
||||
#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
|
||||
use core::cmp::min;
|
||||
use core::marker::PhantomData;
|
||||
use core::ptr;
|
||||
|
||||
use embassy_hal_internal::{Peri, PeripheralType};
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
@ -1814,14 +1813,12 @@ impl<'d, T: Instance> Cryp<'d, T, Async> {
|
||||
assert_eq!(blocks.len() % block_size, 0);
|
||||
// Configure DMA to transfer input to crypto core.
|
||||
let dst_ptr: *mut u32 = T::regs().din().as_ptr();
|
||||
let num_words = blocks.len() / 4;
|
||||
let src_ptr: *const [u8] = ptr::slice_from_raw_parts(blocks.as_ptr().cast(), num_words);
|
||||
let options = TransferOptions {
|
||||
#[cfg(not(gpdma))]
|
||||
priority: crate::dma::Priority::High,
|
||||
..Default::default()
|
||||
};
|
||||
let dma_transfer = unsafe { dma.write_raw(src_ptr, dst_ptr, options) };
|
||||
let dma_transfer = unsafe { dma.write_raw(blocks, dst_ptr, options) };
|
||||
T::regs().dmacr().modify(|w| w.set_dien(true));
|
||||
// Wait for the transfer to complete.
|
||||
dma_transfer.await;
|
||||
@ -1836,14 +1833,12 @@ impl<'d, T: Instance> Cryp<'d, T, Async> {
|
||||
assert_eq!((blocks.len() * 4) % block_size, 0);
|
||||
// Configure DMA to transfer input to crypto core.
|
||||
let dst_ptr: *mut u32 = T::regs().din().as_ptr();
|
||||
let num_words = blocks.len();
|
||||
let src_ptr: *const [u32] = ptr::slice_from_raw_parts(blocks.as_ptr().cast(), num_words);
|
||||
let options = TransferOptions {
|
||||
#[cfg(not(gpdma))]
|
||||
priority: crate::dma::Priority::High,
|
||||
..Default::default()
|
||||
};
|
||||
let dma_transfer = unsafe { dma.write_raw(src_ptr, dst_ptr, options) };
|
||||
let dma_transfer = unsafe { dma.write_raw(blocks, dst_ptr, options) };
|
||||
T::regs().dmacr().modify(|w| w.set_dien(true));
|
||||
// Wait for the transfer to complete.
|
||||
dma_transfer.await;
|
||||
@ -1857,14 +1852,12 @@ impl<'d, T: Instance> Cryp<'d, T, Async> {
|
||||
assert_eq!(blocks.len() % block_size, 0);
|
||||
// Configure DMA to get output from crypto core.
|
||||
let src_ptr = T::regs().dout().as_ptr();
|
||||
let num_words = blocks.len() / 4;
|
||||
let dst_ptr = ptr::slice_from_raw_parts_mut(blocks.as_mut_ptr().cast(), num_words);
|
||||
let options = TransferOptions {
|
||||
#[cfg(not(gpdma))]
|
||||
priority: crate::dma::Priority::VeryHigh,
|
||||
..Default::default()
|
||||
};
|
||||
let dma_transfer = unsafe { dma.read_raw(src_ptr, dst_ptr, options) };
|
||||
let dma_transfer = unsafe { dma.read_raw(src_ptr, blocks, options) };
|
||||
T::regs().dmacr().modify(|w| w.set_doen(true));
|
||||
// Wait for the transfer to complete.
|
||||
dma_transfer.await;
|
||||
|
@ -341,7 +341,7 @@ impl AnyChannel {
|
||||
mem_len: usize,
|
||||
incr_mem: bool,
|
||||
mem_size: WordSize,
|
||||
peripheral_size: WordSize,
|
||||
peri_size: WordSize,
|
||||
options: TransferOptions,
|
||||
) {
|
||||
// "Preceding reads and writes cannot be moved past subsequent writes."
|
||||
@ -357,8 +357,6 @@ impl AnyChannel {
|
||||
#[cfg(dmamux)]
|
||||
super::dmamux::configure_dmamux(&info.dmamux, _request);
|
||||
|
||||
assert!(mem_len > 0 && mem_len <= 0xFFFF);
|
||||
|
||||
match self.info().dma {
|
||||
#[cfg(dma)]
|
||||
DmaInfo::Dma(r) => {
|
||||
@ -368,14 +366,39 @@ impl AnyChannel {
|
||||
state.complete_count.store(0, Ordering::Release);
|
||||
self.clear_irqs();
|
||||
|
||||
// NDTR is the number of transfers in the *peripheral* word size.
|
||||
// ex: if mem_size=1, peri_size=4 and ndtr=3 it'll do 12 mem transfers, 3 peri transfers.
|
||||
let ndtr = match (mem_size, peri_size) {
|
||||
(WordSize::FourBytes, WordSize::OneByte) => mem_len * 4,
|
||||
(WordSize::FourBytes, WordSize::TwoBytes) | (WordSize::TwoBytes, WordSize::OneByte) => mem_len * 2,
|
||||
(WordSize::FourBytes, WordSize::FourBytes)
|
||||
| (WordSize::TwoBytes, WordSize::TwoBytes)
|
||||
| (WordSize::OneByte, WordSize::OneByte) => mem_len,
|
||||
(WordSize::TwoBytes, WordSize::FourBytes) | (WordSize::OneByte, WordSize::TwoBytes) => {
|
||||
assert!(mem_len % 2 == 0);
|
||||
mem_len / 2
|
||||
}
|
||||
(WordSize::OneByte, WordSize::FourBytes) => {
|
||||
assert!(mem_len % 4 == 0);
|
||||
mem_len / 4
|
||||
}
|
||||
};
|
||||
|
||||
assert!(ndtr > 0 && ndtr <= 0xFFFF);
|
||||
|
||||
ch.par().write_value(peri_addr as u32);
|
||||
ch.m0ar().write_value(mem_addr as u32);
|
||||
ch.ndtr().write_value(pac::dma::regs::Ndtr(mem_len as _));
|
||||
ch.ndtr().write_value(pac::dma::regs::Ndtr(ndtr as _));
|
||||
ch.fcr().write(|w| {
|
||||
if let Some(fth) = options.fifo_threshold {
|
||||
// FIFO mode
|
||||
w.set_dmdis(pac::dma::vals::Dmdis::DISABLED);
|
||||
w.set_fth(fth.into());
|
||||
} else if mem_size != peri_size {
|
||||
// force FIFO mode if msize != psize
|
||||
// packing/unpacking doesn't work in direct mode.
|
||||
w.set_dmdis(pac::dma::vals::Dmdis::DISABLED);
|
||||
w.set_fth(FifoThreshold::Half.into());
|
||||
} else {
|
||||
// Direct mode
|
||||
w.set_dmdis(pac::dma::vals::Dmdis::ENABLED);
|
||||
@ -384,7 +407,7 @@ impl AnyChannel {
|
||||
ch.cr().write(|w| {
|
||||
w.set_dir(dir.into());
|
||||
w.set_msize(mem_size.into());
|
||||
w.set_psize(peripheral_size.into());
|
||||
w.set_psize(peri_size.into());
|
||||
w.set_pl(options.priority.into());
|
||||
w.set_minc(incr_mem);
|
||||
w.set_pinc(false);
|
||||
@ -404,6 +427,8 @@ impl AnyChannel {
|
||||
}
|
||||
#[cfg(bdma)]
|
||||
DmaInfo::Bdma(r) => {
|
||||
assert!(mem_len > 0 && mem_len <= 0xFFFF);
|
||||
|
||||
#[cfg(bdma_v2)]
|
||||
critical_section::with(|_| r.cselr().modify(|w| w.set_cs(info.num, _request)));
|
||||
|
||||
@ -417,7 +442,7 @@ impl AnyChannel {
|
||||
ch.mar().write_value(mem_addr as u32);
|
||||
ch.ndtr().write(|w| w.set_ndt(mem_len as u16));
|
||||
ch.cr().write(|w| {
|
||||
w.set_psize(peripheral_size.into());
|
||||
w.set_psize(peri_size.into());
|
||||
w.set_msize(mem_size.into());
|
||||
w.set_minc(incr_mem);
|
||||
w.set_dir(dir.into());
|
||||
@ -587,11 +612,11 @@ impl<'a> Transfer<'a> {
|
||||
}
|
||||
|
||||
/// Create a new read DMA transfer (peripheral to memory), using raw pointers.
|
||||
pub unsafe fn new_read_raw<W: Word>(
|
||||
pub unsafe fn new_read_raw<MW: Word, PW: Word>(
|
||||
channel: Peri<'a, impl Channel>,
|
||||
request: Request,
|
||||
peri_addr: *mut W,
|
||||
buf: *mut [W],
|
||||
peri_addr: *mut PW,
|
||||
buf: *mut [MW],
|
||||
options: TransferOptions,
|
||||
) -> Self {
|
||||
Self::new_inner(
|
||||
@ -599,11 +624,11 @@ impl<'a> Transfer<'a> {
|
||||
request,
|
||||
Dir::PeripheralToMemory,
|
||||
peri_addr as *const u32,
|
||||
buf as *mut W as *mut u32,
|
||||
buf as *mut MW as *mut u32,
|
||||
buf.len(),
|
||||
true,
|
||||
W::size(),
|
||||
W::size(),
|
||||
MW::size(),
|
||||
PW::size(),
|
||||
options,
|
||||
)
|
||||
}
|
||||
@ -672,22 +697,14 @@ impl<'a> Transfer<'a> {
|
||||
mem_addr: *mut u32,
|
||||
mem_len: usize,
|
||||
incr_mem: bool,
|
||||
data_size: WordSize,
|
||||
peripheral_size: WordSize,
|
||||
mem_size: WordSize,
|
||||
peri_size: WordSize,
|
||||
options: TransferOptions,
|
||||
) -> Self {
|
||||
assert!(mem_len > 0 && mem_len <= 0xFFFF);
|
||||
|
||||
channel.configure(
|
||||
_request,
|
||||
dir,
|
||||
peri_addr,
|
||||
mem_addr,
|
||||
mem_len,
|
||||
incr_mem,
|
||||
data_size,
|
||||
peripheral_size,
|
||||
options,
|
||||
_request, dir, peri_addr, mem_addr, mem_len, incr_mem, mem_size, peri_size, options,
|
||||
);
|
||||
channel.start();
|
||||
Self { channel }
|
||||
|
@ -125,11 +125,11 @@ impl<'a> Transfer<'a> {
|
||||
}
|
||||
|
||||
/// Create a new read DMA transfer (peripheral to memory), using raw pointers.
|
||||
pub unsafe fn new_read_raw<W: Word>(
|
||||
pub unsafe fn new_read_raw<MW: Word, PW: Word>(
|
||||
channel: Peri<'a, impl Channel>,
|
||||
request: Request,
|
||||
peri_addr: *mut W,
|
||||
buf: *mut [W],
|
||||
peri_addr: *mut PW,
|
||||
buf: *mut [MW],
|
||||
options: TransferOptions,
|
||||
) -> Self {
|
||||
Self::new_inner(
|
||||
@ -137,11 +137,11 @@ impl<'a> Transfer<'a> {
|
||||
request,
|
||||
Dir::PeripheralToMemory,
|
||||
peri_addr as *const u32,
|
||||
buf as *mut W as *mut u32,
|
||||
buf as *mut MW as *mut u32,
|
||||
buf.len(),
|
||||
true,
|
||||
W::size(),
|
||||
W::size(),
|
||||
PW::size(),
|
||||
MW::size(),
|
||||
options,
|
||||
)
|
||||
}
|
||||
|
@ -20,10 +20,10 @@ impl<'d> ChannelAndRequest<'d> {
|
||||
Transfer::new_read(self.channel.reborrow(), self.request, peri_addr, buf, options)
|
||||
}
|
||||
|
||||
pub unsafe fn read_raw<'a, W: Word>(
|
||||
pub unsafe fn read_raw<'a, MW: Word, PW: Word>(
|
||||
&'a mut self,
|
||||
peri_addr: *mut W,
|
||||
buf: *mut [W],
|
||||
peri_addr: *mut PW,
|
||||
buf: *mut [MW],
|
||||
options: TransferOptions,
|
||||
) -> Transfer<'a> {
|
||||
Transfer::new_read_raw(self.channel.reborrow(), self.request, peri_addr, buf, options)
|
||||
|
@ -843,7 +843,7 @@ impl<'d> Spi<'d, Async> {
|
||||
|
||||
set_rxdmaen(self.info.regs, true);
|
||||
|
||||
let rx_src = self.info.regs.rx_ptr();
|
||||
let rx_src = self.info.regs.rx_ptr::<W>();
|
||||
let rx_f = unsafe { self.rx_dma.as_mut().unwrap().read_raw(rx_src, read, Default::default()) };
|
||||
|
||||
let tx_dst: *mut W = self.info.regs.tx_ptr();
|
||||
|
@ -68,7 +68,9 @@ async fn main(_spawner: Spawner) -> ! {
|
||||
);
|
||||
|
||||
// Decrypt in software using AES-GCM 128-bit
|
||||
let _ = cipher.decrypt_in_place(&iv.into(), aad.into(), &mut payload_vec);
|
||||
cipher
|
||||
.decrypt_in_place(&iv.into(), aad.into(), &mut payload_vec)
|
||||
.unwrap();
|
||||
|
||||
let sw_end_time = Instant::now();
|
||||
let sw_execution_time = sw_end_time - sw_start_time;
|
||||
|
@ -72,7 +72,7 @@ async fn main(_spawner: Spawner) {
|
||||
defmt::assert!(encrypt_tag == payload_vec[ciphertext.len()..ciphertext.len() + encrypt_tag.len()]);
|
||||
|
||||
// Decrypt in software using AES-GCM 128-bit
|
||||
let _ = cipher.decrypt_in_place(&iv.into(), &aad, &mut payload_vec);
|
||||
cipher.decrypt_in_place(&iv.into(), &aad, &mut payload_vec).unwrap();
|
||||
|
||||
info!("Test OK");
|
||||
cortex_m::asm::bkpt();
|
||||
|
Loading…
x
Reference in New Issue
Block a user