aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/dma/mod.rs3
-rw-r--r--embassy-stm32/src/dma/util.rs60
-rw-r--r--embassy-stm32/src/spi/mod.rs40
-rw-r--r--embassy-stm32/src/traits.rs7
4 files changed, 86 insertions, 24 deletions
diff --git a/embassy-stm32/src/dma/mod.rs b/embassy-stm32/src/dma/mod.rs
index 7e3681469..8766d0a60 100644
--- a/embassy-stm32/src/dma/mod.rs
+++ b/embassy-stm32/src/dma/mod.rs
@@ -16,6 +16,9 @@ mod dmamux;
16#[cfg(dmamux)] 16#[cfg(dmamux)]
17pub use dmamux::*; 17pub use dmamux::*;
18 18
19mod util;
20pub(crate) use util::*;
21
19pub(crate) mod ringbuffer; 22pub(crate) mod ringbuffer;
20pub mod word; 23pub mod word;
21 24
diff --git a/embassy-stm32/src/dma/util.rs b/embassy-stm32/src/dma/util.rs
new file mode 100644
index 000000000..962ea2501
--- /dev/null
+++ b/embassy-stm32/src/dma/util.rs
@@ -0,0 +1,60 @@
1use embassy_hal_internal::PeripheralRef;
2
3use super::word::Word;
4use super::{AnyChannel, Request, Transfer, TransferOptions};
5
6/// Convenience wrapper, contains a channel and a request number.
7///
8/// Commonly used in peripheral drivers that own DMA channels.
9pub(crate) struct ChannelAndRequest<'d> {
10 pub channel: PeripheralRef<'d, AnyChannel>,
11 pub request: Request,
12}
13
14impl<'d> ChannelAndRequest<'d> {
15 pub unsafe fn read<'a, W: Word>(
16 &'a mut self,
17 peri_addr: *mut W,
18 buf: &'a mut [W],
19 options: TransferOptions,
20 ) -> Transfer<'a> {
21 Transfer::new_read(&mut self.channel, self.request, peri_addr, buf, options)
22 }
23
24 pub unsafe fn read_raw<'a, W: Word>(
25 &'a mut self,
26 peri_addr: *mut W,
27 buf: *mut [W],
28 options: TransferOptions,
29 ) -> Transfer<'a> {
30 Transfer::new_read_raw(&mut self.channel, self.request, peri_addr, buf, options)
31 }
32
33 pub unsafe fn write<'a, W: Word>(
34 &'a mut self,
35 buf: &'a [W],
36 peri_addr: *mut W,
37 options: TransferOptions,
38 ) -> Transfer<'a> {
39 Transfer::new_write(&mut self.channel, self.request, buf, peri_addr, options)
40 }
41
42 pub unsafe fn write_raw<'a, W: Word>(
43 &'a mut self,
44 buf: *const [W],
45 peri_addr: *mut W,
46 options: TransferOptions,
47 ) -> Transfer<'a> {
48 Transfer::new_write_raw(&mut self.channel, self.request, buf, peri_addr, options)
49 }
50
51 pub unsafe fn write_repeated<'a, W: Word>(
52 &'a mut self,
53 repeated: &'a W,
54 count: usize,
55 peri_addr: *mut W,
56 options: TransferOptions,
57 ) -> Transfer<'a> {
58 Transfer::new_write_repeated(&mut self.channel, self.request, repeated, count, peri_addr, options)
59 }
60}
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs
index a4465e289..303b85346 100644
--- a/embassy-stm32/src/spi/mod.rs
+++ b/embassy-stm32/src/spi/mod.rs
@@ -9,7 +9,7 @@ use embassy_futures::join::join;
9use embassy_hal_internal::{into_ref, PeripheralRef}; 9use embassy_hal_internal::{into_ref, PeripheralRef};
10pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; 10pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
11 11
12use crate::dma::{slice_ptr_parts, word, AnyChannel, Request, Transfer}; 12use crate::dma::{slice_ptr_parts, word, ChannelAndRequest};
13use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _, Speed}; 13use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _, Speed};
14use crate::mode::{Async, Blocking, Mode as PeriMode}; 14use crate::mode::{Async, Blocking, Mode as PeriMode};
15use crate::pac::spi::{regs, vals, Spi as Regs}; 15use crate::pac::spi::{regs, vals, Spi as Regs};
@@ -97,8 +97,8 @@ pub struct Spi<'d, T: Instance, M: PeriMode> {
97 sck: Option<PeripheralRef<'d, AnyPin>>, 97 sck: Option<PeripheralRef<'d, AnyPin>>,
98 mosi: Option<PeripheralRef<'d, AnyPin>>, 98 mosi: Option<PeripheralRef<'d, AnyPin>>,
99 miso: Option<PeripheralRef<'d, AnyPin>>, 99 miso: Option<PeripheralRef<'d, AnyPin>>,
100 txdma: Option<(PeripheralRef<'d, AnyChannel>, Request)>, 100 txdma: Option<ChannelAndRequest<'d>>,
101 rxdma: Option<(PeripheralRef<'d, AnyChannel>, Request)>, 101 rxdma: Option<ChannelAndRequest<'d>>,
102 _phantom: PhantomData<M>, 102 _phantom: PhantomData<M>,
103 current_word_size: word_impl::Config, 103 current_word_size: word_impl::Config,
104} 104}
@@ -109,8 +109,8 @@ impl<'d, T: Instance, M: PeriMode> Spi<'d, T, M> {
109 sck: Option<PeripheralRef<'d, AnyPin>>, 109 sck: Option<PeripheralRef<'d, AnyPin>>,
110 mosi: Option<PeripheralRef<'d, AnyPin>>, 110 mosi: Option<PeripheralRef<'d, AnyPin>>,
111 miso: Option<PeripheralRef<'d, AnyPin>>, 111 miso: Option<PeripheralRef<'d, AnyPin>>,
112 txdma: Option<(PeripheralRef<'d, AnyChannel>, Request)>, 112 txdma: Option<ChannelAndRequest<'d>>,
113 rxdma: Option<(PeripheralRef<'d, AnyChannel>, Request)>, 113 rxdma: Option<ChannelAndRequest<'d>>,
114 config: Config, 114 config: Config,
115 ) -> Self { 115 ) -> Self {
116 into_ref!(peri); 116 into_ref!(peri);
@@ -593,9 +593,8 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
593 w.set_spe(false); 593 w.set_spe(false);
594 }); 594 });
595 595
596 let (txdma, tx_request) = self.txdma.as_mut().unwrap();
597 let tx_dst = T::REGS.tx_ptr(); 596 let tx_dst = T::REGS.tx_ptr();
598 let tx_f = unsafe { Transfer::new_write(txdma, *tx_request, data, tx_dst, Default::default()) }; 597 let tx_f = unsafe { self.txdma.as_mut().unwrap().write(data, tx_dst, Default::default()) };
599 598
600 set_txdmaen(T::REGS, true); 599 set_txdmaen(T::REGS, true);
601 T::REGS.cr1().modify(|w| { 600 T::REGS.cr1().modify(|w| {
@@ -632,22 +631,16 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
632 631
633 let clock_byte_count = data.len(); 632 let clock_byte_count = data.len();
634 633
635 let (rxdma, rx_request) = self.rxdma.as_mut().unwrap();
636 let rx_src = T::REGS.rx_ptr(); 634 let rx_src = T::REGS.rx_ptr();
637 let rx_f = unsafe { Transfer::new_read(rxdma, *rx_request, rx_src, data, Default::default()) }; 635 let rx_f = unsafe { self.rxdma.as_mut().unwrap().read(rx_src, data, Default::default()) };
638 636
639 let (txdma, tx_request) = self.txdma.as_mut().unwrap();
640 let tx_dst = T::REGS.tx_ptr(); 637 let tx_dst = T::REGS.tx_ptr();
641 let clock_byte = 0x00u8; 638 let clock_byte = 0x00u8;
642 let tx_f = unsafe { 639 let tx_f = unsafe {
643 Transfer::new_write_repeated( 640 self.txdma
644 txdma, 641 .as_mut()
645 *tx_request, 642 .unwrap()
646 &clock_byte, 643 .write_repeated(&clock_byte, clock_byte_count, tx_dst, Default::default())
647 clock_byte_count,
648 tx_dst,
649 Default::default(),
650 )
651 }; 644 };
652 645
653 set_txdmaen(T::REGS, true); 646 set_txdmaen(T::REGS, true);
@@ -685,13 +678,16 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
685 678
686 set_rxdmaen(T::REGS, true); 679 set_rxdmaen(T::REGS, true);
687 680
688 let (rxdma, rx_request) = self.rxdma.as_mut().unwrap();
689 let rx_src = T::REGS.rx_ptr(); 681 let rx_src = T::REGS.rx_ptr();
690 let rx_f = unsafe { Transfer::new_read_raw(rxdma, *rx_request, rx_src, read, Default::default()) }; 682 let rx_f = unsafe { self.rxdma.as_mut().unwrap().read_raw(rx_src, read, Default::default()) };
691 683
692 let (txdma, tx_request) = self.txdma.as_mut().unwrap();
693 let tx_dst = T::REGS.tx_ptr(); 684 let tx_dst = T::REGS.tx_ptr();
694 let tx_f = unsafe { Transfer::new_write_raw(txdma, *tx_request, write, tx_dst, Default::default()) }; 685 let tx_f = unsafe {
686 self.txdma
687 .as_mut()
688 .unwrap()
689 .write_raw(write, tx_dst, Default::default())
690 };
695 691
696 set_txdmaen(T::REGS, true); 692 set_txdmaen(T::REGS, true);
697 T::REGS.cr1().modify(|w| { 693 T::REGS.cr1().modify(|w| {
diff --git a/embassy-stm32/src/traits.rs b/embassy-stm32/src/traits.rs
index 539302c49..f603f661f 100644
--- a/embassy-stm32/src/traits.rs
+++ b/embassy-stm32/src/traits.rs
@@ -73,8 +73,11 @@ macro_rules! dma_trait_impl {
73macro_rules! new_dma { 73macro_rules! new_dma {
74 ($name:ident) => {{ 74 ($name:ident) => {{
75 let dma = $name.into_ref(); 75 let dma = $name.into_ref();
76 let req = dma.request(); 76 let request = dma.request();
77 Some((dma.map_into(), req)) 77 Some(crate::dma::ChannelAndRequest {
78 channel: dma.map_into(),
79 request,
80 })
78 }}; 81 }};
79} 82}
80 83