diff options
| author | Dario Nieuwenhuis <[email protected]> | 2024-02-08 20:11:03 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-02-08 20:11:03 +0000 |
| commit | b326ee19bbd65e553e6891c08f623e5acdd95375 (patch) | |
| tree | 7b8560afce7d40720e3286a01538aee6384735e8 | |
| parent | 2e15d1371a891cc3456d7b9fd22a68291770df41 (diff) | |
| parent | 27411658d9710451b04efe014747606018646527 (diff) | |
Merge pull request #2547 from plaes/spi-easydma-size-checks
nrf: spim/spis: Add size checks for EasyDMA 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 | ||
