diff --git a/CHANGELOG.md b/CHANGELOG.md index a08d01f000d..407a521275b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -69,6 +69,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - ESP32-S3: Added support for 80Mhz PSRAM (#1069) - ESP32-C3/S3: Add workaround for USB pin exchange on usb-serial-jtag (#1104). - ESP32C6: Added LP_UART initialization (#1113) +- Add `place-spi-driver-in-ram` feature to `esp-hal-common` (#1096) + ### Changed - Set up interrupts for the DMA and async enabled peripherals only when `async` feature is provided (#1042) diff --git a/esp-hal/Cargo.toml b/esp-hal/Cargo.toml index c2aa51abed4..bcd5d16109d 100644 --- a/esp-hal/Cargo.toml +++ b/esp-hal/Cargo.toml @@ -158,6 +158,9 @@ rv-init-data = ["esp-riscv-rt/init-data", "esp-riscv-rt/init-rw-text"] rv-zero-rtc-bss = ["esp-riscv-rt/zero-rtc-fast-bss"] rv-init-rtc-data = ["esp-riscv-rt/init-rtc-fast-data", "esp-riscv-rt/init-rtc-fast-text"] +# Configuration for placing device drivers in the IRAM for faster access +place-spi-driver-in-ram = [] + # Enable the `impl-register-debug` feature for the selected PAC debug = [ "esp32?/impl-register-debug", diff --git a/esp-hal/src/spi/master.rs b/esp-hal/src/spi/master.rs index 7ae11e5220d..47933a83d19 100644 --- a/esp-hal/src/spi/master.rs +++ b/esp-hal/src/spi/master.rs @@ -50,6 +50,8 @@ use core::marker::PhantomData; use fugit::HertzU32; +#[cfg(feature = "place-spi-driver-in-ram")] +use procmacros::ram; use super::{ DuplexMode, @@ -1027,6 +1029,7 @@ pub mod dma { /// This will return a [SpiDmaTransfer] owning the buffer(s) and the SPI /// instance. The maximum amount of data to be sent is 32736 /// bytes. + #[cfg_attr(feature = "place-spi-driver-in-ram", ram)] pub fn dma_write( mut self, words: TXBUF, @@ -1053,6 +1056,7 @@ pub mod dma { /// This will return a [SpiDmaTransfer] owning the buffer(s) and the SPI /// instance. The maximum amount of data to be received is 32736 /// bytes. + #[cfg_attr(feature = "place-spi-driver-in-ram", ram)] pub fn dma_read( mut self, mut words: RXBUF, @@ -1119,6 +1123,7 @@ pub mod dma { C::P: SpiPeripheral, M: IsHalfDuplex, { + #[cfg_attr(feature = "place-spi-driver-in-ram", ram)] pub fn read( mut self, data_mode: SpiDataMode, @@ -1192,6 +1197,7 @@ pub mod dma { }) } + #[cfg_attr(feature = "place-spi-driver-in-ram", ram)] pub fn write( mut self, data_mode: SpiDataMode, @@ -1837,6 +1843,7 @@ where Ok(words) } + #[cfg_attr(feature = "place-spi-driver-in-ram", ram)] fn start_write_bytes_dma( &mut self, ptr: *const u8, @@ -1867,6 +1874,7 @@ where Ok(()) } + #[cfg_attr(feature = "place-spi-driver-in-ram", ram)] fn start_read_bytes_dma( &mut self, ptr: *mut u8, @@ -2518,6 +2526,7 @@ pub trait Instance { /// you must ensure that the whole messages was written correctly, use /// [`Self::flush`]. // FIXME: See below. + #[cfg_attr(feature = "place-spi-driver-in-ram", ram)] fn write_bytes(&mut self, words: &[u8]) -> Result<(), Error> { let num_chunks = words.len() / FIFO_SIZE; @@ -2578,6 +2587,7 @@ pub trait Instance { /// Sends out a stuffing byte for every byte to read. This function doesn't /// perform flushing. If you want to read the response to something you /// have written before, consider using [`Self::transfer`] instead. + #[cfg_attr(feature = "place-spi-driver-in-ram", ram)] fn read_bytes(&mut self, words: &mut [u8]) -> Result<(), Error> { let empty_array = [EMPTY_WRITE_PAD; FIFO_SIZE]; @@ -2598,6 +2608,7 @@ pub trait Instance { // FIXME: Using something like `core::slice::from_raw_parts` and // `copy_from_slice` on the receive registers works only for the esp32 and // esp32c3 varaints. The reason for this is unknown. + #[cfg_attr(feature = "place-spi-driver-in-ram", ram)] fn read_bytes_from_fifo(&mut self, words: &mut [u8]) -> Result<(), Error> { let reg_block = self.register_block(); @@ -2634,6 +2645,7 @@ pub trait Instance { Ok(()) } + #[cfg_attr(feature = "place-spi-driver-in-ram", ram)] fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Error> { for chunk in words.chunks_mut(FIFO_SIZE) { self.write_bytes(chunk)?;