diff options
| author | Dario Nieuwenhuis <[email protected]> | 2024-04-15 21:47:37 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2024-04-15 21:52:40 +0200 |
| commit | 02da66aec8432f71b8f3121a972044191df2d7e8 (patch) | |
| tree | 7ad749dd02caa40949f2d7892da13e15dc6ef3f9 | |
| parent | d66c054aae616616377c7bcee47f5de8a312d085 (diff) | |
stm32/dma: add ChannelAndRequest helper.
| -rw-r--r-- | embassy-stm32/src/dma/mod.rs | 3 | ||||
| -rw-r--r-- | embassy-stm32/src/dma/util.rs | 60 | ||||
| -rw-r--r-- | embassy-stm32/src/spi/mod.rs | 40 | ||||
| -rw-r--r-- | embassy-stm32/src/traits.rs | 7 |
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)] |
| 17 | pub use dmamux::*; | 17 | pub use dmamux::*; |
| 18 | 18 | ||
| 19 | mod util; | ||
| 20 | pub(crate) use util::*; | ||
| 21 | |||
| 19 | pub(crate) mod ringbuffer; | 22 | pub(crate) mod ringbuffer; |
| 20 | pub mod word; | 23 | pub 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 @@ | |||
| 1 | use embassy_hal_internal::PeripheralRef; | ||
| 2 | |||
| 3 | use super::word::Word; | ||
| 4 | use 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. | ||
| 9 | pub(crate) struct ChannelAndRequest<'d> { | ||
| 10 | pub channel: PeripheralRef<'d, AnyChannel>, | ||
| 11 | pub request: Request, | ||
| 12 | } | ||
| 13 | |||
| 14 | impl<'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; | |||
| 9 | use embassy_hal_internal::{into_ref, PeripheralRef}; | 9 | use embassy_hal_internal::{into_ref, PeripheralRef}; |
| 10 | pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; | 10 | pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; |
| 11 | 11 | ||
| 12 | use crate::dma::{slice_ptr_parts, word, AnyChannel, Request, Transfer}; | 12 | use crate::dma::{slice_ptr_parts, word, ChannelAndRequest}; |
| 13 | use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _, Speed}; | 13 | use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _, Speed}; |
| 14 | use crate::mode::{Async, Blocking, Mode as PeriMode}; | 14 | use crate::mode::{Async, Blocking, Mode as PeriMode}; |
| 15 | use crate::pac::spi::{regs, vals, Spi as Regs}; | 15 | use 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 { | |||
| 73 | macro_rules! new_dma { | 73 | macro_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 | ||
