use core::marker::PhantomData;
use super::{Error, FullDuplexMode, SpiMode};
use crate::{
dma::{DmaPeripheral, Rx, Tx},
gpio::{InputPin, InputSignal, OutputPin, OutputSignal},
peripheral::{Peripheral, PeripheralRef},
peripherals::spi2::RegisterBlock,
system::PeripheralClockControl,
};
pub mod prelude {
#[cfg(spi3)]
pub use super::dma::WithDmaSpi3 as _esp_hal_spi_slave_dma_WithDmaSpi3;
pub use super::{
dma::WithDmaSpi2 as _esp_hal_spi_slave_dma_WithDmaSpi2,
Instance as _esp_hal_spi_slave_Instance,
InstanceDma as _esp_hal_spi_slave_InstanceDma,
};
}
const MAX_DMA_SIZE: usize = 32768 - 32;
pub struct Spi<'d, T, M> {
spi: PeripheralRef<'d, T>,
#[allow(dead_code)]
data_mode: SpiMode,
_mode: PhantomData<M>,
}
impl<'d, T> Spi<'d, T, FullDuplexMode>
where
T: Instance,
{
pub fn new<SCK: InputPin, MOSI: InputPin, MISO: OutputPin, CS: InputPin>(
spi: impl Peripheral<P = T> + 'd,
sck: impl Peripheral<P = SCK> + 'd,
mosi: impl Peripheral<P = MOSI> + 'd,
miso: impl Peripheral<P = MISO> + 'd,
cs: impl Peripheral<P = CS> + 'd,
mode: SpiMode,
) -> Spi<'d, T, FullDuplexMode> {
crate::into_ref!(spi, sck, mosi, miso, cs);
sck.set_to_input()
.connect_input_to_peripheral(spi.sclk_signal());
mosi.set_to_input()
.connect_input_to_peripheral(spi.mosi_signal());
miso.set_to_push_pull_output()
.connect_peripheral_to_output(spi.miso_signal());
cs.set_to_input()
.connect_input_to_peripheral(spi.cs_signal());
Self::new_internal(spi, mode)
}
pub(crate) fn new_internal(
spi: PeripheralRef<'d, T>,
mode: SpiMode,
) -> Spi<'d, T, FullDuplexMode> {
spi.enable_peripheral();
let mut spi = Spi {
spi,
data_mode: mode,
_mode: PhantomData,
};
spi.spi.init();
spi.spi.set_data_mode(mode);
spi
}
}
pub mod dma {
use core::mem;
use embedded_dma::{ReadBuffer, WriteBuffer};
use super::*;
#[cfg(spi3)]
use crate::dma::Spi3Peripheral;
use crate::dma::{
Channel,
ChannelTypes,
DmaError,
DmaTransfer,
DmaTransferRxTx,
RxPrivate,
Spi2Peripheral,
SpiPeripheral,
TxPrivate,
};
pub trait WithDmaSpi2<'d, C>
where
C: ChannelTypes,
C::P: SpiPeripheral,
{
fn with_dma(self, channel: Channel<'d, C>) -> SpiDma<'d, crate::peripherals::SPI2, C>;
}
#[cfg(spi3)]
pub trait WithDmaSpi3<'d, C>
where
C: ChannelTypes,
C::P: SpiPeripheral,
{
fn with_dma(self, channel: Channel<'d, C>) -> SpiDma<'d, crate::peripherals::SPI3, C>;
}
impl<'d, C> WithDmaSpi2<'d, C> for Spi<'d, crate::peripherals::SPI2, FullDuplexMode>
where
C: ChannelTypes,
C::P: SpiPeripheral + Spi2Peripheral,
{
fn with_dma(self, mut channel: Channel<'d, C>) -> SpiDma<'d, crate::peripherals::SPI2, C> {
channel.tx.init_channel();
#[cfg(esp32)]
match self.data_mode {
SpiMode::Mode0 | SpiMode::Mode2 => {
self.spi.invert_i_edge();
}
_ => {}
}
SpiDma {
spi: self.spi,
channel,
}
}
}
#[cfg(spi3)]
impl<'d, C> WithDmaSpi3<'d, C> for Spi<'d, crate::peripherals::SPI3, FullDuplexMode>
where
C: ChannelTypes,
C::P: SpiPeripheral + Spi3Peripheral,
{
fn with_dma(self, mut channel: Channel<'d, C>) -> SpiDma<'d, crate::peripherals::SPI3, C> {
channel.tx.init_channel();
#[cfg(esp32)]
match self.data_mode {
SpiMode::Mode0 | SpiMode::Mode2 => {
self.spi.invert_i_edge();
}
_ => {}
}
SpiDma {
spi: self.spi,
channel,
}
}
}
pub struct SpiDmaTransferRxTx<'d, T, C, RBUFFER, TBUFFER>
where
T: InstanceDma<C::Tx<'d>, C::Rx<'d>>,
C: ChannelTypes,
C::P: SpiPeripheral,
{
spi_dma: SpiDma<'d, T, C>,
rbuffer: RBUFFER,
tbuffer: TBUFFER,
}
impl<'d, T, C, RXBUF, TXBUF> DmaTransferRxTx<RXBUF, TXBUF, SpiDma<'d, T, C>>
for SpiDmaTransferRxTx<'d, T, C, RXBUF, TXBUF>
where
T: InstanceDma<C::Tx<'d>, C::Rx<'d>>,
C: ChannelTypes,
C::P: SpiPeripheral,
{
fn wait(
mut self,
) -> Result<(RXBUF, TXBUF, SpiDma<'d, T, C>), (DmaError, RXBUF, TXBUF, SpiDma<'d, T, C>)>
{
while !self.is_done() {}
self.spi_dma.spi.flush().ok();
let err = self.spi_dma.channel.rx.has_error() || self.spi_dma.channel.tx.has_error();
unsafe {
let rbuffer = core::ptr::read(&self.rbuffer);
let tbuffer = core::ptr::read(&self.tbuffer);
let payload = core::ptr::read(&self.spi_dma);
mem::forget(self);
if err {
Err((DmaError::DescriptorError, rbuffer, tbuffer, payload))
} else {
Ok((rbuffer, tbuffer, payload))
}
}
}
fn is_done(&self) -> bool {
let ch = &self.spi_dma.channel;
ch.tx.is_done() && ch.rx.is_done() && !self.spi_dma.spi.is_bus_busy()
}
}
impl<'d, T, C, RXBUF, TXBUF> Drop for SpiDmaTransferRxTx<'d, T, C, RXBUF, TXBUF>
where
T: InstanceDma<C::Tx<'d>, C::Rx<'d>>,
C: ChannelTypes,
C::P: SpiPeripheral,
{
fn drop(&mut self) {
while !self.is_done() {}
self.spi_dma.spi.flush().ok();
}
}
pub struct SpiDmaTransferRx<'d, T, C, BUFFER>
where
T: InstanceDma<C::Tx<'d>, C::Rx<'d>>,
C: ChannelTypes,
C::P: SpiPeripheral,
{
spi_dma: SpiDma<'d, T, C>,
buffer: BUFFER,
}
impl<'d, T, C, BUFFER> DmaTransfer<BUFFER, SpiDma<'d, T, C>> for SpiDmaTransferRx<'d, T, C, BUFFER>
where
T: InstanceDma<C::Tx<'d>, C::Rx<'d>>,
C: ChannelTypes,
C::P: SpiPeripheral,
{
fn wait(
mut self,
) -> Result<(BUFFER, SpiDma<'d, T, C>), (DmaError, BUFFER, SpiDma<'d, T, C>)> {
while !self.is_done() {}
self.spi_dma.spi.flush().ok();
unsafe {
let buffer = core::ptr::read(&self.buffer);
let payload = core::ptr::read(&self.spi_dma);
let err =
self.spi_dma.channel.rx.has_error() || self.spi_dma.channel.tx.has_error();
mem::forget(self);
if err {
Err((DmaError::DescriptorError, buffer, payload))
} else {
Ok((buffer, payload))
}
}
}
fn is_done(&self) -> bool {
let ch = &self.spi_dma.channel;
ch.rx.is_done()
}
}
impl<'d, T, C, BUFFER> Drop for SpiDmaTransferRx<'d, T, C, BUFFER>
where
T: InstanceDma<C::Tx<'d>, C::Rx<'d>>,
C: ChannelTypes,
C::P: SpiPeripheral,
{
fn drop(&mut self) {
while !self.is_done() {}
self.spi_dma.spi.flush().ok(); }
}
pub struct SpiDmaTransferTx<'d, T, C, BUFFER>
where
T: InstanceDma<C::Tx<'d>, C::Rx<'d>>,
C: ChannelTypes,
C::P: SpiPeripheral,
{
spi_dma: SpiDma<'d, T, C>,
buffer: BUFFER,
}
impl<'d, T, C, BUFFER> DmaTransfer<BUFFER, SpiDma<'d, T, C>> for SpiDmaTransferTx<'d, T, C, BUFFER>
where
T: InstanceDma<C::Tx<'d>, C::Rx<'d>>,
C: ChannelTypes,
C::P: SpiPeripheral,
{
fn wait(
mut self,
) -> Result<(BUFFER, SpiDma<'d, T, C>), (DmaError, BUFFER, SpiDma<'d, T, C>)> {
while !self.is_done() {}
self.spi_dma.spi.flush().ok();
let err = self.spi_dma.channel.rx.has_error() || self.spi_dma.channel.tx.has_error();
unsafe {
let buffer = core::ptr::read(&self.buffer);
let payload = core::ptr::read(&self.spi_dma);
mem::forget(self);
if err {
Err((DmaError::DescriptorError, buffer, payload))
} else {
Ok((buffer, payload))
}
}
}
fn is_done(&self) -> bool {
let ch = &self.spi_dma.channel;
ch.tx.is_done()
}
}
impl<'d, T, C, BUFFER> Drop for SpiDmaTransferTx<'d, T, C, BUFFER>
where
T: InstanceDma<C::Tx<'d>, C::Rx<'d>>,
C: ChannelTypes,
C::P: SpiPeripheral,
{
fn drop(&mut self) {
while !self.is_done() {}
self.spi_dma.spi.flush().ok(); }
}
pub struct SpiDma<'d, T, C>
where
C: ChannelTypes,
C::P: SpiPeripheral,
{
pub(crate) spi: PeripheralRef<'d, T>,
pub(crate) channel: Channel<'d, C>,
}
impl<'d, T, C> core::fmt::Debug for SpiDma<'d, T, C>
where
C: ChannelTypes,
C::P: SpiPeripheral,
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("SpiDma").finish()
}
}
impl<'d, T, C> SpiDma<'d, T, C>
where
T: InstanceDma<C::Tx<'d>, C::Rx<'d>>,
C: ChannelTypes,
C::P: SpiPeripheral,
{
pub fn dma_write<TXBUF>(
mut self,
words: TXBUF,
) -> Result<SpiDmaTransferTx<'d, T, C, TXBUF>, Error>
where
TXBUF: ReadBuffer<Word = u8>,
{
let (ptr, len) = unsafe { words.read_buffer() };
if len > MAX_DMA_SIZE {
return Err(Error::MaxDmaTransferSizeExceeded);
}
self.spi
.start_write_bytes_dma(ptr, len, &mut self.channel.tx)
.map(move |_| SpiDmaTransferTx {
spi_dma: self,
buffer: words,
})
}
pub fn dma_read<RXBUF>(
mut self,
mut words: RXBUF,
) -> Result<SpiDmaTransferRx<'d, T, C, RXBUF>, Error>
where
RXBUF: WriteBuffer<Word = u8>,
{
let (ptr, len) = unsafe { words.write_buffer() };
if len > MAX_DMA_SIZE {
return Err(Error::MaxDmaTransferSizeExceeded);
}
self.spi
.start_read_bytes_dma(ptr, len, &mut self.channel.rx)
.map(move |_| SpiDmaTransferRx {
spi_dma: self,
buffer: words,
})
}
pub fn dma_transfer<TXBUF, RXBUF>(
mut self,
words: TXBUF,
mut read_buffer: RXBUF,
) -> Result<SpiDmaTransferRxTx<'d, T, C, RXBUF, TXBUF>, Error>
where
TXBUF: ReadBuffer<Word = u8>,
RXBUF: WriteBuffer<Word = u8>,
{
let (write_ptr, write_len) = unsafe { words.read_buffer() };
let (read_ptr, read_len) = unsafe { read_buffer.write_buffer() };
if write_len > MAX_DMA_SIZE || read_len > MAX_DMA_SIZE {
return Err(Error::MaxDmaTransferSizeExceeded);
}
self.spi
.start_transfer_dma(
write_ptr,
write_len,
read_ptr,
read_len,
&mut self.channel.tx,
&mut self.channel.rx,
)
.map(move |_| SpiDmaTransferRxTx {
spi_dma: self,
rbuffer: read_buffer,
tbuffer: words,
})
}
}
}
pub trait InstanceDma<TX, RX>: Instance
where
TX: Tx,
RX: Rx,
{
fn start_transfer_dma(
&mut self,
write_buffer_ptr: *const u8,
write_buffer_len: usize,
read_buffer_ptr: *mut u8,
read_buffer_len: usize,
tx: &mut TX,
rx: &mut RX,
) -> Result<(), Error> {
let reg_block = self.register_block();
tx.is_done();
rx.is_done();
self.enable_dma();
reset_dma_before_load_dma_dscr(reg_block);
tx.prepare_transfer_without_start(
self.dma_peripheral(),
false,
write_buffer_ptr,
write_buffer_len,
)?;
rx.prepare_transfer_without_start(
false,
self.dma_peripheral(),
read_buffer_ptr,
read_buffer_len,
)?;
self.clear_dma_interrupts();
reset_dma_before_usr_cmd(reg_block);
#[cfg(not(esp32))]
reg_block
.dma_conf()
.modify(|_, w| w.dma_slv_seg_trans_en().clear_bit());
tx.start_transfer()?;
Ok(rx.start_transfer()?)
}
fn start_write_bytes_dma(
&mut self,
ptr: *const u8,
len: usize,
tx: &mut TX,
) -> Result<(), Error> {
let reg_block = self.register_block();
tx.is_done();
self.enable_dma();
reset_dma_before_load_dma_dscr(reg_block);
tx.prepare_transfer_without_start(self.dma_peripheral(), false, ptr, len)?;
self.clear_dma_interrupts();
reset_dma_before_usr_cmd(reg_block);
#[cfg(not(esp32))]
reg_block
.dma_conf()
.modify(|_, w| w.dma_slv_seg_trans_en().clear_bit());
Ok(tx.start_transfer()?)
}
fn start_read_bytes_dma(&mut self, ptr: *mut u8, len: usize, rx: &mut RX) -> Result<(), Error> {
let reg_block = self.register_block();
rx.is_done();
self.enable_dma();
reset_dma_before_load_dma_dscr(reg_block);
rx.prepare_transfer_without_start(false, self.dma_peripheral(), ptr, len)?;
self.clear_dma_interrupts();
reset_dma_before_usr_cmd(reg_block);
#[cfg(not(esp32))]
reg_block
.dma_conf()
.modify(|_, w| w.dma_slv_seg_trans_en().clear_bit());
Ok(rx.start_transfer()?)
}
fn dma_peripheral(&self) -> DmaPeripheral {
match self.spi_num() {
2 => DmaPeripheral::Spi2,
#[cfg(spi3)]
3 => DmaPeripheral::Spi3,
_ => panic!("Illegal SPI instance"),
}
}
#[cfg(any(esp32c2, esp32c3, esp32c6, esp32h2, esp32s3))]
fn enable_dma(&self) {
let reg_block = self.register_block();
reg_block.dma_conf().modify(|_, w| {
w.dma_tx_ena()
.set_bit()
.dma_rx_ena()
.set_bit()
.rx_eof_en()
.clear_bit()
});
}
#[cfg(any(esp32, esp32s2))]
fn enable_dma(&self) {
}
#[cfg(any(esp32c2, esp32c3, esp32c6, esp32h2, esp32s3))]
fn clear_dma_interrupts(&self) {
let reg_block = self.register_block();
reg_block.dma_int_clr().write(|w| {
w.dma_infifo_full_err_int_clr()
.set_bit()
.dma_outfifo_empty_err_int_clr()
.set_bit()
.trans_done_int_clr()
.set_bit()
.mst_rx_afifo_wfull_err_int_clr()
.set_bit()
.mst_tx_afifo_rempty_err_int_clr()
.set_bit()
});
}
#[cfg(any(esp32, esp32s2))]
fn clear_dma_interrupts(&self) {
let reg_block = self.register_block();
reg_block.dma_int_clr.write(|w| {
w.inlink_dscr_empty_int_clr()
.set_bit()
.outlink_dscr_error_int_clr()
.set_bit()
.inlink_dscr_error_int_clr()
.set_bit()
.in_done_int_clr()
.set_bit()
.in_err_eof_int_clr()
.set_bit()
.in_suc_eof_int_clr()
.set_bit()
.out_done_int_clr()
.set_bit()
.out_eof_int_clr()
.set_bit()
.out_total_eof_int_clr()
.set_bit()
});
}
}
#[cfg(not(any(esp32, esp32s2)))]
fn reset_dma_before_usr_cmd(reg_block: &RegisterBlock) {
reg_block.dma_conf().modify(|_, w| {
w.rx_afifo_rst()
.set_bit()
.buf_afifo_rst()
.set_bit()
.dma_afifo_rst()
.set_bit()
});
}
#[cfg(any(esp32, esp32s2))]
fn reset_dma_before_usr_cmd(_reg_block: &RegisterBlock) {}
#[cfg(not(any(esp32, esp32s2)))]
fn reset_dma_before_load_dma_dscr(_reg_block: &RegisterBlock) {}
#[cfg(any(esp32, esp32s2))]
fn reset_dma_before_load_dma_dscr(reg_block: &RegisterBlock) {
reg_block.dma_conf.modify(|_, w| {
w.out_rst()
.set_bit()
.in_rst()
.set_bit()
.ahbm_fifo_rst()
.set_bit()
.ahbm_rst()
.set_bit()
});
}
impl<TX, RX> InstanceDma<TX, RX> for crate::peripherals::SPI2
where
TX: Tx,
RX: Rx,
{
}
#[cfg(spi3)]
impl<TX, RX> InstanceDma<TX, RX> for crate::peripherals::SPI3
where
TX: Tx,
RX: Rx,
{
}
pub trait Instance {
fn register_block(&self) -> &RegisterBlock;
fn sclk_signal(&self) -> InputSignal;
fn mosi_signal(&self) -> InputSignal;
fn miso_signal(&self) -> OutputSignal;
fn cs_signal(&self) -> InputSignal;
fn enable_peripheral(&self);
fn spi_num(&self) -> u8;
fn init(&mut self) {
let reg_block = self.register_block();
reg_block.slave().write(|w| w.mode().set_bit());
reg_block.user().modify(|_, w| {
w.usr_miso_highpart()
.clear_bit()
.doutdin()
.set_bit()
.usr_miso()
.set_bit()
.usr_mosi()
.set_bit()
.usr_dummy_idle()
.clear_bit()
.usr_addr()
.clear_bit()
.usr_command()
.clear_bit()
});
#[cfg(not(any(esp32, esp32s2)))]
reg_block.clk_gate().modify(|_, w| {
w.clk_en()
.clear_bit()
.mst_clk_active()
.clear_bit()
.mst_clk_sel()
.clear_bit()
});
#[cfg(not(any(esp32, esp32s2)))]
reg_block.ctrl().modify(|_, w| {
w.q_pol()
.clear_bit()
.d_pol()
.clear_bit()
.hold_pol()
.clear_bit()
});
#[cfg(esp32s2)]
reg_block
.ctrl()
.modify(|_, w| w.q_pol().clear_bit().d_pol().clear_bit().wp().clear_bit());
#[cfg(esp32)]
reg_block.ctrl().modify(|_, w| w.wp().clear_bit());
#[cfg(not(esp32))]
reg_block.misc().write(|w| unsafe { w.bits(0) });
}
#[cfg(not(esp32))]
fn set_data_mode(&mut self, data_mode: SpiMode) -> &mut Self {
let reg_block = self.register_block();
match data_mode {
SpiMode::Mode0 => {
reg_block
.user()
.modify(|_, w| w.tsck_i_edge().clear_bit().rsck_i_edge().clear_bit());
#[cfg(esp32s2)]
reg_block.ctrl1.modify(|_, w| w.clk_mode_13().clear_bit());
#[cfg(not(esp32s2))]
reg_block.slave().modify(|_, w| w.clk_mode_13().clear_bit());
}
SpiMode::Mode1 => {
reg_block
.user()
.modify(|_, w| w.tsck_i_edge().set_bit().rsck_i_edge().set_bit());
#[cfg(esp32s2)]
reg_block.ctrl1().modify(|_, w| w.clk_mode_13().set_bit());
#[cfg(not(esp32s2))]
reg_block.slave().modify(|_, w| w.clk_mode_13().set_bit());
}
SpiMode::Mode2 => {
reg_block
.user()
.modify(|_, w| w.tsck_i_edge().set_bit().rsck_i_edge().set_bit());
#[cfg(esp32s2)]
reg_block.ctrl1().modify(|_, w| w.clk_mode_13().clear_bit());
#[cfg(not(esp32s2))]
reg_block.slave().modify(|_, w| w.clk_mode_13().clear_bit());
}
SpiMode::Mode3 => {
reg_block
.user()
.modify(|_, w| w.tsck_i_edge().clear_bit().rsck_i_edge().clear_bit());
#[cfg(esp32s2)]
reg_block.ctrl1().modify(|_, w| w.clk_mode_13().set_bit());
#[cfg(not(esp32s2))]
reg_block.slave().modify(|_, w| w.clk_mode_13().set_bit());
}
}
self
}
#[cfg(esp32)]
fn set_data_mode(&mut self, data_mode: SpiMode) -> &mut Self {
let reg_block = self.register_block();
match data_mode {
SpiMode::Mode0 => {
reg_block.pin.modify(|_, w| w.ck_idle_edge().set_bit());
reg_block.user.modify(|_, w| w.ck_i_edge().clear_bit());
}
SpiMode::Mode1 => {
reg_block.pin.modify(|_, w| w.ck_idle_edge().set_bit());
reg_block.user.modify(|_, w| w.ck_i_edge().set_bit());
}
SpiMode::Mode2 => {
reg_block.pin.modify(|_, w| w.ck_idle_edge().clear_bit());
reg_block.user.modify(|_, w| w.ck_i_edge().set_bit());
}
SpiMode::Mode3 => {
reg_block.pin.modify(|_, w| w.ck_idle_edge().clear_bit());
reg_block.user.modify(|_, w| w.ck_i_edge().clear_bit());
}
}
self
}
#[cfg(esp32)]
fn invert_i_edge(&self) {
let reg_block = self.register_block();
reg_block
.pin
.modify(|r, w| w.ck_idle_edge().variant(r.ck_idle_edge().bit_is_clear()));
reg_block
.user
.modify(|r, w| w.ck_i_edge().variant(r.ck_i_edge().bit_is_clear()));
}
fn is_bus_busy(&self) -> bool {
let reg_block = self.register_block();
#[cfg(any(esp32, esp32s2))]
{
reg_block.slave.read().trans_done().bit_is_clear()
}
#[cfg(not(any(esp32, esp32s2)))]
{
reg_block
.dma_int_raw()
.read()
.trans_done_int_raw()
.bit_is_clear()
}
}
fn flush(&mut self) -> Result<(), Error> {
while self.is_bus_busy() {
}
Ok(())
}
fn setup_for_flush(&self) {
#[cfg(any(esp32, esp32s2))]
self.register_block()
.slave()
.modify(|_, w| w.trans_done().clear_bit());
#[cfg(not(any(esp32, esp32s2)))]
self.register_block()
.dma_int_clr()
.write(|w| w.trans_done_int_clr().set_bit());
}
}
#[cfg(any(esp32c2, esp32c3, esp32c6, esp32h2))]
impl Instance for crate::peripherals::SPI2 {
#[inline(always)]
fn register_block(&self) -> &RegisterBlock {
self
}
#[inline(always)]
fn sclk_signal(&self) -> InputSignal {
InputSignal::FSPICLK
}
#[inline(always)]
fn mosi_signal(&self) -> InputSignal {
InputSignal::FSPID
}
#[inline(always)]
fn miso_signal(&self) -> OutputSignal {
OutputSignal::FSPIQ
}
#[inline(always)]
fn cs_signal(&self) -> InputSignal {
InputSignal::FSPICS0
}
#[inline(always)]
fn enable_peripheral(&self) {
PeripheralClockControl::enable(crate::system::Peripheral::Spi2);
}
#[inline(always)]
fn spi_num(&self) -> u8 {
2
}
}
#[cfg(esp32)]
impl Instance for crate::peripherals::SPI2 {
#[inline(always)]
fn register_block(&self) -> &RegisterBlock {
self
}
#[inline(always)]
fn sclk_signal(&self) -> InputSignal {
InputSignal::HSPICLK
}
#[inline(always)]
fn mosi_signal(&self) -> InputSignal {
InputSignal::HSPID
}
#[inline(always)]
fn miso_signal(&self) -> OutputSignal {
OutputSignal::HSPIQ
}
#[inline(always)]
fn cs_signal(&self) -> InputSignal {
InputSignal::HSPICS0
}
#[inline(always)]
fn enable_peripheral(&self) {
PeripheralClockControl::enable(crate::system::Peripheral::Spi2);
}
#[inline(always)]
fn spi_num(&self) -> u8 {
2
}
}
#[cfg(esp32)]
impl Instance for crate::peripherals::SPI3 {
#[inline(always)]
fn register_block(&self) -> &RegisterBlock {
self
}
#[inline(always)]
fn sclk_signal(&self) -> InputSignal {
InputSignal::VSPICLK
}
#[inline(always)]
fn mosi_signal(&self) -> InputSignal {
InputSignal::VSPID
}
#[inline(always)]
fn miso_signal(&self) -> OutputSignal {
OutputSignal::VSPIQ
}
#[inline(always)]
fn cs_signal(&self) -> InputSignal {
InputSignal::VSPICS0
}
#[inline(always)]
fn enable_peripheral(&self) {
PeripheralClockControl::enable(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 sclk_signal(&self) -> InputSignal {
InputSignal::FSPICLK
}
#[inline(always)]
fn mosi_signal(&self) -> InputSignal {
InputSignal::FSPID
}
#[inline(always)]
fn miso_signal(&self) -> OutputSignal {
OutputSignal::FSPIQ
}
#[inline(always)]
fn cs_signal(&self) -> InputSignal {
InputSignal::FSPICS0
}
#[inline(always)]
fn enable_peripheral(&self) {
PeripheralClockControl::enable(crate::system::Peripheral::Spi2)
}
#[inline(always)]
fn spi_num(&self) -> u8 {
2
}
}
#[cfg(any(esp32s2, esp32s3))]
impl Instance for crate::peripherals::SPI3 {
#[inline(always)]
fn register_block(&self) -> &RegisterBlock {
self
}
#[inline(always)]
fn sclk_signal(&self) -> InputSignal {
InputSignal::SPI3_CLK
}
#[inline(always)]
fn mosi_signal(&self) -> InputSignal {
InputSignal::SPI3_D
}
#[inline(always)]
fn miso_signal(&self) -> OutputSignal {
OutputSignal::SPI3_Q
}
#[inline(always)]
fn cs_signal(&self) -> InputSignal {
InputSignal::SPI3_CS0
}
#[inline(always)]
fn enable_peripheral(&self) {
PeripheralClockControl::enable(crate::system::Peripheral::Spi3)
}
#[inline(always)]
fn spi_num(&self) -> u8 {
3
}
}