rp/spi: enable rxdmae/txdmae only once at init.

see https://github.com/raspberrypi/pico-sdk/blob/master/src/rp2_common/hardware_spi/spi.c#L27-L28
This commit is contained in:
Dario Nieuwenhuis 2023-06-02 04:04:38 +02:00
parent f901cf57e5
commit dd5ce985bd

View File

@ -90,10 +90,16 @@ impl<'d, T: Instance, M: Mode> Spi<'d, T, M> {
w.set_sph(config.phase == Phase::CaptureOnSecondTransition);
w.set_scr(postdiv);
});
p.cr1().write(|w| {
w.set_sse(true); // enable
// Always enable DREQ signals -- harmless if DMA is not listening
p.dmacr().write(|reg| {
reg.set_rxdmae(true);
reg.set_txdmae(true);
});
// finally, enable.
p.cr1().write(|w| w.set_sse(true));
if let Some(pin) = &clk {
pin.io().ctrl().write(|w| w.set_funcsel(1));
}
@ -329,9 +335,6 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
pub async fn write(&mut self, buffer: &[u8]) -> Result<(), Error> {
let tx_ch = self.tx_dma.as_mut().unwrap();
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
// is held across an await and makes the future non-Send.
crate::dma::write(tx_ch, buffer, self.inner.regs().dr().ptr() as *mut _, T::TX_DREQ)
@ -354,13 +357,6 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
}
pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
unsafe {
self.inner.regs().dmacr().write(|reg| {
reg.set_rxdmae(true);
reg.set_txdmae(true);
})
};
// Start RX first. Transfer starts when TX starts, if RX
// is not started yet we might lose bytes.
let rx_ch = self.rx_dma.as_mut().unwrap();
@ -392,13 +388,6 @@ impl<'d, T: Instance> Spi<'d, T, Async> {
let (_, tx_len) = crate::dma::slice_ptr_parts(tx_ptr);
let (_, rx_len) = crate::dma::slice_ptr_parts_mut(rx_ptr);
unsafe {
self.inner.regs().dmacr().write(|reg| {
reg.set_rxdmae(true);
reg.set_txdmae(true);
})
};
// Start RX first. Transfer starts when TX starts, if RX
// is not started yet we might lose bytes.
let rx_ch = self.rx_dma.as_mut().unwrap();