aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPriit Laes <[email protected]>2024-02-08 21:43:05 +0200
committerPriit Laes <[email protected]>2024-02-08 21:48:41 +0200
commit27411658d9710451b04efe014747606018646527 (patch)
tree7b8560afce7d40720e3286a01538aee6384735e8
parent2e15d1371a891cc3456d7b9fd22a68291770df41 (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.rs14
-rw-r--r--embassy-nrf/src/spis.rs8
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
13pub use pac::spim0::config::ORDER_A as BitOrder; 13pub use pac::spim0::config::ORDER_A as BitOrder;
14pub use pac::spim0::frequency::FREQUENCY_A as Frequency; 14pub use pac::spim0::frequency::FREQUENCY_A as Frequency;
15 15
16use crate::chip::FORCE_COPY_BUFFER_SIZE; 16use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE};
17use crate::gpio::sealed::Pin as _; 17use crate::gpio::sealed::Pin as _;
18use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits}; 18use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits};
19use crate::interrupt::typelevel::Interrupt; 19use 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]
27pub enum Error { 27pub 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};
11pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3}; 11pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
12pub use pac::spis0::config::ORDER_A as BitOrder; 12pub use pac::spis0::config::ORDER_A as BitOrder;
13 13
14use crate::chip::FORCE_COPY_BUFFER_SIZE; 14use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE};
15use crate::gpio::sealed::Pin as _; 15use crate::gpio::sealed::Pin as _;
16use crate::gpio::{self, AnyPin, Pin as GpioPin}; 16use crate::gpio::{self, AnyPin, Pin as GpioPin};
17use crate::interrupt::typelevel::Interrupt; 17use 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