nrf: spim/spis: Add size checks for EasyDMA buffer

On most nRF chips, maximum buffer size for EasyDMA is 255, thus
we never got any data when attempting to use 256 bytes as RX/TX buffer.
This commit is contained in:
Priit Laes 2024-02-08 21:43:05 +02:00
parent 2e15d1371a
commit 27411658d9
2 changed files with 18 additions and 4 deletions

View file

@ -13,7 +13,7 @@ pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MO
pub use pac::spim0::config::ORDER_A as BitOrder;
pub use pac::spim0::frequency::FREQUENCY_A as Frequency;
use crate::chip::FORCE_COPY_BUFFER_SIZE;
use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE};
use crate::gpio::sealed::Pin as _;
use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits};
use crate::interrupt::typelevel::Interrupt;
@ -25,9 +25,9 @@ use crate::{interrupt, pac, Peripheral};
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[non_exhaustive]
pub enum Error {
/// TX buffer was too long.
/// Supplied TX buffer overflows EasyDMA transmit buffer
TxBufferTooLong,
/// RX buffer was too long.
/// Supplied RX buffer overflows EasyDMA receive buffer
RxBufferTooLong,
/// EasyDMA can only read from data memory, read only buffers in flash will fail.
BufferNotInRAM,
@ -220,11 +220,19 @@ impl<'d, T: Instance> Spim<'d, T> {
// Set up the DMA write.
let (ptr, tx_len) = slice_ptr_parts(tx);
if tx_len > EASY_DMA_SIZE {
return Err(Error::TxBufferTooLong);
}
r.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr as _) });
r.txd.maxcnt.write(|w| unsafe { w.maxcnt().bits(tx_len as _) });
// Set up the DMA read.
let (ptr, rx_len) = slice_ptr_parts_mut(rx);
if rx_len > EASY_DMA_SIZE {
return Err(Error::RxBufferTooLong);
}
r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as _) });
r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(rx_len as _) });

View file

@ -11,7 +11,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
pub use pac::spis0::config::ORDER_A as BitOrder;
use crate::chip::FORCE_COPY_BUFFER_SIZE;
use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE};
use crate::gpio::sealed::Pin as _;
use crate::gpio::{self, AnyPin, Pin as GpioPin};
use crate::interrupt::typelevel::Interrupt;
@ -227,11 +227,17 @@ impl<'d, T: Instance> Spis<'d, T> {
// Set up the DMA write.
let (ptr, len) = slice_ptr_parts(tx);
if len > EASY_DMA_SIZE {
return Err(Error::TxBufferTooLong);
}
r.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr as _) });
r.txd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) });
// Set up the DMA read.
let (ptr, len) = slice_ptr_parts_mut(rx);
if len > EASY_DMA_SIZE {
return Err(Error::RxBufferTooLong);
}
r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as _) });
r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) });