Skip to content

Commit

Permalink
Add option to configure the device driver IRAM placement (RFC) (#1096)
Browse files Browse the repository at this point in the history
* SPI RAM patch

* SPI in IRAM

* Add DMA functions to IRAM

* Try fixing the interrupt latency issue

* Revert changes

* Rename the option name to `optimize-spi-in-iram`

* Fix clippy warning

* Fix typo
  • Loading branch information
ProfFan authored Feb 21, 2024
1 parent 4bc1aaa commit 9a95c0a
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,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)
Expand Down
3 changes: 3 additions & 0 deletions esp-hal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
12 changes: 12 additions & 0 deletions esp-hal/src/spi/master.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
use core::marker::PhantomData;

use fugit::HertzU32;
#[cfg(feature = "place-spi-driver-in-ram")]
use procmacros::ram;

use super::{
DuplexMode,
Expand Down Expand Up @@ -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<TXBUF>(
mut self,
words: TXBUF,
Expand All @@ -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<RXBUF>(
mut self,
mut words: RXBUF,
Expand Down Expand Up @@ -1119,6 +1123,7 @@ pub mod dma {
C::P: SpiPeripheral,
M: IsHalfDuplex,
{
#[cfg_attr(feature = "place-spi-driver-in-ram", ram)]
pub fn read<RXBUF>(
mut self,
data_mode: SpiDataMode,
Expand Down Expand Up @@ -1192,6 +1197,7 @@ pub mod dma {
})
}

#[cfg_attr(feature = "place-spi-driver-in-ram", ram)]
pub fn write<TXBUF>(
mut self,
data_mode: SpiDataMode,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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];

Expand All @@ -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();

Expand Down Expand Up @@ -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)?;
Expand Down

0 comments on commit 9a95c0a

Please sign in to comment.