From 0981c1b619529fca8bb2eb2029e8afd8efb54fd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Buga?= Date: Fri, 27 Sep 2024 19:03:18 +0200 Subject: [PATCH] SPI peripheral signal cleanup (#2245) * Compact peripheral description a bit * Enable QSPI on ESP32 SPI3 * Remove SPI4 from ESP32S2 * Changelog * Remove inaccurate comment --- esp-hal/CHANGELOG.md | 1 + esp-hal/src/spi/master.rs | 424 ++++++++++++------------------ esp-metadata/devices/esp32s2.toml | 1 - 3 files changed, 168 insertions(+), 258 deletions(-) diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md index 0514cd5f490..47f3a53364e 100644 --- a/esp-hal/CHANGELOG.md +++ b/esp-hal/CHANGELOG.md @@ -73,6 +73,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - SPI: Fixed an issue where repeated calls to `dma_transfer` may end up looping indefinitely (#2179) - SPI: Fixed an issue that prevented correctly reading the first byte in a transaction (#2179) - SPI: ESP32: Send address with correct data mode even when no data is sent. (#2231) +- SPI: ESP32: Allow using QSPI mode on SPI3. (#2245) - PARL_IO: Fixed an issue that caused garbage to be output at the start of some requests (#2211) - TWAI on ESP32 (#2207) diff --git a/esp-hal/src/spi/master.rs b/esp-hal/src/spi/master.rs index c8de6d380b7..d43006d99c6 100644 --- a/esp-hal/src/spi/master.rs +++ b/esp-hal/src/spi/master.rs @@ -507,10 +507,7 @@ where /// /// Copies the content of `words` in chunks of 64 bytes into the SPI /// transmission FIFO. If `words` is longer than 64 bytes, multiple - /// sequential transfers are performed. This function will return before - /// all bytes of the last chunk to transmit have been sent to the wire. If - /// you must ensure that the whole messages was written correctly, use - /// `flush`. + /// sequential transfers are performed. pub fn write_bytes(&mut self, words: &[u8]) -> Result<(), Error> { self.spi.write_bytes(words)?; self.spi.flush()?; @@ -2466,6 +2463,8 @@ pub trait ExtendedInstance: Instance { #[doc(hidden)] pub trait Instance: private::Sealed { + fn peripheral(&self) -> crate::system::Peripheral; + fn register_block(&self) -> &RegisterBlock; fn sclk_signal(&self) -> OutputSignal; @@ -2476,9 +2475,15 @@ pub trait Instance: private::Sealed { fn cs_signal(&self) -> OutputSignal; - fn enable_peripheral(&self); + #[inline(always)] + fn enable_peripheral(&self) { + PeripheralClockControl::enable(self.peripheral()); + } - fn reset_peripheral(&self); + #[inline(always)] + fn reset_peripheral(&self) { + PeripheralClockControl::reset(self.peripheral()); + } fn spi_num(&self) -> u8; @@ -3136,93 +3141,21 @@ fn set_up_common_phases(reg_block: &RegisterBlock, cmd: Command, address: Addres } } -#[cfg(any(esp32c2, esp32c3, esp32c6, esp32h2))] +#[cfg(spi2)] impl Instance for crate::peripherals::SPI2 { #[inline(always)] fn register_block(&self) -> &RegisterBlock { self } - #[inline(always)] - fn set_interrupt_handler(&mut self, handler: InterruptHandler) { - self.bind_spi2_interrupt(handler.handler()); - crate::interrupt::enable(crate::peripherals::Interrupt::SPI2, handler.priority()).unwrap(); - } - - #[inline(always)] - fn sclk_signal(&self) -> OutputSignal { - OutputSignal::FSPICLK_MUX - } - - #[inline(always)] - fn mosi_signal(&self) -> OutputSignal { - OutputSignal::FSPID - } - - #[inline(always)] - fn miso_signal(&self) -> InputSignal { - InputSignal::FSPIQ - } - - #[inline(always)] - fn cs_signal(&self) -> OutputSignal { - OutputSignal::FSPICS0 - } - - #[inline(always)] - fn enable_peripheral(&self) { - PeripheralClockControl::enable(crate::system::Peripheral::Spi2); - } - - #[inline(always)] - fn reset_peripheral(&self) { - PeripheralClockControl::reset(crate::system::Peripheral::Spi2); - } - #[inline(always)] fn spi_num(&self) -> u8 { 2 } -} - -#[cfg(any(esp32c2, esp32c3, esp32c6, esp32h2))] -impl ExtendedInstance for crate::peripherals::SPI2 { - #[inline(always)] - fn sio0_input_signal(&self) -> InputSignal { - InputSignal::FSPID - } - - #[inline(always)] - fn sio1_output_signal(&self) -> OutputSignal { - OutputSignal::FSPIQ - } - - #[inline(always)] - fn sio2_output_signal(&self) -> OutputSignal { - OutputSignal::FSPIWP - } - - #[inline(always)] - fn sio2_input_signal(&self) -> InputSignal { - InputSignal::FSPIWP - } #[inline(always)] - fn sio3_output_signal(&self) -> OutputSignal { - OutputSignal::FSPIHD - } - - #[inline(always)] - fn sio3_input_signal(&self) -> InputSignal { - InputSignal::FSPIHD - } -} - -#[cfg(esp32)] -impl Instance for crate::peripherals::SPI2 { - #[inline(always)] - fn register_block(&self) -> &RegisterBlock { - self + fn peripheral(&self) -> crate::system::Peripheral { + crate::system::Peripheral::Spi2 } #[inline(always)] @@ -3233,203 +3166,135 @@ impl Instance for crate::peripherals::SPI2 { #[inline(always)] fn sclk_signal(&self) -> OutputSignal { - OutputSignal::HSPICLK + cfg_if::cfg_if! { + if #[cfg(esp32)] { + OutputSignal::HSPICLK + } else if #[cfg(any(esp32s2, esp32s3))] { + OutputSignal::FSPICLK + } else { + OutputSignal::FSPICLK_MUX + } + } } #[inline(always)] fn mosi_signal(&self) -> OutputSignal { - OutputSignal::HSPID + cfg_if::cfg_if! { + if #[cfg(esp32)] { + OutputSignal::HSPID + } else { + OutputSignal::FSPID + } + } } #[inline(always)] fn miso_signal(&self) -> InputSignal { - InputSignal::HSPIQ + cfg_if::cfg_if! { + if #[cfg(esp32)] { + InputSignal::HSPIQ + } else { + InputSignal::FSPIQ + } + } } #[inline(always)] fn cs_signal(&self) -> OutputSignal { - OutputSignal::HSPICS0 - } - - #[inline(always)] - fn enable_peripheral(&self) { - PeripheralClockControl::enable(crate::system::Peripheral::Spi2); - } - - #[inline(always)] - fn reset_peripheral(&self) { - PeripheralClockControl::reset(crate::system::Peripheral::Spi2); - } - - #[inline(always)] - fn spi_num(&self) -> u8 { - 2 + cfg_if::cfg_if! { + if #[cfg(esp32)] { + OutputSignal::HSPICS0 + } else { + OutputSignal::FSPICS0 + } + } } } -#[cfg(esp32)] +#[cfg(spi2)] impl ExtendedInstance for crate::peripherals::SPI2 { + #[inline(always)] fn sio0_input_signal(&self) -> InputSignal { - InputSignal::HSPID + cfg_if::cfg_if! { + if #[cfg(esp32)] { + InputSignal::HSPID + } else { + InputSignal::FSPID + } + } } + #[inline(always)] fn sio1_output_signal(&self) -> OutputSignal { - OutputSignal::HSPIQ + cfg_if::cfg_if! { + if #[cfg(esp32)] { + OutputSignal::HSPIQ + } else { + OutputSignal::FSPIQ + } + } } + #[inline(always)] fn sio2_output_signal(&self) -> OutputSignal { - OutputSignal::HSPIWP + cfg_if::cfg_if! { + if #[cfg(esp32)] { + OutputSignal::HSPIWP + } else { + OutputSignal::FSPIWP + } + } } + #[inline(always)] fn sio2_input_signal(&self) -> InputSignal { - InputSignal::HSPIWP + cfg_if::cfg_if! { + if #[cfg(esp32)] { + InputSignal::HSPIWP + } else { + InputSignal::FSPIWP + } + } } + #[inline(always)] fn sio3_output_signal(&self) -> OutputSignal { - OutputSignal::HSPIHD + cfg_if::cfg_if! { + if #[cfg(esp32)] { + OutputSignal::HSPIHD + } else { + OutputSignal::FSPIHD + } + } } + #[inline(always)] fn sio3_input_signal(&self) -> InputSignal { - InputSignal::HSPIHD + cfg_if::cfg_if! { + if #[cfg(esp32)] { + InputSignal::HSPIHD + } else { + InputSignal::FSPIHD + } + } } } -#[cfg(esp32)] +#[cfg(spi3)] impl Instance for crate::peripherals::SPI3 { #[inline(always)] fn register_block(&self) -> &RegisterBlock { self } - #[inline(always)] - fn set_interrupt_handler(&mut self, handler: InterruptHandler) { - self.bind_spi3_interrupt(handler.handler()); - crate::interrupt::enable(crate::peripherals::Interrupt::SPI3, handler.priority()).unwrap(); - } - - #[inline(always)] - fn sclk_signal(&self) -> OutputSignal { - OutputSignal::VSPICLK - } - - #[inline(always)] - fn mosi_signal(&self) -> OutputSignal { - OutputSignal::VSPID - } - - #[inline(always)] - fn miso_signal(&self) -> InputSignal { - InputSignal::VSPIQ - } - - #[inline(always)] - fn cs_signal(&self) -> OutputSignal { - OutputSignal::VSPICS0 - } - - #[inline(always)] - fn enable_peripheral(&self) { - PeripheralClockControl::enable(crate::system::Peripheral::Spi3) - } - - #[inline(always)] - fn reset_peripheral(&self) { - PeripheralClockControl::reset(crate::system::Peripheral::Spi3) - } - #[inline(always)] fn spi_num(&self) -> u8 { 3 } -} - -#[cfg(any(esp32s2, esp32s3))] -impl Instance for crate::peripherals::SPI2 { - #[inline(always)] - fn register_block(&self) -> &RegisterBlock { - self - } - - #[inline(always)] - fn set_interrupt_handler(&mut self, handler: InterruptHandler) { - self.bind_spi2_interrupt(handler.handler()); - crate::interrupt::enable(crate::peripherals::Interrupt::SPI2, handler.priority()).unwrap(); - } - - #[inline(always)] - fn sclk_signal(&self) -> OutputSignal { - OutputSignal::FSPICLK - } - - #[inline(always)] - fn mosi_signal(&self) -> OutputSignal { - OutputSignal::FSPID - } - - #[inline(always)] - fn miso_signal(&self) -> InputSignal { - InputSignal::FSPIQ - } - - #[inline(always)] - fn cs_signal(&self) -> OutputSignal { - OutputSignal::FSPICS0 - } - - #[inline(always)] - fn enable_peripheral(&self) { - PeripheralClockControl::enable(crate::system::Peripheral::Spi2) - } - - #[inline(always)] - fn reset_peripheral(&self) { - PeripheralClockControl::reset(crate::system::Peripheral::Spi2) - } - - #[inline(always)] - fn spi_num(&self) -> u8 { - 2 - } -} - -#[cfg(any(esp32s2, esp32s3))] -impl ExtendedInstance for crate::peripherals::SPI2 { - #[inline(always)] - fn sio0_input_signal(&self) -> InputSignal { - InputSignal::FSPID - } - - #[inline(always)] - fn sio1_output_signal(&self) -> OutputSignal { - OutputSignal::FSPIQ - } - - #[inline(always)] - fn sio2_output_signal(&self) -> OutputSignal { - OutputSignal::FSPIWP - } - - #[inline(always)] - fn sio2_input_signal(&self) -> InputSignal { - InputSignal::FSPIWP - } - - #[inline(always)] - fn sio3_output_signal(&self) -> OutputSignal { - OutputSignal::FSPIHD - } #[inline(always)] - fn sio3_input_signal(&self) -> InputSignal { - InputSignal::FSPIHD - } -} - -#[cfg(any(esp32s2, esp32s3))] -impl Instance for crate::peripherals::SPI3 { - #[inline(always)] - fn register_block(&self) -> &RegisterBlock { - self + fn peripheral(&self) -> crate::system::Peripheral { + crate::system::Peripheral::Spi3 } #[inline(always)] @@ -3440,69 +3305,114 @@ impl Instance for crate::peripherals::SPI3 { #[inline(always)] fn sclk_signal(&self) -> OutputSignal { - OutputSignal::SPI3_CLK + cfg_if::cfg_if! { + if #[cfg(esp32)] { + OutputSignal::VSPICLK + } else { + OutputSignal::SPI3_CLK + } + } } #[inline(always)] fn mosi_signal(&self) -> OutputSignal { - OutputSignal::SPI3_D + cfg_if::cfg_if! { + if #[cfg(esp32)] { + OutputSignal::VSPID + } else { + OutputSignal::SPI3_D + } + } } #[inline(always)] fn miso_signal(&self) -> InputSignal { - InputSignal::SPI3_Q + cfg_if::cfg_if! { + if #[cfg(esp32)] { + InputSignal::VSPIQ + } else { + InputSignal::SPI3_Q + } + } } #[inline(always)] fn cs_signal(&self) -> OutputSignal { - OutputSignal::SPI3_CS0 - } - - #[inline(always)] - fn enable_peripheral(&self) { - PeripheralClockControl::enable(crate::system::Peripheral::Spi3) - } - - #[inline(always)] - fn reset_peripheral(&self) { - PeripheralClockControl::reset(crate::system::Peripheral::Spi3) - } - - #[inline(always)] - fn spi_num(&self) -> u8 { - 3 + cfg_if::cfg_if! { + if #[cfg(esp32)] { + OutputSignal::VSPICS0 + } else { + OutputSignal::SPI3_CS0 + } + } } } -#[cfg(esp32s3)] +#[cfg(all(spi3, any(esp32, esp32s3)))] impl ExtendedInstance for crate::peripherals::SPI3 { #[inline(always)] fn sio0_input_signal(&self) -> InputSignal { - InputSignal::SPI3_D + cfg_if::cfg_if! { + if #[cfg(esp32)] { + InputSignal::HSPID + } else { + InputSignal::SPI3_D + } + } } #[inline(always)] fn sio1_output_signal(&self) -> OutputSignal { - OutputSignal::SPI3_Q + cfg_if::cfg_if! { + if #[cfg(esp32)] { + OutputSignal::HSPIQ + } else { + OutputSignal::SPI3_Q + } + } } #[inline(always)] fn sio2_output_signal(&self) -> OutputSignal { - OutputSignal::SPI3_WP + cfg_if::cfg_if! { + if #[cfg(esp32)] { + OutputSignal::HSPIWP + } else { + OutputSignal::SPI3_WP + } + } } #[inline(always)] fn sio2_input_signal(&self) -> InputSignal { - InputSignal::SPI3_WP + cfg_if::cfg_if! { + if #[cfg(esp32)] { + InputSignal::HSPIWP + } else { + InputSignal::SPI3_WP + } + } } #[inline(always)] fn sio3_output_signal(&self) -> OutputSignal { - OutputSignal::SPI3_HD + cfg_if::cfg_if! { + if #[cfg(esp32)] { + OutputSignal::HSPIHD + } else { + OutputSignal::SPI3_HD + } + } } #[inline(always)] fn sio3_input_signal(&self) -> InputSignal { - InputSignal::SPI3_HD + cfg_if::cfg_if! { + if #[cfg(esp32)] { + InputSignal::HSPIHD + } else { + InputSignal::SPI3_HD + } + } } } diff --git a/esp-metadata/devices/esp32s2.toml b/esp-metadata/devices/esp32s2.toml index 9d51c04ec04..2b556cd00cf 100644 --- a/esp-metadata/devices/esp32s2.toml +++ b/esp-metadata/devices/esp32s2.toml @@ -34,7 +34,6 @@ peripherals = [ "spi1", "spi2", "spi3", - "spi4", "system", "systimer", "timg0",