mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-22 06:42:32 +00:00
Merge #954
954: rp: fix async SPI read and write r=lulf a=newAM Closes #953 Co-authored-by: Alex Martens <alex@thinglab.org>
This commit is contained in:
commit
6663390224
@ -75,6 +75,25 @@ pub unsafe fn write<'a, C: Channel, W: Word>(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub unsafe fn write_repeated<'a, C: Channel, W: Word>(
|
||||||
|
ch: impl Peripheral<P = C> + 'a,
|
||||||
|
to: *mut W,
|
||||||
|
len: usize,
|
||||||
|
dreq: u8,
|
||||||
|
) -> Transfer<'a, C> {
|
||||||
|
let dummy: u32 = 0;
|
||||||
|
copy_inner(
|
||||||
|
ch,
|
||||||
|
&dummy as *const u32,
|
||||||
|
to as *mut u32,
|
||||||
|
len,
|
||||||
|
W::size(),
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
dreq,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub unsafe fn copy<'a, C: Channel, W: Word>(
|
pub unsafe fn copy<'a, C: Channel, W: Word>(
|
||||||
ch: impl Peripheral<P = C> + 'a,
|
ch: impl Peripheral<P = C> + 'a,
|
||||||
from: &[W],
|
from: &[W],
|
||||||
|
@ -325,30 +325,52 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> {
|
pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> {
|
||||||
let ch = self.tx_dma.as_mut().unwrap();
|
let tx_ch = self.tx_dma.as_mut().unwrap();
|
||||||
let transfer = unsafe {
|
let tx_transfer = unsafe {
|
||||||
self.inner.regs().dmacr().modify(|reg| {
|
self.inner.regs().dmacr().modify(|reg| {
|
||||||
reg.set_txdmae(true);
|
reg.set_txdmae(true);
|
||||||
});
|
});
|
||||||
// If we don't assign future to a variable, the data register pointer
|
// If we don't assign future to a variable, the data register pointer
|
||||||
// is held across an await and makes the future non-Send.
|
// is held across an await and makes the future non-Send.
|
||||||
crate::dma::write(ch, buffer, self.inner.regs().dr().ptr() as *mut _, T::TX_DREQ)
|
crate::dma::write(tx_ch, buffer, self.inner.regs().dr().ptr() as *mut _, T::TX_DREQ)
|
||||||
};
|
};
|
||||||
transfer.await;
|
tx_transfer.await;
|
||||||
|
|
||||||
|
let p = self.inner.regs();
|
||||||
|
unsafe {
|
||||||
|
while p.sr().read().bsy() {}
|
||||||
|
|
||||||
|
// clear RX FIFO contents to prevent stale reads
|
||||||
|
while p.sr().read().rne() {
|
||||||
|
let _: u16 = p.dr().read().data();
|
||||||
|
}
|
||||||
|
// clear RX overrun interrupt
|
||||||
|
p.icr().write(|w| w.set_roric(true));
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
|
pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
|
||||||
let ch = self.rx_dma.as_mut().unwrap();
|
unsafe {
|
||||||
let transfer = unsafe {
|
self.inner.regs().dmacr().write(|reg| {
|
||||||
self.inner.regs().dmacr().modify(|reg| {
|
|
||||||
reg.set_rxdmae(true);
|
reg.set_rxdmae(true);
|
||||||
});
|
reg.set_txdmae(true);
|
||||||
|
})
|
||||||
|
};
|
||||||
|
let tx_ch = self.tx_dma.as_mut().unwrap();
|
||||||
|
let tx_transfer = unsafe {
|
||||||
// If we don't assign future to a variable, the data register pointer
|
// If we don't assign future to a variable, the data register pointer
|
||||||
// is held across an await and makes the future non-Send.
|
// is held across an await and makes the future non-Send.
|
||||||
crate::dma::read(ch, self.inner.regs().dr().ptr() as *const _, buffer, T::RX_DREQ)
|
crate::dma::write_repeated(tx_ch, self.inner.regs().dr().ptr() as *mut u8, buffer.len(), T::TX_DREQ)
|
||||||
};
|
};
|
||||||
transfer.await;
|
let rx_ch = self.rx_dma.as_mut().unwrap();
|
||||||
|
let rx_transfer = unsafe {
|
||||||
|
// If we don't assign future to a variable, the data register pointer
|
||||||
|
// is held across an await and makes the future non-Send.
|
||||||
|
crate::dma::read(rx_ch, self.inner.regs().dr().ptr() as *const _, buffer, T::RX_DREQ)
|
||||||
|
};
|
||||||
|
join(tx_transfer, rx_transfer).await;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,20 +386,20 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
|
|||||||
let (_, from_len) = crate::dma::slice_ptr_parts(tx_ptr);
|
let (_, from_len) = crate::dma::slice_ptr_parts(tx_ptr);
|
||||||
let (_, to_len) = crate::dma::slice_ptr_parts_mut(rx_ptr);
|
let (_, to_len) = crate::dma::slice_ptr_parts_mut(rx_ptr);
|
||||||
assert_eq!(from_len, to_len);
|
assert_eq!(from_len, to_len);
|
||||||
|
unsafe {
|
||||||
|
self.inner.regs().dmacr().write(|reg| {
|
||||||
|
reg.set_rxdmae(true);
|
||||||
|
reg.set_txdmae(true);
|
||||||
|
})
|
||||||
|
};
|
||||||
let tx_ch = self.tx_dma.as_mut().unwrap();
|
let tx_ch = self.tx_dma.as_mut().unwrap();
|
||||||
let tx_transfer = unsafe {
|
let tx_transfer = unsafe {
|
||||||
self.inner.regs().dmacr().modify(|reg| {
|
|
||||||
reg.set_txdmae(true);
|
|
||||||
});
|
|
||||||
// If we don't assign future to a variable, the data register pointer
|
// If we don't assign future to a variable, the data register pointer
|
||||||
// is held across an await and makes the future non-Send.
|
// is held across an await and makes the future non-Send.
|
||||||
crate::dma::write(tx_ch, tx_ptr, self.inner.regs().dr().ptr() as *mut _, T::TX_DREQ)
|
crate::dma::write(tx_ch, tx_ptr, self.inner.regs().dr().ptr() as *mut _, T::TX_DREQ)
|
||||||
};
|
};
|
||||||
let rx_ch = self.rx_dma.as_mut().unwrap();
|
let rx_ch = self.rx_dma.as_mut().unwrap();
|
||||||
let rx_transfer = unsafe {
|
let rx_transfer = unsafe {
|
||||||
self.inner.regs().dmacr().modify(|reg| {
|
|
||||||
reg.set_rxdmae(true);
|
|
||||||
});
|
|
||||||
// If we don't assign future to a variable, the data register pointer
|
// If we don't assign future to a variable, the data register pointer
|
||||||
// is held across an await and makes the future non-Send.
|
// is held across an await and makes the future non-Send.
|
||||||
crate::dma::read(rx_ch, self.inner.regs().dr().ptr() as *const _, rx_ptr, T::RX_DREQ)
|
crate::dma::read(rx_ch, self.inner.regs().dr().ptr() as *const _, rx_ptr, T::RX_DREQ)
|
||||||
|
Loading…
Reference in New Issue
Block a user