diff options
| author | Bob McWhirter <[email protected]> | 2021-07-20 15:20:16 -0400 |
|---|---|---|
| committer | Bob McWhirter <[email protected]> | 2021-07-23 13:22:39 -0400 |
| commit | 4c5a234a3aff07077cba4e8fe42feb10ed8458bd (patch) | |
| tree | f1a351cb2c77e58e29b7021b08ca753c12c2b95a | |
| parent | 7bbad4c4e577c310a15667543e3670d205e29c8f (diff) | |
Add a non-minc write() to DMA which takes a count.
Use it from "read-only" SPI.
| -rw-r--r-- | embassy-stm32/src/dma/bdma.rs | 29 | ||||
| -rw-r--r-- | embassy-stm32/src/dma/dma.rs | 29 | ||||
| -rw-r--r-- | embassy-stm32/src/dma/mod.rs | 8 | ||||
| -rw-r--r-- | embassy-stm32/src/spi/mod.rs | 4 | ||||
| -rw-r--r-- | embassy-stm32/src/spi/v3.rs | 52 |
5 files changed, 115 insertions, 7 deletions
diff --git a/embassy-stm32/src/dma/bdma.rs b/embassy-stm32/src/dma/bdma.rs index e2da2a8ea..46670e1be 100644 --- a/embassy-stm32/src/dma/bdma.rs +++ b/embassy-stm32/src/dma/bdma.rs | |||
| @@ -47,6 +47,7 @@ pub(crate) unsafe fn do_transfer( | |||
| 47 | peri_addr: *const u8, | 47 | peri_addr: *const u8, |
| 48 | mem_addr: *mut u8, | 48 | mem_addr: *mut u8, |
| 49 | mem_len: usize, | 49 | mem_len: usize, |
| 50 | incr_mem: bool, | ||
| 50 | #[cfg(dmamux)] dmamux_regs: pac::dmamux::Dmamux, | 51 | #[cfg(dmamux)] dmamux_regs: pac::dmamux::Dmamux, |
| 51 | #[cfg(dmamux)] dmamux_ch_num: u8, | 52 | #[cfg(dmamux)] dmamux_ch_num: u8, |
| 52 | ) -> impl Future<Output = ()> { | 53 | ) -> impl Future<Output = ()> { |
| @@ -182,6 +183,7 @@ pac::dma_channels! { | |||
| 182 | src, | 183 | src, |
| 183 | buf.as_mut_ptr(), | 184 | buf.as_mut_ptr(), |
| 184 | buf.len(), | 185 | buf.len(), |
| 186 | true, | ||
| 185 | #[cfg(dmamux)] | 187 | #[cfg(dmamux)] |
| 186 | <Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS, | 188 | <Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS, |
| 187 | #[cfg(dmamux)] | 189 | #[cfg(dmamux)] |
| @@ -206,6 +208,33 @@ pac::dma_channels! { | |||
| 206 | dst, | 208 | dst, |
| 207 | buf.as_ptr() as *mut u8, | 209 | buf.as_ptr() as *mut u8, |
| 208 | buf.len(), | 210 | buf.len(), |
| 211 | true, | ||
| 212 | #[cfg(dmamux)] | ||
| 213 | <Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS, | ||
| 214 | #[cfg(dmamux)] | ||
| 215 | <Self as super::dmamux::sealed::MuxChannel>::DMAMUX_CH_NUM, | ||
| 216 | ) | ||
| 217 | } | ||
| 218 | } | ||
| 219 | |||
| 220 | fn write_x<'a>( | ||
| 221 | &'a mut self, | ||
| 222 | request: Request, | ||
| 223 | word: &u8, | ||
| 224 | count: usize, | ||
| 225 | dst: *mut u8, | ||
| 226 | ) -> Self::WriteFuture<'a> { | ||
| 227 | unsafe { | ||
| 228 | do_transfer( | ||
| 229 | crate::pac::$dma_peri, | ||
| 230 | $channel_num, | ||
| 231 | (dma_num!($dma_peri) * 8) + $channel_num, | ||
| 232 | request, | ||
| 233 | vals::Dir::FROMMEMORY, | ||
| 234 | dst, | ||
| 235 | word as *const u8 as *mut u8, | ||
| 236 | count, | ||
| 237 | false, | ||
| 209 | #[cfg(dmamux)] | 238 | #[cfg(dmamux)] |
| 210 | <Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS, | 239 | <Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS, |
| 211 | #[cfg(dmamux)] | 240 | #[cfg(dmamux)] |
diff --git a/embassy-stm32/src/dma/dma.rs b/embassy-stm32/src/dma/dma.rs index cf0889a3e..9ac6df159 100644 --- a/embassy-stm32/src/dma/dma.rs +++ b/embassy-stm32/src/dma/dma.rs | |||
| @@ -48,6 +48,7 @@ pub(crate) unsafe fn do_transfer( | |||
| 48 | peri_addr: *const u8, | 48 | peri_addr: *const u8, |
| 49 | mem_addr: *mut u8, | 49 | mem_addr: *mut u8, |
| 50 | mem_len: usize, | 50 | mem_len: usize, |
| 51 | incr_mem: bool, | ||
| 51 | #[cfg(dmamux)] dmamux_regs: pac::dmamux::Dmamux, | 52 | #[cfg(dmamux)] dmamux_regs: pac::dmamux::Dmamux, |
| 52 | #[cfg(dmamux)] dmamux_ch_num: u8, | 53 | #[cfg(dmamux)] dmamux_ch_num: u8, |
| 53 | ) -> impl Future<Output = ()> { | 54 | ) -> impl Future<Output = ()> { |
| @@ -187,6 +188,7 @@ pac::dma_channels! { | |||
| 187 | src, | 188 | src, |
| 188 | buf.as_mut_ptr(), | 189 | buf.as_mut_ptr(), |
| 189 | buf.len(), | 190 | buf.len(), |
| 191 | true, | ||
| 190 | #[cfg(dmamux)] | 192 | #[cfg(dmamux)] |
| 191 | <Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS, | 193 | <Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS, |
| 192 | #[cfg(dmamux)] | 194 | #[cfg(dmamux)] |
| @@ -211,6 +213,33 @@ pac::dma_channels! { | |||
| 211 | dst, | 213 | dst, |
| 212 | buf.as_ptr() as *mut u8, | 214 | buf.as_ptr() as *mut u8, |
| 213 | buf.len(), | 215 | buf.len(), |
| 216 | true, | ||
| 217 | #[cfg(dmamux)] | ||
| 218 | <Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS, | ||
| 219 | #[cfg(dmamux)] | ||
| 220 | <Self as super::dmamux::sealed::MuxChannel>::DMAMUX_CH_NUM, | ||
| 221 | ) | ||
| 222 | } | ||
| 223 | } | ||
| 224 | |||
| 225 | fn write_x<'a>( | ||
| 226 | &'a mut self, | ||
| 227 | request: Request, | ||
| 228 | word: &u8, | ||
| 229 | num: usize, | ||
| 230 | dst: *mut u8, | ||
| 231 | ) -> Self::WriteFuture<'a> { | ||
| 232 | unsafe { | ||
| 233 | do_transfer( | ||
| 234 | crate::pac::$dma_peri, | ||
| 235 | $channel_num, | ||
| 236 | (dma_num!($dma_peri) * 8) + $channel_num, | ||
| 237 | request, | ||
| 238 | vals::Dir::MEMORYTOPERIPHERAL, | ||
| 239 | dst, | ||
| 240 | word as *const u8 as *mut u8, | ||
| 241 | num, | ||
| 242 | false, | ||
| 214 | #[cfg(dmamux)] | 243 | #[cfg(dmamux)] |
| 215 | <Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS, | 244 | <Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS, |
| 216 | #[cfg(dmamux)] | 245 | #[cfg(dmamux)] |
diff --git a/embassy-stm32/src/dma/mod.rs b/embassy-stm32/src/dma/mod.rs index fbf82b87b..60f6a3020 100644 --- a/embassy-stm32/src/dma/mod.rs +++ b/embassy-stm32/src/dma/mod.rs | |||
| @@ -42,6 +42,14 @@ pub trait Channel: sealed::Channel { | |||
| 42 | buf: &'a [u8], | 42 | buf: &'a [u8], |
| 43 | dst: *mut u8, | 43 | dst: *mut u8, |
| 44 | ) -> Self::WriteFuture<'a>; | 44 | ) -> Self::WriteFuture<'a>; |
| 45 | |||
| 46 | fn write_x<'a>( | ||
| 47 | &'a mut self, | ||
| 48 | request: Request, | ||
| 49 | word: &u8, | ||
| 50 | num: usize, | ||
| 51 | dst: *mut u8, | ||
| 52 | ) -> Self::WriteFuture<'a>; | ||
| 45 | } | 53 | } |
| 46 | 54 | ||
| 47 | pub struct NoDma; | 55 | pub struct NoDma; |
diff --git a/embassy-stm32/src/spi/mod.rs b/embassy-stm32/src/spi/mod.rs index 7e1686443..f84d820b5 100644 --- a/embassy-stm32/src/spi/mod.rs +++ b/embassy-stm32/src/spi/mod.rs | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | #![macro_use] | 1 | #![macro_use] |
| 2 | 2 | ||
| 3 | #[cfg_attr(spi_v1, path = "v1.rs")] | 3 | //#[cfg_attr(spi_v1, path = "v1.rs")] |
| 4 | #[cfg_attr(spi_v2, path = "v2.rs")] | 4 | //#[cfg_attr(spi_v2, path = "v2.rs")] |
| 5 | #[cfg_attr(spi_v3, path = "v3.rs")] | 5 | #[cfg_attr(spi_v3, path = "v3.rs")] |
| 6 | mod _version; | 6 | mod _version; |
| 7 | use crate::{dma, peripherals, rcc::RccPeripheral}; | 7 | use crate::{dma, peripherals, rcc::RccPeripheral}; |
diff --git a/embassy-stm32/src/spi/v3.rs b/embassy-stm32/src/spi/v3.rs index 2df2b49b6..a3f9b8911 100644 --- a/embassy-stm32/src/spi/v3.rs +++ b/embassy-stm32/src/spi/v3.rs | |||
| @@ -18,6 +18,8 @@ use embassy_extras::unborrow; | |||
| 18 | use embassy_traits::spi as traits; | 18 | use embassy_traits::spi as traits; |
| 19 | pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; | 19 | pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; |
| 20 | 20 | ||
| 21 | use futures::future::join; | ||
| 22 | |||
| 21 | impl WordSize { | 23 | impl WordSize { |
| 22 | fn dsize(&self) -> u8 { | 24 | fn dsize(&self) -> u8 { |
| 23 | match self { | 25 | match self { |
| @@ -176,18 +178,58 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||
| 176 | } | 178 | } |
| 177 | 179 | ||
| 178 | #[allow(unused)] | 180 | #[allow(unused)] |
| 179 | async fn write_dma_u8(&mut self, write: &[u8]) -> Result<(), Error> { | 181 | async fn write_dma_u8(&mut self, write: &[u8]) -> Result<(), Error> |
| 180 | unimplemented!() | 182 | where |
| 183 | Tx: TxDmaChannel<T>, | ||
| 184 | { | ||
| 185 | let request = self.txdma.request(); | ||
| 186 | let dst = T::regs().txdr().ptr() as *mut u8; | ||
| 187 | let f = self.txdma.write(request, write, dst); | ||
| 188 | unsafe { | ||
| 189 | T::regs().cfg1().modify(|reg| { | ||
| 190 | reg.set_txdmaen(true); | ||
| 191 | }); | ||
| 192 | } | ||
| 193 | |||
| 194 | f.await; | ||
| 195 | Ok(()) | ||
| 181 | } | 196 | } |
| 182 | 197 | ||
| 183 | #[allow(unused)] | 198 | #[allow(unused)] |
| 184 | async fn read_dma_u8(&mut self, read: &mut [u8]) -> Result<(), Error> { | 199 | async fn read_dma_u8(&mut self, read: &mut [u8]) -> Result<(), Error> |
| 200 | where | ||
| 201 | Tx: TxDmaChannel<T>, | ||
| 202 | Rx: RxDmaChannel<T>, | ||
| 203 | { | ||
| 185 | unimplemented!() | 204 | unimplemented!() |
| 186 | } | 205 | } |
| 187 | 206 | ||
| 188 | #[allow(unused)] | 207 | #[allow(unused)] |
| 189 | async fn read_write_dma_u8(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Error> { | 208 | async fn read_write_dma_u8(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Error> |
| 190 | unimplemented!() | 209 | where |
| 210 | Tx: TxDmaChannel<T>, | ||
| 211 | Rx: RxDmaChannel<T>, | ||
| 212 | { | ||
| 213 | let rx_request = self.rxdma.request(); | ||
| 214 | let rx_src = T::regs().rxdr().ptr() as *mut u8; | ||
| 215 | let rx_f = self.rxdma.read(rx_request, rx_src, read); | ||
| 216 | |||
| 217 | let tx_request = self.txdma.request(); | ||
| 218 | let tx_dst = T::regs().txdr().ptr() as *mut u8; | ||
| 219 | let clock_byte = 0x00; | ||
| 220 | let tx_f = self | ||
| 221 | .txdma | ||
| 222 | .write_x(tx_request, &clock_byte, read.len(), tx_dst); | ||
| 223 | |||
| 224 | unsafe { | ||
| 225 | T::regs().cfg1().modify(|reg| { | ||
| 226 | reg.set_txdmaen(true); | ||
| 227 | reg.set_rxdmaen(true); | ||
| 228 | }); | ||
| 229 | } | ||
| 230 | |||
| 231 | let r = join(tx_f, rx_f).await; | ||
| 232 | Ok(()) | ||
| 191 | } | 233 | } |
| 192 | } | 234 | } |
| 193 | 235 | ||
