Add a non-minc write() to DMA which takes a count.
Use it from "read-only" SPI.
This commit is contained in:
		| @@ -47,6 +47,7 @@ pub(crate) unsafe fn do_transfer( | |||||||
|     peri_addr: *const u8, |     peri_addr: *const u8, | ||||||
|     mem_addr: *mut u8, |     mem_addr: *mut u8, | ||||||
|     mem_len: usize, |     mem_len: usize, | ||||||
|  |     incr_mem: bool, | ||||||
|     #[cfg(dmamux)] dmamux_regs: pac::dmamux::Dmamux, |     #[cfg(dmamux)] dmamux_regs: pac::dmamux::Dmamux, | ||||||
|     #[cfg(dmamux)] dmamux_ch_num: u8, |     #[cfg(dmamux)] dmamux_ch_num: u8, | ||||||
| ) -> impl Future<Output = ()> { | ) -> impl Future<Output = ()> { | ||||||
| @@ -182,6 +183,7 @@ pac::dma_channels! { | |||||||
|                         src, |                         src, | ||||||
|                         buf.as_mut_ptr(), |                         buf.as_mut_ptr(), | ||||||
|                         buf.len(), |                         buf.len(), | ||||||
|  |                         true, | ||||||
|                         #[cfg(dmamux)] |                         #[cfg(dmamux)] | ||||||
|                         <Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS, |                         <Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS, | ||||||
|                         #[cfg(dmamux)] |                         #[cfg(dmamux)] | ||||||
| @@ -206,6 +208,33 @@ pac::dma_channels! { | |||||||
|                         dst, |                         dst, | ||||||
|                         buf.as_ptr() as *mut u8, |                         buf.as_ptr() as *mut u8, | ||||||
|                         buf.len(), |                         buf.len(), | ||||||
|  |                         true, | ||||||
|  |                         #[cfg(dmamux)] | ||||||
|  |                         <Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS, | ||||||
|  |                         #[cfg(dmamux)] | ||||||
|  |                         <Self as super::dmamux::sealed::MuxChannel>::DMAMUX_CH_NUM, | ||||||
|  |                     ) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             fn write_x<'a>( | ||||||
|  |                 &'a mut self, | ||||||
|  |                 request: Request, | ||||||
|  |                 word: &u8, | ||||||
|  |                 count: usize, | ||||||
|  |                 dst: *mut u8, | ||||||
|  |             ) -> Self::WriteFuture<'a> { | ||||||
|  |                 unsafe { | ||||||
|  |                     do_transfer( | ||||||
|  |                         crate::pac::$dma_peri, | ||||||
|  |                         $channel_num, | ||||||
|  |                         (dma_num!($dma_peri) * 8) + $channel_num, | ||||||
|  |                         request, | ||||||
|  |                         vals::Dir::FROMMEMORY, | ||||||
|  |                         dst, | ||||||
|  |                         word as *const u8 as *mut u8, | ||||||
|  |                         count, | ||||||
|  |                         false, | ||||||
|                         #[cfg(dmamux)] |                         #[cfg(dmamux)] | ||||||
|                         <Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS, |                         <Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS, | ||||||
|                         #[cfg(dmamux)] |                         #[cfg(dmamux)] | ||||||
|   | |||||||
| @@ -48,6 +48,7 @@ pub(crate) unsafe fn do_transfer( | |||||||
|     peri_addr: *const u8, |     peri_addr: *const u8, | ||||||
|     mem_addr: *mut u8, |     mem_addr: *mut u8, | ||||||
|     mem_len: usize, |     mem_len: usize, | ||||||
|  |     incr_mem: bool, | ||||||
|     #[cfg(dmamux)] dmamux_regs: pac::dmamux::Dmamux, |     #[cfg(dmamux)] dmamux_regs: pac::dmamux::Dmamux, | ||||||
|     #[cfg(dmamux)] dmamux_ch_num: u8, |     #[cfg(dmamux)] dmamux_ch_num: u8, | ||||||
| ) -> impl Future<Output = ()> { | ) -> impl Future<Output = ()> { | ||||||
| @@ -187,6 +188,7 @@ pac::dma_channels! { | |||||||
|                         src, |                         src, | ||||||
|                         buf.as_mut_ptr(), |                         buf.as_mut_ptr(), | ||||||
|                         buf.len(), |                         buf.len(), | ||||||
|  |                         true, | ||||||
|                         #[cfg(dmamux)] |                         #[cfg(dmamux)] | ||||||
|                         <Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS, |                         <Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS, | ||||||
|                         #[cfg(dmamux)] |                         #[cfg(dmamux)] | ||||||
| @@ -211,6 +213,33 @@ pac::dma_channels! { | |||||||
|                         dst, |                         dst, | ||||||
|                         buf.as_ptr() as *mut u8, |                         buf.as_ptr() as *mut u8, | ||||||
|                         buf.len(), |                         buf.len(), | ||||||
|  |                         true, | ||||||
|  |                         #[cfg(dmamux)] | ||||||
|  |                         <Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS, | ||||||
|  |                         #[cfg(dmamux)] | ||||||
|  |                         <Self as super::dmamux::sealed::MuxChannel>::DMAMUX_CH_NUM, | ||||||
|  |                     ) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             fn write_x<'a>( | ||||||
|  |                 &'a mut self, | ||||||
|  |                 request: Request, | ||||||
|  |                 word: &u8, | ||||||
|  |                 num: usize, | ||||||
|  |                 dst: *mut u8, | ||||||
|  |             ) -> Self::WriteFuture<'a> { | ||||||
|  |                 unsafe { | ||||||
|  |                     do_transfer( | ||||||
|  |                         crate::pac::$dma_peri, | ||||||
|  |                         $channel_num, | ||||||
|  |                         (dma_num!($dma_peri) * 8) + $channel_num, | ||||||
|  |                         request, | ||||||
|  |                         vals::Dir::MEMORYTOPERIPHERAL, | ||||||
|  |                         dst, | ||||||
|  |                         word as *const u8 as *mut u8, | ||||||
|  |                         num, | ||||||
|  |                         false, | ||||||
|                         #[cfg(dmamux)] |                         #[cfg(dmamux)] | ||||||
|                         <Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS, |                         <Self as super::dmamux::sealed::MuxChannel>::DMAMUX_REGS, | ||||||
|                         #[cfg(dmamux)] |                         #[cfg(dmamux)] | ||||||
|   | |||||||
| @@ -42,6 +42,14 @@ pub trait Channel: sealed::Channel { | |||||||
|         buf: &'a [u8], |         buf: &'a [u8], | ||||||
|         dst: *mut u8, |         dst: *mut u8, | ||||||
|     ) -> Self::WriteFuture<'a>; |     ) -> Self::WriteFuture<'a>; | ||||||
|  |  | ||||||
|  |     fn write_x<'a>( | ||||||
|  |         &'a mut self, | ||||||
|  |         request: Request, | ||||||
|  |         word: &u8, | ||||||
|  |         num: usize, | ||||||
|  |         dst: *mut u8, | ||||||
|  |     ) -> Self::WriteFuture<'a>; | ||||||
| } | } | ||||||
|  |  | ||||||
| pub struct NoDma; | pub struct NoDma; | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| #![macro_use] | #![macro_use] | ||||||
|  |  | ||||||
| #[cfg_attr(spi_v1, path = "v1.rs")] | //#[cfg_attr(spi_v1, path = "v1.rs")] | ||||||
| #[cfg_attr(spi_v2, path = "v2.rs")] | //#[cfg_attr(spi_v2, path = "v2.rs")] | ||||||
| #[cfg_attr(spi_v3, path = "v3.rs")] | #[cfg_attr(spi_v3, path = "v3.rs")] | ||||||
| mod _version; | mod _version; | ||||||
| use crate::{dma, peripherals, rcc::RccPeripheral}; | use crate::{dma, peripherals, rcc::RccPeripheral}; | ||||||
|   | |||||||
| @@ -18,6 +18,8 @@ use embassy_extras::unborrow; | |||||||
| use embassy_traits::spi as traits; | use embassy_traits::spi as traits; | ||||||
| pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; | pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; | ||||||
|  |  | ||||||
|  | use futures::future::join; | ||||||
|  |  | ||||||
| impl WordSize { | impl WordSize { | ||||||
|     fn dsize(&self) -> u8 { |     fn dsize(&self) -> u8 { | ||||||
|         match self { |         match self { | ||||||
| @@ -176,18 +178,58 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     #[allow(unused)] |     #[allow(unused)] | ||||||
|     async fn write_dma_u8(&mut self, write: &[u8]) -> Result<(), Error> { |     async fn write_dma_u8(&mut self, write: &[u8]) -> Result<(), Error> | ||||||
|  |     where | ||||||
|  |         Tx: TxDmaChannel<T>, | ||||||
|  |     { | ||||||
|  |         let request = self.txdma.request(); | ||||||
|  |         let dst = T::regs().txdr().ptr() as *mut u8; | ||||||
|  |         let f = self.txdma.write(request, write, dst); | ||||||
|  |         unsafe { | ||||||
|  |             T::regs().cfg1().modify(|reg| { | ||||||
|  |                 reg.set_txdmaen(true); | ||||||
|  |             }); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         f.await; | ||||||
|  |         Ok(()) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     #[allow(unused)] | ||||||
|  |     async fn read_dma_u8(&mut self, read: &mut [u8]) -> Result<(), Error> | ||||||
|  |     where | ||||||
|  |         Tx: TxDmaChannel<T>, | ||||||
|  |         Rx: RxDmaChannel<T>, | ||||||
|  |     { | ||||||
|         unimplemented!() |         unimplemented!() | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     #[allow(unused)] |     #[allow(unused)] | ||||||
|     async fn read_dma_u8(&mut self, read: &mut [u8]) -> Result<(), Error> { |     async fn read_write_dma_u8(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Error> | ||||||
|         unimplemented!() |     where | ||||||
|     } |         Tx: TxDmaChannel<T>, | ||||||
|  |         Rx: RxDmaChannel<T>, | ||||||
|  |     { | ||||||
|  |         let rx_request = self.rxdma.request(); | ||||||
|  |         let rx_src = T::regs().rxdr().ptr() as *mut u8; | ||||||
|  |         let rx_f = self.rxdma.read(rx_request, rx_src, read); | ||||||
|  |  | ||||||
|     #[allow(unused)] |         let tx_request = self.txdma.request(); | ||||||
|     async fn read_write_dma_u8(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Error> { |         let tx_dst = T::regs().txdr().ptr() as *mut u8; | ||||||
|         unimplemented!() |         let clock_byte = 0x00; | ||||||
|  |         let tx_f = self | ||||||
|  |             .txdma | ||||||
|  |             .write_x(tx_request, &clock_byte, read.len(), tx_dst); | ||||||
|  |  | ||||||
|  |         unsafe { | ||||||
|  |             T::regs().cfg1().modify(|reg| { | ||||||
|  |                 reg.set_txdmaen(true); | ||||||
|  |                 reg.set_rxdmaen(true); | ||||||
|  |             }); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         let r = join(tx_f, rx_f).await; | ||||||
|  |         Ok(()) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user