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:
parent
2e15d1371a
commit
27411658d9
2 changed files with 18 additions and 4 deletions
|
@ -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::config::ORDER_A as BitOrder;
|
||||||
pub use pac::spim0::frequency::FREQUENCY_A as Frequency;
|
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::sealed::Pin as _;
|
||||||
use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits};
|
use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits};
|
||||||
use crate::interrupt::typelevel::Interrupt;
|
use crate::interrupt::typelevel::Interrupt;
|
||||||
|
@ -25,9 +25,9 @@ use crate::{interrupt, pac, Peripheral};
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// TX buffer was too long.
|
/// Supplied TX buffer overflows EasyDMA transmit buffer
|
||||||
TxBufferTooLong,
|
TxBufferTooLong,
|
||||||
/// RX buffer was too long.
|
/// Supplied RX buffer overflows EasyDMA receive buffer
|
||||||
RxBufferTooLong,
|
RxBufferTooLong,
|
||||||
/// EasyDMA can only read from data memory, read only buffers in flash will fail.
|
/// EasyDMA can only read from data memory, read only buffers in flash will fail.
|
||||||
BufferNotInRAM,
|
BufferNotInRAM,
|
||||||
|
@ -220,11 +220,19 @@ impl<'d, T: Instance> Spim<'d, T> {
|
||||||
|
|
||||||
// Set up the DMA write.
|
// Set up the DMA write.
|
||||||
let (ptr, tx_len) = slice_ptr_parts(tx);
|
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.ptr.write(|w| unsafe { w.ptr().bits(ptr as _) });
|
||||||
r.txd.maxcnt.write(|w| unsafe { w.maxcnt().bits(tx_len as _) });
|
r.txd.maxcnt.write(|w| unsafe { w.maxcnt().bits(tx_len as _) });
|
||||||
|
|
||||||
// Set up the DMA read.
|
// Set up the DMA read.
|
||||||
let (ptr, rx_len) = slice_ptr_parts_mut(rx);
|
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.ptr.write(|w| unsafe { w.ptr().bits(ptr as _) });
|
||||||
r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(rx_len as _) });
|
r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(rx_len as _) });
|
||||||
|
|
||||||
|
|
|
@ -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 embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
|
||||||
pub use pac::spis0::config::ORDER_A as BitOrder;
|
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::sealed::Pin as _;
|
||||||
use crate::gpio::{self, AnyPin, Pin as GpioPin};
|
use crate::gpio::{self, AnyPin, Pin as GpioPin};
|
||||||
use crate::interrupt::typelevel::Interrupt;
|
use crate::interrupt::typelevel::Interrupt;
|
||||||
|
@ -227,11 +227,17 @@ impl<'d, T: Instance> Spis<'d, T> {
|
||||||
|
|
||||||
// Set up the DMA write.
|
// Set up the DMA write.
|
||||||
let (ptr, len) = slice_ptr_parts(tx);
|
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.ptr.write(|w| unsafe { w.ptr().bits(ptr as _) });
|
||||||
r.txd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) });
|
r.txd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) });
|
||||||
|
|
||||||
// Set up the DMA read.
|
// Set up the DMA read.
|
||||||
let (ptr, len) = slice_ptr_parts_mut(rx);
|
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.ptr.write(|w| unsafe { w.ptr().bits(ptr as _) });
|
||||||
r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) });
|
r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) });
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue