diff options
| -rw-r--r-- | embassy-stm32/src/cryp/mod.rs | 13 | ||||
| -rw-r--r-- | embassy-stm32/src/dma/dma_bdma.rs | 63 | ||||
| -rw-r--r-- | embassy-stm32/src/dma/gpdma.rs | 12 | ||||
| -rw-r--r-- | embassy-stm32/src/dma/util.rs | 6 | ||||
| -rw-r--r-- | embassy-stm32/src/spi/mod.rs | 2 | ||||
| -rw-r--r-- | examples/stm32f7/src/bin/cryp.rs | 4 | ||||
| -rw-r--r-- | tests/stm32/src/bin/cryp.rs | 2 |
7 files changed, 57 insertions, 45 deletions
diff --git a/embassy-stm32/src/cryp/mod.rs b/embassy-stm32/src/cryp/mod.rs index fba3c0fd7..35d9f8cce 100644 --- a/embassy-stm32/src/cryp/mod.rs +++ b/embassy-stm32/src/cryp/mod.rs | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] | 2 | #[cfg(any(cryp_v2, cryp_v3, cryp_v4))] |
| 3 | use core::cmp::min; | 3 | use core::cmp::min; |
| 4 | use core::marker::PhantomData; | 4 | use core::marker::PhantomData; |
| 5 | use core::ptr; | ||
| 6 | 5 | ||
| 7 | use embassy_hal_internal::{Peri, PeripheralType}; | 6 | use embassy_hal_internal::{Peri, PeripheralType}; |
| 8 | use embassy_sync::waitqueue::AtomicWaker; | 7 | use embassy_sync::waitqueue::AtomicWaker; |
| @@ -1814,14 +1813,12 @@ impl<'d, T: Instance> Cryp<'d, T, Async> { | |||
| 1814 | assert_eq!(blocks.len() % block_size, 0); | 1813 | assert_eq!(blocks.len() % block_size, 0); |
| 1815 | // Configure DMA to transfer input to crypto core. | 1814 | // Configure DMA to transfer input to crypto core. |
| 1816 | let dst_ptr: *mut u32 = T::regs().din().as_ptr(); | 1815 | let dst_ptr: *mut u32 = T::regs().din().as_ptr(); |
| 1817 | let num_words = blocks.len() / 4; | ||
| 1818 | let src_ptr: *const [u8] = ptr::slice_from_raw_parts(blocks.as_ptr().cast(), num_words); | ||
| 1819 | let options = TransferOptions { | 1816 | let options = TransferOptions { |
| 1820 | #[cfg(not(gpdma))] | 1817 | #[cfg(not(gpdma))] |
| 1821 | priority: crate::dma::Priority::High, | 1818 | priority: crate::dma::Priority::High, |
| 1822 | ..Default::default() | 1819 | ..Default::default() |
| 1823 | }; | 1820 | }; |
| 1824 | let dma_transfer = unsafe { dma.write_raw(src_ptr, dst_ptr, options) }; | 1821 | let dma_transfer = unsafe { dma.write_raw(blocks, dst_ptr, options) }; |
| 1825 | T::regs().dmacr().modify(|w| w.set_dien(true)); | 1822 | T::regs().dmacr().modify(|w| w.set_dien(true)); |
| 1826 | // Wait for the transfer to complete. | 1823 | // Wait for the transfer to complete. |
| 1827 | dma_transfer.await; | 1824 | dma_transfer.await; |
| @@ -1836,14 +1833,12 @@ impl<'d, T: Instance> Cryp<'d, T, Async> { | |||
| 1836 | assert_eq!((blocks.len() * 4) % block_size, 0); | 1833 | assert_eq!((blocks.len() * 4) % block_size, 0); |
| 1837 | // Configure DMA to transfer input to crypto core. | 1834 | // Configure DMA to transfer input to crypto core. |
| 1838 | let dst_ptr: *mut u32 = T::regs().din().as_ptr(); | 1835 | let dst_ptr: *mut u32 = T::regs().din().as_ptr(); |
| 1839 | let num_words = blocks.len(); | ||
| 1840 | let src_ptr: *const [u32] = ptr::slice_from_raw_parts(blocks.as_ptr().cast(), num_words); | ||
| 1841 | let options = TransferOptions { | 1836 | let options = TransferOptions { |
| 1842 | #[cfg(not(gpdma))] | 1837 | #[cfg(not(gpdma))] |
| 1843 | priority: crate::dma::Priority::High, | 1838 | priority: crate::dma::Priority::High, |
| 1844 | ..Default::default() | 1839 | ..Default::default() |
| 1845 | }; | 1840 | }; |
| 1846 | let dma_transfer = unsafe { dma.write_raw(src_ptr, dst_ptr, options) }; | 1841 | let dma_transfer = unsafe { dma.write_raw(blocks, dst_ptr, options) }; |
| 1847 | T::regs().dmacr().modify(|w| w.set_dien(true)); | 1842 | T::regs().dmacr().modify(|w| w.set_dien(true)); |
| 1848 | // Wait for the transfer to complete. | 1843 | // Wait for the transfer to complete. |
| 1849 | dma_transfer.await; | 1844 | dma_transfer.await; |
| @@ -1857,14 +1852,12 @@ impl<'d, T: Instance> Cryp<'d, T, Async> { | |||
| 1857 | assert_eq!(blocks.len() % block_size, 0); | 1852 | assert_eq!(blocks.len() % block_size, 0); |
| 1858 | // Configure DMA to get output from crypto core. | 1853 | // Configure DMA to get output from crypto core. |
| 1859 | let src_ptr = T::regs().dout().as_ptr(); | 1854 | let src_ptr = T::regs().dout().as_ptr(); |
| 1860 | let num_words = blocks.len() / 4; | ||
| 1861 | let dst_ptr = ptr::slice_from_raw_parts_mut(blocks.as_mut_ptr().cast(), num_words); | ||
| 1862 | let options = TransferOptions { | 1855 | let options = TransferOptions { |
| 1863 | #[cfg(not(gpdma))] | 1856 | #[cfg(not(gpdma))] |
| 1864 | priority: crate::dma::Priority::VeryHigh, | 1857 | priority: crate::dma::Priority::VeryHigh, |
| 1865 | ..Default::default() | 1858 | ..Default::default() |
| 1866 | }; | 1859 | }; |
| 1867 | let dma_transfer = unsafe { dma.read_raw(src_ptr, dst_ptr, options) }; | 1860 | let dma_transfer = unsafe { dma.read_raw(src_ptr, blocks, options) }; |
| 1868 | T::regs().dmacr().modify(|w| w.set_doen(true)); | 1861 | T::regs().dmacr().modify(|w| w.set_doen(true)); |
| 1869 | // Wait for the transfer to complete. | 1862 | // Wait for the transfer to complete. |
| 1870 | dma_transfer.await; | 1863 | dma_transfer.await; |
diff --git a/embassy-stm32/src/dma/dma_bdma.rs b/embassy-stm32/src/dma/dma_bdma.rs index caf135989..464823bfc 100644 --- a/embassy-stm32/src/dma/dma_bdma.rs +++ b/embassy-stm32/src/dma/dma_bdma.rs | |||
| @@ -341,7 +341,7 @@ impl AnyChannel { | |||
| 341 | mem_len: usize, | 341 | mem_len: usize, |
| 342 | incr_mem: bool, | 342 | incr_mem: bool, |
| 343 | mem_size: WordSize, | 343 | mem_size: WordSize, |
| 344 | peripheral_size: WordSize, | 344 | peri_size: WordSize, |
| 345 | options: TransferOptions, | 345 | options: TransferOptions, |
| 346 | ) { | 346 | ) { |
| 347 | // "Preceding reads and writes cannot be moved past subsequent writes." | 347 | // "Preceding reads and writes cannot be moved past subsequent writes." |
| @@ -357,8 +357,6 @@ impl AnyChannel { | |||
| 357 | #[cfg(dmamux)] | 357 | #[cfg(dmamux)] |
| 358 | super::dmamux::configure_dmamux(&info.dmamux, _request); | 358 | super::dmamux::configure_dmamux(&info.dmamux, _request); |
| 359 | 359 | ||
| 360 | assert!(mem_len > 0 && mem_len <= 0xFFFF); | ||
| 361 | |||
| 362 | match self.info().dma { | 360 | match self.info().dma { |
| 363 | #[cfg(dma)] | 361 | #[cfg(dma)] |
| 364 | DmaInfo::Dma(r) => { | 362 | DmaInfo::Dma(r) => { |
| @@ -368,14 +366,39 @@ impl AnyChannel { | |||
| 368 | state.complete_count.store(0, Ordering::Release); | 366 | state.complete_count.store(0, Ordering::Release); |
| 369 | self.clear_irqs(); | 367 | self.clear_irqs(); |
| 370 | 368 | ||
| 369 | // NDTR is the number of transfers in the *peripheral* word size. | ||
| 370 | // ex: if mem_size=1, peri_size=4 and ndtr=3 it'll do 12 mem transfers, 3 peri transfers. | ||
| 371 | let ndtr = match (mem_size, peri_size) { | ||
| 372 | (WordSize::FourBytes, WordSize::OneByte) => mem_len * 4, | ||
| 373 | (WordSize::FourBytes, WordSize::TwoBytes) | (WordSize::TwoBytes, WordSize::OneByte) => mem_len * 2, | ||
| 374 | (WordSize::FourBytes, WordSize::FourBytes) | ||
| 375 | | (WordSize::TwoBytes, WordSize::TwoBytes) | ||
| 376 | | (WordSize::OneByte, WordSize::OneByte) => mem_len, | ||
| 377 | (WordSize::TwoBytes, WordSize::FourBytes) | (WordSize::OneByte, WordSize::TwoBytes) => { | ||
| 378 | assert!(mem_len % 2 == 0); | ||
| 379 | mem_len / 2 | ||
| 380 | } | ||
| 381 | (WordSize::OneByte, WordSize::FourBytes) => { | ||
| 382 | assert!(mem_len % 4 == 0); | ||
| 383 | mem_len / 4 | ||
| 384 | } | ||
| 385 | }; | ||
| 386 | |||
| 387 | assert!(ndtr > 0 && ndtr <= 0xFFFF); | ||
| 388 | |||
| 371 | ch.par().write_value(peri_addr as u32); | 389 | ch.par().write_value(peri_addr as u32); |
| 372 | ch.m0ar().write_value(mem_addr as u32); | 390 | ch.m0ar().write_value(mem_addr as u32); |
| 373 | ch.ndtr().write_value(pac::dma::regs::Ndtr(mem_len as _)); | 391 | ch.ndtr().write_value(pac::dma::regs::Ndtr(ndtr as _)); |
| 374 | ch.fcr().write(|w| { | 392 | ch.fcr().write(|w| { |
| 375 | if let Some(fth) = options.fifo_threshold { | 393 | if let Some(fth) = options.fifo_threshold { |
| 376 | // FIFO mode | 394 | // FIFO mode |
| 377 | w.set_dmdis(pac::dma::vals::Dmdis::DISABLED); | 395 | w.set_dmdis(pac::dma::vals::Dmdis::DISABLED); |
| 378 | w.set_fth(fth.into()); | 396 | w.set_fth(fth.into()); |
| 397 | } else if mem_size != peri_size { | ||
| 398 | // force FIFO mode if msize != psize | ||
| 399 | // packing/unpacking doesn't work in direct mode. | ||
| 400 | w.set_dmdis(pac::dma::vals::Dmdis::DISABLED); | ||
| 401 | w.set_fth(FifoThreshold::Half.into()); | ||
| 379 | } else { | 402 | } else { |
| 380 | // Direct mode | 403 | // Direct mode |
| 381 | w.set_dmdis(pac::dma::vals::Dmdis::ENABLED); | 404 | w.set_dmdis(pac::dma::vals::Dmdis::ENABLED); |
| @@ -384,7 +407,7 @@ impl AnyChannel { | |||
| 384 | ch.cr().write(|w| { | 407 | ch.cr().write(|w| { |
| 385 | w.set_dir(dir.into()); | 408 | w.set_dir(dir.into()); |
| 386 | w.set_msize(mem_size.into()); | 409 | w.set_msize(mem_size.into()); |
| 387 | w.set_psize(peripheral_size.into()); | 410 | w.set_psize(peri_size.into()); |
| 388 | w.set_pl(options.priority.into()); | 411 | w.set_pl(options.priority.into()); |
| 389 | w.set_minc(incr_mem); | 412 | w.set_minc(incr_mem); |
| 390 | w.set_pinc(false); | 413 | w.set_pinc(false); |
| @@ -404,6 +427,8 @@ impl AnyChannel { | |||
| 404 | } | 427 | } |
| 405 | #[cfg(bdma)] | 428 | #[cfg(bdma)] |
| 406 | DmaInfo::Bdma(r) => { | 429 | DmaInfo::Bdma(r) => { |
| 430 | assert!(mem_len > 0 && mem_len <= 0xFFFF); | ||
| 431 | |||
| 407 | #[cfg(bdma_v2)] | 432 | #[cfg(bdma_v2)] |
| 408 | critical_section::with(|_| r.cselr().modify(|w| w.set_cs(info.num, _request))); | 433 | critical_section::with(|_| r.cselr().modify(|w| w.set_cs(info.num, _request))); |
| 409 | 434 | ||
| @@ -417,7 +442,7 @@ impl AnyChannel { | |||
| 417 | ch.mar().write_value(mem_addr as u32); | 442 | ch.mar().write_value(mem_addr as u32); |
| 418 | ch.ndtr().write(|w| w.set_ndt(mem_len as u16)); | 443 | ch.ndtr().write(|w| w.set_ndt(mem_len as u16)); |
| 419 | ch.cr().write(|w| { | 444 | ch.cr().write(|w| { |
| 420 | w.set_psize(peripheral_size.into()); | 445 | w.set_psize(peri_size.into()); |
| 421 | w.set_msize(mem_size.into()); | 446 | w.set_msize(mem_size.into()); |
| 422 | w.set_minc(incr_mem); | 447 | w.set_minc(incr_mem); |
| 423 | w.set_dir(dir.into()); | 448 | w.set_dir(dir.into()); |
| @@ -587,11 +612,11 @@ impl<'a> Transfer<'a> { | |||
| 587 | } | 612 | } |
| 588 | 613 | ||
| 589 | /// Create a new read DMA transfer (peripheral to memory), using raw pointers. | 614 | /// Create a new read DMA transfer (peripheral to memory), using raw pointers. |
| 590 | pub unsafe fn new_read_raw<W: Word>( | 615 | pub unsafe fn new_read_raw<MW: Word, PW: Word>( |
| 591 | channel: Peri<'a, impl Channel>, | 616 | channel: Peri<'a, impl Channel>, |
| 592 | request: Request, | 617 | request: Request, |
| 593 | peri_addr: *mut W, | 618 | peri_addr: *mut PW, |
| 594 | buf: *mut [W], | 619 | buf: *mut [MW], |
| 595 | options: TransferOptions, | 620 | options: TransferOptions, |
| 596 | ) -> Self { | 621 | ) -> Self { |
| 597 | Self::new_inner( | 622 | Self::new_inner( |
| @@ -599,11 +624,11 @@ impl<'a> Transfer<'a> { | |||
| 599 | request, | 624 | request, |
| 600 | Dir::PeripheralToMemory, | 625 | Dir::PeripheralToMemory, |
| 601 | peri_addr as *const u32, | 626 | peri_addr as *const u32, |
| 602 | buf as *mut W as *mut u32, | 627 | buf as *mut MW as *mut u32, |
| 603 | buf.len(), | 628 | buf.len(), |
| 604 | true, | 629 | true, |
| 605 | W::size(), | 630 | MW::size(), |
| 606 | W::size(), | 631 | PW::size(), |
| 607 | options, | 632 | options, |
| 608 | ) | 633 | ) |
| 609 | } | 634 | } |
| @@ -672,22 +697,14 @@ impl<'a> Transfer<'a> { | |||
| 672 | mem_addr: *mut u32, | 697 | mem_addr: *mut u32, |
| 673 | mem_len: usize, | 698 | mem_len: usize, |
| 674 | incr_mem: bool, | 699 | incr_mem: bool, |
| 675 | data_size: WordSize, | 700 | mem_size: WordSize, |
| 676 | peripheral_size: WordSize, | 701 | peri_size: WordSize, |
| 677 | options: TransferOptions, | 702 | options: TransferOptions, |
| 678 | ) -> Self { | 703 | ) -> Self { |
| 679 | assert!(mem_len > 0 && mem_len <= 0xFFFF); | 704 | assert!(mem_len > 0 && mem_len <= 0xFFFF); |
| 680 | 705 | ||
| 681 | channel.configure( | 706 | channel.configure( |
| 682 | _request, | 707 | _request, dir, peri_addr, mem_addr, mem_len, incr_mem, mem_size, peri_size, options, |
| 683 | dir, | ||
| 684 | peri_addr, | ||
| 685 | mem_addr, | ||
| 686 | mem_len, | ||
| 687 | incr_mem, | ||
| 688 | data_size, | ||
| 689 | peripheral_size, | ||
| 690 | options, | ||
| 691 | ); | 708 | ); |
| 692 | channel.start(); | 709 | channel.start(); |
| 693 | Self { channel } | 710 | Self { channel } |
diff --git a/embassy-stm32/src/dma/gpdma.rs b/embassy-stm32/src/dma/gpdma.rs index ade70fb55..151e4ab9f 100644 --- a/embassy-stm32/src/dma/gpdma.rs +++ b/embassy-stm32/src/dma/gpdma.rs | |||
| @@ -125,11 +125,11 @@ impl<'a> Transfer<'a> { | |||
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | /// Create a new read DMA transfer (peripheral to memory), using raw pointers. | 127 | /// Create a new read DMA transfer (peripheral to memory), using raw pointers. |
| 128 | pub unsafe fn new_read_raw<W: Word>( | 128 | pub unsafe fn new_read_raw<MW: Word, PW: Word>( |
| 129 | channel: Peri<'a, impl Channel>, | 129 | channel: Peri<'a, impl Channel>, |
| 130 | request: Request, | 130 | request: Request, |
| 131 | peri_addr: *mut W, | 131 | peri_addr: *mut PW, |
| 132 | buf: *mut [W], | 132 | buf: *mut [MW], |
| 133 | options: TransferOptions, | 133 | options: TransferOptions, |
| 134 | ) -> Self { | 134 | ) -> Self { |
| 135 | Self::new_inner( | 135 | Self::new_inner( |
| @@ -137,11 +137,11 @@ impl<'a> Transfer<'a> { | |||
| 137 | request, | 137 | request, |
| 138 | Dir::PeripheralToMemory, | 138 | Dir::PeripheralToMemory, |
| 139 | peri_addr as *const u32, | 139 | peri_addr as *const u32, |
| 140 | buf as *mut W as *mut u32, | 140 | buf as *mut MW as *mut u32, |
| 141 | buf.len(), | 141 | buf.len(), |
| 142 | true, | 142 | true, |
| 143 | W::size(), | 143 | PW::size(), |
| 144 | W::size(), | 144 | MW::size(), |
| 145 | options, | 145 | options, |
| 146 | ) | 146 | ) |
| 147 | } | 147 | } |
diff --git a/embassy-stm32/src/dma/util.rs b/embassy-stm32/src/dma/util.rs index 8bf89e2fe..3245887c1 100644 --- a/embassy-stm32/src/dma/util.rs +++ b/embassy-stm32/src/dma/util.rs | |||
| @@ -20,10 +20,10 @@ impl<'d> ChannelAndRequest<'d> { | |||
| 20 | Transfer::new_read(self.channel.reborrow(), self.request, peri_addr, buf, options) | 20 | Transfer::new_read(self.channel.reborrow(), self.request, peri_addr, buf, options) |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | pub unsafe fn read_raw<'a, W: Word>( | 23 | pub unsafe fn read_raw<'a, MW: Word, PW: Word>( |
| 24 | &'a mut self, | 24 | &'a mut self, |
| 25 | peri_addr: *mut W, | 25 | peri_addr: *mut PW, |
| 26 | buf: *mut [W], | 26 | buf: *mut [MW], |
| 27 | options: TransferOptions, | 27 | options: TransferOptions, |
| 28 | ) -> Transfer<'a> { | 28 | ) -> Transfer<'a> { |
| 29 | Transfer::new_read_raw(self.channel.reborrow(), self.request, peri_addr, buf, options) | 29 | Transfer::new_read_raw(self.channel.reborrow(), self.request, peri_addr, buf, options) |
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index 9e2ba093a..c8d83f07e 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs | |||
| @@ -843,7 +843,7 @@ impl<'d> Spi<'d, Async> { | |||
| 843 | 843 | ||
| 844 | set_rxdmaen(self.info.regs, true); | 844 | set_rxdmaen(self.info.regs, true); |
| 845 | 845 | ||
| 846 | let rx_src = self.info.regs.rx_ptr(); | 846 | let rx_src = self.info.regs.rx_ptr::<W>(); |
| 847 | let rx_f = unsafe { self.rx_dma.as_mut().unwrap().read_raw(rx_src, read, Default::default()) }; | 847 | let rx_f = unsafe { self.rx_dma.as_mut().unwrap().read_raw(rx_src, read, Default::default()) }; |
| 848 | 848 | ||
| 849 | let tx_dst: *mut W = self.info.regs.tx_ptr(); | 849 | let tx_dst: *mut W = self.info.regs.tx_ptr(); |
diff --git a/examples/stm32f7/src/bin/cryp.rs b/examples/stm32f7/src/bin/cryp.rs index 235853cb9..a31e9b4f2 100644 --- a/examples/stm32f7/src/bin/cryp.rs +++ b/examples/stm32f7/src/bin/cryp.rs | |||
| @@ -68,7 +68,9 @@ async fn main(_spawner: Spawner) -> ! { | |||
| 68 | ); | 68 | ); |
| 69 | 69 | ||
| 70 | // Decrypt in software using AES-GCM 128-bit | 70 | // Decrypt in software using AES-GCM 128-bit |
| 71 | let _ = cipher.decrypt_in_place(&iv.into(), aad.into(), &mut payload_vec); | 71 | cipher |
| 72 | .decrypt_in_place(&iv.into(), aad.into(), &mut payload_vec) | ||
| 73 | .unwrap(); | ||
| 72 | 74 | ||
| 73 | let sw_end_time = Instant::now(); | 75 | let sw_end_time = Instant::now(); |
| 74 | let sw_execution_time = sw_end_time - sw_start_time; | 76 | let sw_execution_time = sw_end_time - sw_start_time; |
diff --git a/tests/stm32/src/bin/cryp.rs b/tests/stm32/src/bin/cryp.rs index 028775ac8..f54c99cc3 100644 --- a/tests/stm32/src/bin/cryp.rs +++ b/tests/stm32/src/bin/cryp.rs | |||
| @@ -72,7 +72,7 @@ async fn main(_spawner: Spawner) { | |||
| 72 | defmt::assert!(encrypt_tag == payload_vec[ciphertext.len()..ciphertext.len() + encrypt_tag.len()]); | 72 | defmt::assert!(encrypt_tag == payload_vec[ciphertext.len()..ciphertext.len() + encrypt_tag.len()]); |
| 73 | 73 | ||
| 74 | // Decrypt in software using AES-GCM 128-bit | 74 | // Decrypt in software using AES-GCM 128-bit |
| 75 | let _ = cipher.decrypt_in_place(&iv.into(), &aad, &mut payload_vec); | 75 | cipher.decrypt_in_place(&iv.into(), &aad, &mut payload_vec).unwrap(); |
| 76 | 76 | ||
| 77 | info!("Test OK"); | 77 | info!("Test OK"); |
| 78 | cortex_m::asm::bkpt(); | 78 | cortex_m::asm::bkpt(); |
