mirror of
https://github.com/embassy-rs/embassy.git
synced 2025-09-28 04:40:39 +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))]
|
#[cfg(any(cryp_v2, cryp_v3, cryp_v4))]
|
||||||
use core::cmp::min;
|
use core::cmp::min;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use core::ptr;
|
|
||||||
|
|
||||||
use embassy_hal_internal::{Peri, PeripheralType};
|
use embassy_hal_internal::{Peri, PeripheralType};
|
||||||
use embassy_sync::waitqueue::AtomicWaker;
|
use embassy_sync::waitqueue::AtomicWaker;
|
||||||
@ -1814,14 +1813,12 @@ impl<'d, T: Instance> Cryp<'d, T, Async> {
|
|||||||
assert_eq!(blocks.len() % block_size, 0);
|
assert_eq!(blocks.len() % block_size, 0);
|
||||||
// Configure DMA to transfer input to crypto core.
|
// Configure DMA to transfer input to crypto core.
|
||||||
let dst_ptr: *mut u32 = T::regs().din().as_ptr();
|
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 {
|
let options = TransferOptions {
|
||||||
#[cfg(not(gpdma))]
|
#[cfg(not(gpdma))]
|
||||||
priority: crate::dma::Priority::High,
|
priority: crate::dma::Priority::High,
|
||||||
..Default::default()
|
..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));
|
T::regs().dmacr().modify(|w| w.set_dien(true));
|
||||||
// Wait for the transfer to complete.
|
// Wait for the transfer to complete.
|
||||||
dma_transfer.await;
|
dma_transfer.await;
|
||||||
@ -1836,14 +1833,12 @@ impl<'d, T: Instance> Cryp<'d, T, Async> {
|
|||||||
assert_eq!((blocks.len() * 4) % block_size, 0);
|
assert_eq!((blocks.len() * 4) % block_size, 0);
|
||||||
// Configure DMA to transfer input to crypto core.
|
// Configure DMA to transfer input to crypto core.
|
||||||
let dst_ptr: *mut u32 = T::regs().din().as_ptr();
|
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 {
|
let options = TransferOptions {
|
||||||
#[cfg(not(gpdma))]
|
#[cfg(not(gpdma))]
|
||||||
priority: crate::dma::Priority::High,
|
priority: crate::dma::Priority::High,
|
||||||
..Default::default()
|
..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));
|
T::regs().dmacr().modify(|w| w.set_dien(true));
|
||||||
// Wait for the transfer to complete.
|
// Wait for the transfer to complete.
|
||||||
dma_transfer.await;
|
dma_transfer.await;
|
||||||
@ -1857,14 +1852,12 @@ impl<'d, T: Instance> Cryp<'d, T, Async> {
|
|||||||
assert_eq!(blocks.len() % block_size, 0);
|
assert_eq!(blocks.len() % block_size, 0);
|
||||||
// Configure DMA to get output from crypto core.
|
// Configure DMA to get output from crypto core.
|
||||||
let src_ptr = T::regs().dout().as_ptr();
|
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 {
|
let options = TransferOptions {
|
||||||
#[cfg(not(gpdma))]
|
#[cfg(not(gpdma))]
|
||||||
priority: crate::dma::Priority::VeryHigh,
|
priority: crate::dma::Priority::VeryHigh,
|
||||||
..Default::default()
|
..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));
|
T::regs().dmacr().modify(|w| w.set_doen(true));
|
||||||
// Wait for the transfer to complete.
|
// Wait for the transfer to complete.
|
||||||
dma_transfer.await;
|
dma_transfer.await;
|
||||||
|
@ -341,7 +341,7 @@ impl AnyChannel {
|
|||||||
mem_len: usize,
|
mem_len: usize,
|
||||||
incr_mem: bool,
|
incr_mem: bool,
|
||||||
mem_size: WordSize,
|
mem_size: WordSize,
|
||||||
peripheral_size: WordSize,
|
peri_size: WordSize,
|
||||||
options: TransferOptions,
|
options: TransferOptions,
|
||||||
) {
|
) {
|
||||||
// "Preceding reads and writes cannot be moved past subsequent writes."
|
// "Preceding reads and writes cannot be moved past subsequent writes."
|
||||||
@ -357,8 +357,6 @@ impl AnyChannel {
|
|||||||
#[cfg(dmamux)]
|
#[cfg(dmamux)]
|
||||||
super::dmamux::configure_dmamux(&info.dmamux, _request);
|
super::dmamux::configure_dmamux(&info.dmamux, _request);
|
||||||
|
|
||||||
assert!(mem_len > 0 && mem_len <= 0xFFFF);
|
|
||||||
|
|
||||||
match self.info().dma {
|
match self.info().dma {
|
||||||
#[cfg(dma)]
|
#[cfg(dma)]
|
||||||
DmaInfo::Dma(r) => {
|
DmaInfo::Dma(r) => {
|
||||||
@ -368,14 +366,39 @@ impl AnyChannel {
|
|||||||
state.complete_count.store(0, Ordering::Release);
|
state.complete_count.store(0, Ordering::Release);
|
||||||
self.clear_irqs();
|
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.par().write_value(peri_addr as u32);
|
||||||
ch.m0ar().write_value(mem_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| {
|
ch.fcr().write(|w| {
|
||||||
if let Some(fth) = options.fifo_threshold {
|
if let Some(fth) = options.fifo_threshold {
|
||||||
// FIFO mode
|
// FIFO mode
|
||||||
w.set_dmdis(pac::dma::vals::Dmdis::DISABLED);
|
w.set_dmdis(pac::dma::vals::Dmdis::DISABLED);
|
||||||
w.set_fth(fth.into());
|
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 {
|
} else {
|
||||||
// Direct mode
|
// Direct mode
|
||||||
w.set_dmdis(pac::dma::vals::Dmdis::ENABLED);
|
w.set_dmdis(pac::dma::vals::Dmdis::ENABLED);
|
||||||
@ -384,7 +407,7 @@ impl AnyChannel {
|
|||||||
ch.cr().write(|w| {
|
ch.cr().write(|w| {
|
||||||
w.set_dir(dir.into());
|
w.set_dir(dir.into());
|
||||||
w.set_msize(mem_size.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_pl(options.priority.into());
|
||||||
w.set_minc(incr_mem);
|
w.set_minc(incr_mem);
|
||||||
w.set_pinc(false);
|
w.set_pinc(false);
|
||||||
@ -404,6 +427,8 @@ impl AnyChannel {
|
|||||||
}
|
}
|
||||||
#[cfg(bdma)]
|
#[cfg(bdma)]
|
||||||
DmaInfo::Bdma(r) => {
|
DmaInfo::Bdma(r) => {
|
||||||
|
assert!(mem_len > 0 && mem_len <= 0xFFFF);
|
||||||
|
|
||||||
#[cfg(bdma_v2)]
|
#[cfg(bdma_v2)]
|
||||||
critical_section::with(|_| r.cselr().modify(|w| w.set_cs(info.num, _request)));
|
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.mar().write_value(mem_addr as u32);
|
||||||
ch.ndtr().write(|w| w.set_ndt(mem_len as u16));
|
ch.ndtr().write(|w| w.set_ndt(mem_len as u16));
|
||||||
ch.cr().write(|w| {
|
ch.cr().write(|w| {
|
||||||
w.set_psize(peripheral_size.into());
|
w.set_psize(peri_size.into());
|
||||||
w.set_msize(mem_size.into());
|
w.set_msize(mem_size.into());
|
||||||
w.set_minc(incr_mem);
|
w.set_minc(incr_mem);
|
||||||
w.set_dir(dir.into());
|
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.
|
/// 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>,
|
channel: Peri<'a, impl Channel>,
|
||||||
request: Request,
|
request: Request,
|
||||||
peri_addr: *mut W,
|
peri_addr: *mut PW,
|
||||||
buf: *mut [W],
|
buf: *mut [MW],
|
||||||
options: TransferOptions,
|
options: TransferOptions,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::new_inner(
|
Self::new_inner(
|
||||||
@ -599,11 +624,11 @@ impl<'a> Transfer<'a> {
|
|||||||
request,
|
request,
|
||||||
Dir::PeripheralToMemory,
|
Dir::PeripheralToMemory,
|
||||||
peri_addr as *const u32,
|
peri_addr as *const u32,
|
||||||
buf as *mut W as *mut u32,
|
buf as *mut MW as *mut u32,
|
||||||
buf.len(),
|
buf.len(),
|
||||||
true,
|
true,
|
||||||
W::size(),
|
MW::size(),
|
||||||
W::size(),
|
PW::size(),
|
||||||
options,
|
options,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -672,22 +697,14 @@ impl<'a> Transfer<'a> {
|
|||||||
mem_addr: *mut u32,
|
mem_addr: *mut u32,
|
||||||
mem_len: usize,
|
mem_len: usize,
|
||||||
incr_mem: bool,
|
incr_mem: bool,
|
||||||
data_size: WordSize,
|
mem_size: WordSize,
|
||||||
peripheral_size: WordSize,
|
peri_size: WordSize,
|
||||||
options: TransferOptions,
|
options: TransferOptions,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
assert!(mem_len > 0 && mem_len <= 0xFFFF);
|
assert!(mem_len > 0 && mem_len <= 0xFFFF);
|
||||||
|
|
||||||
channel.configure(
|
channel.configure(
|
||||||
_request,
|
_request, dir, peri_addr, mem_addr, mem_len, incr_mem, mem_size, peri_size, options,
|
||||||
dir,
|
|
||||||
peri_addr,
|
|
||||||
mem_addr,
|
|
||||||
mem_len,
|
|
||||||
incr_mem,
|
|
||||||
data_size,
|
|
||||||
peripheral_size,
|
|
||||||
options,
|
|
||||||
);
|
);
|
||||||
channel.start();
|
channel.start();
|
||||||
Self { channel }
|
Self { channel }
|
||||||
|
@ -125,11 +125,11 @@ impl<'a> Transfer<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new read DMA transfer (peripheral to memory), using raw pointers.
|
/// 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>,
|
channel: Peri<'a, impl Channel>,
|
||||||
request: Request,
|
request: Request,
|
||||||
peri_addr: *mut W,
|
peri_addr: *mut PW,
|
||||||
buf: *mut [W],
|
buf: *mut [MW],
|
||||||
options: TransferOptions,
|
options: TransferOptions,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::new_inner(
|
Self::new_inner(
|
||||||
@ -137,11 +137,11 @@ impl<'a> Transfer<'a> {
|
|||||||
request,
|
request,
|
||||||
Dir::PeripheralToMemory,
|
Dir::PeripheralToMemory,
|
||||||
peri_addr as *const u32,
|
peri_addr as *const u32,
|
||||||
buf as *mut W as *mut u32,
|
buf as *mut MW as *mut u32,
|
||||||
buf.len(),
|
buf.len(),
|
||||||
true,
|
true,
|
||||||
W::size(),
|
PW::size(),
|
||||||
W::size(),
|
MW::size(),
|
||||||
options,
|
options,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -20,10 +20,10 @@ impl<'d> ChannelAndRequest<'d> {
|
|||||||
Transfer::new_read(self.channel.reborrow(), self.request, peri_addr, buf, options)
|
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,
|
&'a mut self,
|
||||||
peri_addr: *mut W,
|
peri_addr: *mut PW,
|
||||||
buf: *mut [W],
|
buf: *mut [MW],
|
||||||
options: TransferOptions,
|
options: TransferOptions,
|
||||||
) -> Transfer<'a> {
|
) -> Transfer<'a> {
|
||||||
Transfer::new_read_raw(self.channel.reborrow(), self.request, peri_addr, buf, options)
|
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);
|
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 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();
|
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
|
// 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_end_time = Instant::now();
|
||||||
let sw_execution_time = sw_end_time - sw_start_time;
|
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()]);
|
defmt::assert!(encrypt_tag == payload_vec[ciphertext.len()..ciphertext.len() + encrypt_tag.len()]);
|
||||||
|
|
||||||
// Decrypt in software using AES-GCM 128-bit
|
// 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");
|
info!("Test OK");
|
||||||
cortex_m::asm::bkpt();
|
cortex_m::asm::bkpt();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user