Add a non-minc write() to DMA which takes a count.

Use it from "read-only" SPI.
This commit is contained in:
Bob McWhirter 2021-07-20 15:20:16 -04:00
parent 7bbad4c4e5
commit 4c5a234a3a
5 changed files with 117 additions and 9 deletions

View File

@ -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)]

View File

@ -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)]

View File

@ -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;

View File

@ -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};

View File

@ -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);
let tx_request = self.txdma.request();
let tx_dst = T::regs().txdr().ptr() as *mut u8;
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);
});
} }
#[allow(unused)] let r = join(tx_f, rx_f).await;
async fn read_write_dma_u8(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Error> { Ok(())
unimplemented!()
} }
} }