diff options
| author | Priit Laes <[email protected]> | 2024-02-08 21:43:05 +0200 |
|---|---|---|
| committer | Priit Laes <[email protected]> | 2024-02-08 21:48:41 +0200 |
| commit | 27411658d9710451b04efe014747606018646527 (patch) | |
| tree | 7b8560afce7d40720e3286a01538aee6384735e8 | |
| parent | 2e15d1371a891cc3456d7b9fd22a68291770df41 (diff) | |
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.
| -rw-r--r-- | embassy-nrf/src/spim.rs | 14 | ||||
| -rw-r--r-- | embassy-nrf/src/spis.rs | 8 |
2 files changed, 18 insertions, 4 deletions
diff --git a/embassy-nrf/src/spim.rs b/embassy-nrf/src/spim.rs index 6b6f79188..8937159df 100644 --- a/embassy-nrf/src/spim.rs +++ b/embassy-nrf/src/spim.rs | |||
| @@ -13,7 +13,7 @@ pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MO | |||
| 13 | pub use pac::spim0::config::ORDER_A as BitOrder; | 13 | pub use pac::spim0::config::ORDER_A as BitOrder; |
| 14 | pub use pac::spim0::frequency::FREQUENCY_A as Frequency; | 14 | pub use pac::spim0::frequency::FREQUENCY_A as Frequency; |
| 15 | 15 | ||
| 16 | use crate::chip::FORCE_COPY_BUFFER_SIZE; | 16 | use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; |
| 17 | use crate::gpio::sealed::Pin as _; | 17 | use crate::gpio::sealed::Pin as _; |
| 18 | use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits}; | 18 | use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits}; |
| 19 | use crate::interrupt::typelevel::Interrupt; | 19 | use crate::interrupt::typelevel::Interrupt; |
| @@ -25,9 +25,9 @@ use crate::{interrupt, pac, Peripheral}; | |||
| 25 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 25 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 26 | #[non_exhaustive] | 26 | #[non_exhaustive] |
| 27 | pub enum Error { | 27 | pub enum Error { |
| 28 | /// TX buffer was too long. | 28 | /// Supplied TX buffer overflows EasyDMA transmit buffer |
| 29 | TxBufferTooLong, | 29 | TxBufferTooLong, |
| 30 | /// RX buffer was too long. | 30 | /// Supplied RX buffer overflows EasyDMA receive buffer |
| 31 | RxBufferTooLong, | 31 | RxBufferTooLong, |
| 32 | /// EasyDMA can only read from data memory, read only buffers in flash will fail. | 32 | /// EasyDMA can only read from data memory, read only buffers in flash will fail. |
| 33 | BufferNotInRAM, | 33 | BufferNotInRAM, |
| @@ -220,11 +220,19 @@ impl<'d, T: Instance> Spim<'d, T> { | |||
| 220 | 220 | ||
| 221 | // Set up the DMA write. | 221 | // Set up the DMA write. |
| 222 | let (ptr, tx_len) = slice_ptr_parts(tx); | 222 | let (ptr, tx_len) = slice_ptr_parts(tx); |
| 223 | if tx_len > EASY_DMA_SIZE { | ||
| 224 | return Err(Error::TxBufferTooLong); | ||
| 225 | } | ||
| 226 | |||
| 223 | r.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr as _) }); | 227 | r.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr as _) }); |
| 224 | r.txd.maxcnt.write(|w| unsafe { w.maxcnt().bits(tx_len as _) }); | 228 | r.txd.maxcnt.write(|w| unsafe { w.maxcnt().bits(tx_len as _) }); |
| 225 | 229 | ||
| 226 | // Set up the DMA read. | 230 | // Set up the DMA read. |
| 227 | let (ptr, rx_len) = slice_ptr_parts_mut(rx); | 231 | let (ptr, rx_len) = slice_ptr_parts_mut(rx); |
| 232 | if rx_len > EASY_DMA_SIZE { | ||
| 233 | return Err(Error::RxBufferTooLong); | ||
| 234 | } | ||
| 235 | |||
| 228 | r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as _) }); | 236 | r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as _) }); |
| 229 | r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(rx_len as _) }); | 237 | r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(rx_len as _) }); |
| 230 | 238 | ||
diff --git a/embassy-nrf/src/spis.rs b/embassy-nrf/src/spis.rs index 60f4c9865..772ca40cc 100644 --- a/embassy-nrf/src/spis.rs +++ b/embassy-nrf/src/spis.rs | |||
| @@ -11,7 +11,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef}; | |||
| 11 | pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; | 11 | pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; |
| 12 | pub use pac::spis0::config::ORDER_A as BitOrder; | 12 | pub use pac::spis0::config::ORDER_A as BitOrder; |
| 13 | 13 | ||
| 14 | use crate::chip::FORCE_COPY_BUFFER_SIZE; | 14 | use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; |
| 15 | use crate::gpio::sealed::Pin as _; | 15 | use crate::gpio::sealed::Pin as _; |
| 16 | use crate::gpio::{self, AnyPin, Pin as GpioPin}; | 16 | use crate::gpio::{self, AnyPin, Pin as GpioPin}; |
| 17 | use crate::interrupt::typelevel::Interrupt; | 17 | use crate::interrupt::typelevel::Interrupt; |
| @@ -227,11 +227,17 @@ impl<'d, T: Instance> Spis<'d, T> { | |||
| 227 | 227 | ||
| 228 | // Set up the DMA write. | 228 | // Set up the DMA write. |
| 229 | let (ptr, len) = slice_ptr_parts(tx); | 229 | let (ptr, len) = slice_ptr_parts(tx); |
| 230 | if len > EASY_DMA_SIZE { | ||
| 231 | return Err(Error::TxBufferTooLong); | ||
| 232 | } | ||
| 230 | r.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr as _) }); | 233 | r.txd.ptr.write(|w| unsafe { w.ptr().bits(ptr as _) }); |
| 231 | r.txd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) }); | 234 | r.txd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) }); |
| 232 | 235 | ||
| 233 | // Set up the DMA read. | 236 | // Set up the DMA read. |
| 234 | let (ptr, len) = slice_ptr_parts_mut(rx); | 237 | let (ptr, len) = slice_ptr_parts_mut(rx); |
| 238 | if len > EASY_DMA_SIZE { | ||
| 239 | return Err(Error::RxBufferTooLong); | ||
| 240 | } | ||
| 235 | r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as _) }); | 241 | r.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as _) }); |
| 236 | r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) }); | 242 | r.rxd.maxcnt.write(|w| unsafe { w.maxcnt().bits(len as _) }); |
| 237 | 243 | ||
