mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-10-01 14:20:44 +00:00
SPI slave: remove public hidden API (#2470)
* Redo declaration as macro * Add Info * Move impl out of Instance traits * Publish traits
This commit is contained in:
parent
0da6eec089
commit
8782429e9f
@ -75,7 +75,7 @@ use core::marker::PhantomData;
|
||||
|
||||
use super::{Error, SpiMode};
|
||||
use crate::{
|
||||
dma::{DescriptorChain, DmaChannelConvert, DmaEligible, PeripheralMarker, Rx, Tx},
|
||||
dma::{DmaChannelConvert, DmaEligible, PeripheralMarker},
|
||||
gpio::{
|
||||
interconnect::{PeripheralInput, PeripheralOutput},
|
||||
InputSignal,
|
||||
@ -144,16 +144,16 @@ where
|
||||
|
||||
// TODO: with_pins et. al.
|
||||
sclk.enable_input(true, private::Internal);
|
||||
this.spi.sclk_signal().connect_to(sclk);
|
||||
this.spi.info().sclk.connect_to(sclk);
|
||||
|
||||
mosi.enable_input(true, private::Internal);
|
||||
this.spi.mosi_signal().connect_to(mosi);
|
||||
this.spi.info().mosi.connect_to(mosi);
|
||||
|
||||
miso.set_to_push_pull_output(private::Internal);
|
||||
this.spi.miso_signal().connect_to(miso);
|
||||
this.spi.info().miso.connect_to(miso);
|
||||
|
||||
cs.enable_input(true, private::Internal);
|
||||
this.spi.cs_signal().connect_to(cs);
|
||||
this.spi.info().cs.connect_to(cs);
|
||||
|
||||
this
|
||||
}
|
||||
@ -161,7 +161,7 @@ where
|
||||
pub(crate) fn new_internal(spi: impl Peripheral<P = T> + 'd, mode: SpiMode) -> Spi<'d, M, T> {
|
||||
crate::into_ref!(spi);
|
||||
|
||||
let mut spi = Spi {
|
||||
let spi = Spi {
|
||||
spi,
|
||||
data_mode: mode,
|
||||
_mode: PhantomData,
|
||||
@ -170,8 +170,8 @@ where
|
||||
PeripheralClockControl::reset(spi.spi.peripheral());
|
||||
PeripheralClockControl::enable(spi.spi.peripheral());
|
||||
|
||||
spi.spi.init();
|
||||
spi.spi.set_data_mode(mode, false);
|
||||
spi.spi.info().init();
|
||||
spi.spi.info().set_data_mode(mode, false);
|
||||
|
||||
spi
|
||||
}
|
||||
@ -208,7 +208,7 @@ pub mod dma {
|
||||
/// descriptors.
|
||||
#[cfg_attr(esp32, doc = "\n\n**Note**: ESP32 only supports Mode 1 and 3.")]
|
||||
pub fn with_dma<CH, DM>(
|
||||
mut self,
|
||||
self,
|
||||
channel: Channel<'d, CH, DM>,
|
||||
rx_descriptors: &'static mut [DmaDescriptor],
|
||||
tx_descriptors: &'static mut [DmaDescriptor],
|
||||
@ -218,7 +218,7 @@ pub mod dma {
|
||||
DM: Mode,
|
||||
Channel<'d, CH, M>: From<Channel<'d, CH, DM>>,
|
||||
{
|
||||
self.spi.set_data_mode(self.data_mode, true);
|
||||
self.spi.info().set_data_mode(self.data_mode, true);
|
||||
SpiDma::new(self.spi, channel.into(), rx_descriptors, tx_descriptors)
|
||||
}
|
||||
}
|
||||
@ -253,10 +253,10 @@ pub mod dma {
|
||||
fn peripheral_wait_dma(&mut self, is_rx: bool, is_tx: bool) {
|
||||
while !((!is_tx || self.channel.tx.is_done())
|
||||
&& (!is_rx || self.channel.rx.is_done())
|
||||
&& !self.spi.is_bus_busy())
|
||||
&& !self.spi.info().is_bus_busy())
|
||||
{}
|
||||
|
||||
self.spi.flush().ok();
|
||||
self.spi.info().flush().ok();
|
||||
}
|
||||
|
||||
fn peripheral_dma_stop(&mut self) {
|
||||
@ -318,6 +318,14 @@ pub mod dma {
|
||||
tx_chain: DescriptorChain::new(tx_descriptors),
|
||||
}
|
||||
}
|
||||
|
||||
fn driver(&self) -> DmaDriver {
|
||||
DmaDriver {
|
||||
info: self.spi.info(),
|
||||
dma_peripheral: self.spi.dma_peripheral(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Register a buffer for a DMA write.
|
||||
///
|
||||
/// This will return a [DmaTransferTx]. The maximum amount of data to be
|
||||
@ -338,7 +346,7 @@ pub mod dma {
|
||||
}
|
||||
|
||||
unsafe {
|
||||
self.spi
|
||||
self.driver()
|
||||
.start_transfer_dma(
|
||||
&mut self.rx_chain,
|
||||
&mut self.tx_chain,
|
||||
@ -373,7 +381,7 @@ pub mod dma {
|
||||
}
|
||||
|
||||
unsafe {
|
||||
self.spi
|
||||
self.driver()
|
||||
.start_transfer_dma(
|
||||
&mut self.rx_chain,
|
||||
&mut self.tx_chain,
|
||||
@ -412,7 +420,7 @@ pub mod dma {
|
||||
}
|
||||
|
||||
unsafe {
|
||||
self.spi
|
||||
self.driver()
|
||||
.start_transfer_dma(
|
||||
&mut self.rx_chain,
|
||||
&mut self.tx_chain,
|
||||
@ -427,163 +435,197 @@ pub mod dma {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub trait InstanceDma: Instance + DmaEligible {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
unsafe fn start_transfer_dma<RX, TX>(
|
||||
&mut self,
|
||||
rx_chain: &mut DescriptorChain,
|
||||
tx_chain: &mut DescriptorChain,
|
||||
read_buffer_ptr: *mut u8,
|
||||
read_buffer_len: usize,
|
||||
write_buffer_ptr: *const u8,
|
||||
write_buffer_len: usize,
|
||||
rx: &mut RX,
|
||||
tx: &mut TX,
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
RX: Rx,
|
||||
TX: Tx,
|
||||
{
|
||||
let reg_block = self.register_block();
|
||||
|
||||
self.enable_dma();
|
||||
|
||||
reset_spi(reg_block);
|
||||
|
||||
if read_buffer_len > 0 {
|
||||
rx_chain.fill_for_rx(false, read_buffer_ptr, read_buffer_len)?;
|
||||
rx.prepare_transfer_without_start(self.dma_peripheral(), rx_chain)?;
|
||||
}
|
||||
|
||||
if write_buffer_len > 0 {
|
||||
tx_chain.fill_for_tx(false, write_buffer_ptr, write_buffer_len)?;
|
||||
tx.prepare_transfer_without_start(self.dma_peripheral(), tx_chain)?;
|
||||
}
|
||||
|
||||
#[cfg(esp32)]
|
||||
self.prepare_length_and_lines(read_buffer_len, write_buffer_len);
|
||||
|
||||
reset_dma_before_usr_cmd(reg_block);
|
||||
|
||||
#[cfg(not(esp32))]
|
||||
reg_block
|
||||
.dma_conf()
|
||||
.modify(|_, w| w.dma_slv_seg_trans_en().clear_bit());
|
||||
|
||||
self.clear_dma_interrupts();
|
||||
self.setup_for_flush();
|
||||
reg_block.cmd().modify(|_, w| w.usr().set_bit());
|
||||
|
||||
if read_buffer_len > 0 {
|
||||
rx.start_transfer()?;
|
||||
}
|
||||
|
||||
if write_buffer_len > 0 {
|
||||
tx.start_transfer()?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
struct DmaDriver {
|
||||
info: &'static Info,
|
||||
dma_peripheral: crate::dma::DmaPeripheral,
|
||||
}
|
||||
|
||||
fn enable_dma(&self) {
|
||||
let reg_block = self.register_block();
|
||||
#[cfg(gdma)]
|
||||
impl DmaDriver {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
unsafe fn start_transfer_dma<RX, TX>(
|
||||
&self,
|
||||
rx_chain: &mut DescriptorChain,
|
||||
tx_chain: &mut DescriptorChain,
|
||||
read_buffer_ptr: *mut u8,
|
||||
read_buffer_len: usize,
|
||||
write_buffer_ptr: *const u8,
|
||||
write_buffer_len: usize,
|
||||
rx: &mut RX,
|
||||
tx: &mut TX,
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
RX: Rx,
|
||||
TX: Tx,
|
||||
{
|
||||
self.enable_dma();
|
||||
|
||||
self.info.reset_spi();
|
||||
|
||||
if read_buffer_len > 0 {
|
||||
rx_chain.fill_for_rx(false, read_buffer_ptr, read_buffer_len)?;
|
||||
rx.prepare_transfer_without_start(self.dma_peripheral, rx_chain)?;
|
||||
}
|
||||
|
||||
if write_buffer_len > 0 {
|
||||
tx_chain.fill_for_tx(false, write_buffer_ptr, write_buffer_len)?;
|
||||
tx.prepare_transfer_without_start(self.dma_peripheral, tx_chain)?;
|
||||
}
|
||||
|
||||
#[cfg(esp32)]
|
||||
self.info
|
||||
.prepare_length_and_lines(read_buffer_len, write_buffer_len);
|
||||
|
||||
self.reset_dma_before_usr_cmd();
|
||||
|
||||
let reg_block = self.info.register_block();
|
||||
#[cfg(not(esp32))]
|
||||
reg_block
|
||||
.dma_conf()
|
||||
.modify(|_, w| w.dma_slv_seg_trans_en().clear_bit());
|
||||
|
||||
self.clear_dma_interrupts();
|
||||
self.info.setup_for_flush();
|
||||
reg_block.cmd().modify(|_, w| w.usr().set_bit());
|
||||
|
||||
if read_buffer_len > 0 {
|
||||
rx.start_transfer()?;
|
||||
}
|
||||
|
||||
if write_buffer_len > 0 {
|
||||
tx.start_transfer()?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn reset_dma_before_usr_cmd(&self) {
|
||||
let reg_block = self.info.register_block();
|
||||
#[cfg(gdma)]
|
||||
reg_block.dma_conf().modify(|_, w| {
|
||||
w.dma_tx_ena().set_bit();
|
||||
w.dma_rx_ena().set_bit();
|
||||
w.rx_eof_en().clear_bit()
|
||||
w.rx_afifo_rst().set_bit();
|
||||
w.buf_afifo_rst().set_bit();
|
||||
w.dma_afifo_rst().set_bit()
|
||||
});
|
||||
|
||||
#[cfg(pdma)]
|
||||
let _ = reg_block;
|
||||
}
|
||||
|
||||
fn enable_dma(&self) {
|
||||
let reg_block = self.info.register_block();
|
||||
#[cfg(gdma)]
|
||||
{
|
||||
reg_block.dma_conf().modify(|_, w| {
|
||||
w.dma_tx_ena().set_bit();
|
||||
w.dma_rx_ena().set_bit();
|
||||
w.rx_eof_en().clear_bit()
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(pdma)]
|
||||
{
|
||||
fn set_rst_bit(reg_block: &RegisterBlock, bit: bool) {
|
||||
reg_block.dma_conf().modify(|_, w| {
|
||||
w.in_rst().bit(bit);
|
||||
w.out_rst().bit(bit);
|
||||
w.ahbm_fifo_rst().bit(bit);
|
||||
w.ahbm_rst().bit(bit)
|
||||
});
|
||||
|
||||
#[cfg(esp32s2)]
|
||||
reg_block
|
||||
.dma_conf()
|
||||
.modify(|_, w| w.dma_infifo_full_clr().bit(bit));
|
||||
}
|
||||
set_rst_bit(reg_block, true);
|
||||
set_rst_bit(reg_block, false);
|
||||
}
|
||||
}
|
||||
|
||||
fn clear_dma_interrupts(&self) {
|
||||
let reg_block = self.info.register_block();
|
||||
|
||||
#[cfg(gdma)]
|
||||
reg_block.dma_int_clr().write(|w| {
|
||||
w.dma_infifo_full_err().clear_bit_by_one();
|
||||
w.dma_outfifo_empty_err().clear_bit_by_one();
|
||||
w.trans_done().clear_bit_by_one();
|
||||
w.mst_rx_afifo_wfull_err().clear_bit_by_one();
|
||||
w.mst_tx_afifo_rempty_err().clear_bit_by_one()
|
||||
});
|
||||
|
||||
#[cfg(pdma)]
|
||||
reg_block.dma_int_clr().write(|w| {
|
||||
w.inlink_dscr_empty().clear_bit_by_one();
|
||||
w.outlink_dscr_error().clear_bit_by_one();
|
||||
w.inlink_dscr_error().clear_bit_by_one();
|
||||
w.in_done().clear_bit_by_one();
|
||||
w.in_err_eof().clear_bit_by_one();
|
||||
w.in_suc_eof().clear_bit_by_one();
|
||||
w.out_done().clear_bit_by_one();
|
||||
w.out_eof().clear_bit_by_one();
|
||||
w.out_total_eof().clear_bit_by_one()
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(pdma)]
|
||||
{
|
||||
fn set_rst_bit(reg_block: &RegisterBlock, bit: bool) {
|
||||
reg_block.dma_conf().modify(|_, w| {
|
||||
w.in_rst().bit(bit);
|
||||
w.out_rst().bit(bit);
|
||||
w.ahbm_fifo_rst().bit(bit);
|
||||
w.ahbm_rst().bit(bit)
|
||||
});
|
||||
|
||||
#[cfg(esp32s2)]
|
||||
reg_block
|
||||
.dma_conf()
|
||||
.modify(|_, w| w.dma_infifo_full_clr().bit(bit));
|
||||
}
|
||||
set_rst_bit(reg_block, true);
|
||||
set_rst_bit(reg_block, false);
|
||||
}
|
||||
}
|
||||
|
||||
fn clear_dma_interrupts(&self) {
|
||||
let reg_block = self.register_block();
|
||||
|
||||
#[cfg(gdma)]
|
||||
reg_block.dma_int_clr().write(|w| {
|
||||
w.dma_infifo_full_err().clear_bit_by_one();
|
||||
w.dma_outfifo_empty_err().clear_bit_by_one();
|
||||
w.trans_done().clear_bit_by_one();
|
||||
w.mst_rx_afifo_wfull_err().clear_bit_by_one();
|
||||
w.mst_tx_afifo_rempty_err().clear_bit_by_one()
|
||||
});
|
||||
|
||||
#[cfg(pdma)]
|
||||
reg_block.dma_int_clr().write(|w| {
|
||||
w.inlink_dscr_empty().clear_bit_by_one();
|
||||
w.outlink_dscr_error().clear_bit_by_one();
|
||||
w.inlink_dscr_error().clear_bit_by_one();
|
||||
w.in_done().clear_bit_by_one();
|
||||
w.in_err_eof().clear_bit_by_one();
|
||||
w.in_suc_eof().clear_bit_by_one();
|
||||
w.out_done().clear_bit_by_one();
|
||||
w.out_eof().clear_bit_by_one();
|
||||
w.out_total_eof().clear_bit_by_one()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn reset_spi(reg_block: &RegisterBlock) {
|
||||
#[cfg(esp32)]
|
||||
{
|
||||
reg_block.slave().modify(|_, w| w.sync_reset().set_bit());
|
||||
reg_block.slave().modify(|_, w| w.sync_reset().clear_bit());
|
||||
}
|
||||
|
||||
#[cfg(not(esp32))]
|
||||
{
|
||||
reg_block.slave().modify(|_, w| w.soft_reset().set_bit());
|
||||
reg_block.slave().modify(|_, w| w.soft_reset().clear_bit());
|
||||
}
|
||||
/// SPI peripheral instance.
|
||||
pub trait Instance: Peripheral<P = Self> + Into<AnySpi> + PeripheralMarker + 'static {
|
||||
/// Returns the peripheral data describing this SPI instance.
|
||||
fn info(&self) -> &'static Info;
|
||||
}
|
||||
|
||||
fn reset_dma_before_usr_cmd(reg_block: &RegisterBlock) {
|
||||
#[cfg(gdma)]
|
||||
reg_block.dma_conf().modify(|_, w| {
|
||||
w.rx_afifo_rst().set_bit();
|
||||
w.buf_afifo_rst().set_bit();
|
||||
w.dma_afifo_rst().set_bit()
|
||||
});
|
||||
|
||||
#[cfg(pdma)]
|
||||
let _ = reg_block;
|
||||
}
|
||||
/// A marker for DMA-capable SPI peripheral instances.
|
||||
pub trait InstanceDma: Instance + DmaEligible {}
|
||||
|
||||
impl InstanceDma for crate::peripherals::SPI2 {}
|
||||
#[cfg(spi3)]
|
||||
impl InstanceDma for crate::peripherals::SPI3 {}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub trait Instance: Peripheral<P = Self> + Into<AnySpi> + PeripheralMarker + 'static {
|
||||
fn register_block(&self) -> &RegisterBlock;
|
||||
/// Peripheral data describing a particular SPI instance.
|
||||
#[non_exhaustive]
|
||||
pub struct Info {
|
||||
/// Pointer to the register block for this SPI instance.
|
||||
///
|
||||
/// Use [Self::register_block] to access the register block.
|
||||
pub register_block: *const RegisterBlock,
|
||||
|
||||
fn sclk_signal(&self) -> InputSignal;
|
||||
fn mosi_signal(&self) -> InputSignal;
|
||||
fn miso_signal(&self) -> OutputSignal;
|
||||
fn cs_signal(&self) -> InputSignal;
|
||||
/// SCLK signal.
|
||||
pub sclk: InputSignal,
|
||||
|
||||
/// MOSI signal.
|
||||
pub mosi: InputSignal,
|
||||
|
||||
/// MISO signal.
|
||||
pub miso: OutputSignal,
|
||||
|
||||
/// Chip select signal.
|
||||
pub cs: InputSignal,
|
||||
}
|
||||
|
||||
impl Info {
|
||||
/// Returns the register block for this SPI instance.
|
||||
pub fn register_block(&self) -> &RegisterBlock {
|
||||
unsafe { &*self.register_block }
|
||||
}
|
||||
|
||||
fn reset_spi(&self) {
|
||||
let reg_block = self.register_block();
|
||||
|
||||
#[cfg(esp32)]
|
||||
{
|
||||
reg_block.slave().modify(|_, w| w.sync_reset().set_bit());
|
||||
reg_block.slave().modify(|_, w| w.sync_reset().clear_bit());
|
||||
}
|
||||
|
||||
#[cfg(not(esp32))]
|
||||
{
|
||||
reg_block.slave().modify(|_, w| w.soft_reset().set_bit());
|
||||
reg_block.slave().modify(|_, w| w.soft_reset().clear_bit());
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(esp32)]
|
||||
fn prepare_length_and_lines(&self, rx_len: usize, tx_len: usize) {
|
||||
@ -604,7 +646,7 @@ pub trait Instance: Peripheral<P = Self> + Into<AnySpi> + PeripheralMarker + 'st
|
||||
}
|
||||
|
||||
/// Initialize for full-duplex 1 bit mode
|
||||
fn init(&mut self) {
|
||||
fn init(&self) {
|
||||
let reg_block = self.register_block();
|
||||
|
||||
reg_block.clock().write(|w| unsafe { w.bits(0) });
|
||||
@ -617,7 +659,7 @@ pub trait Instance: Peripheral<P = Self> + Into<AnySpi> + PeripheralMarker + 'st
|
||||
|
||||
w.mode().set_bit()
|
||||
});
|
||||
reset_spi(reg_block);
|
||||
self.reset_spi();
|
||||
|
||||
reg_block.user().modify(|_, w| {
|
||||
w.doutdin().set_bit();
|
||||
@ -628,7 +670,7 @@ pub trait Instance: Peripheral<P = Self> + Into<AnySpi> + PeripheralMarker + 'st
|
||||
reg_block.misc().write(|w| unsafe { w.bits(0) });
|
||||
}
|
||||
|
||||
fn set_data_mode(&mut self, data_mode: SpiMode, dma: bool) -> &mut Self {
|
||||
fn set_data_mode(&self, data_mode: SpiMode, dma: bool) {
|
||||
let reg_block = self.register_block();
|
||||
#[cfg(esp32)]
|
||||
{
|
||||
@ -699,8 +741,6 @@ pub trait Instance: Peripheral<P = Self> + Into<AnySpi> + PeripheralMarker + 'st
|
||||
.bit(matches!(data_mode, SpiMode::Mode1 | SpiMode::Mode3))
|
||||
});
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
fn is_bus_busy(&self) -> bool {
|
||||
@ -717,7 +757,7 @@ pub trait Instance: Peripheral<P = Self> + Into<AnySpi> + PeripheralMarker + 'st
|
||||
}
|
||||
|
||||
// Check if the bus is busy and if it is wait for it to be idle
|
||||
fn flush(&mut self) -> Result<(), Error> {
|
||||
fn flush(&self) -> Result<(), Error> {
|
||||
while self.is_bus_busy() {
|
||||
// Wait for bus to be clear
|
||||
}
|
||||
@ -738,107 +778,46 @@ pub trait Instance: Peripheral<P = Self> + Into<AnySpi> + PeripheralMarker + 'st
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(spi2)]
|
||||
impl Instance for crate::peripherals::SPI2 {
|
||||
#[inline(always)]
|
||||
fn register_block(&self) -> &RegisterBlock {
|
||||
self
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn sclk_signal(&self) -> InputSignal {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(esp32)] {
|
||||
InputSignal::HSPICLK
|
||||
} else {
|
||||
InputSignal::FSPICLK
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn mosi_signal(&self) -> InputSignal {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(esp32)] {
|
||||
InputSignal::HSPID
|
||||
} else {
|
||||
InputSignal::FSPID
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn miso_signal(&self) -> OutputSignal {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(esp32)] {
|
||||
OutputSignal::HSPIQ
|
||||
} else {
|
||||
OutputSignal::FSPIQ
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn cs_signal(&self) -> InputSignal {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(esp32)] {
|
||||
InputSignal::HSPICS0
|
||||
} else {
|
||||
InputSignal::FSPICS0
|
||||
}
|
||||
}
|
||||
impl PartialEq for Info {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.register_block == other.register_block
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(spi3)]
|
||||
impl Instance for crate::peripherals::SPI3 {
|
||||
#[inline(always)]
|
||||
fn register_block(&self) -> &RegisterBlock {
|
||||
self
|
||||
}
|
||||
unsafe impl Sync for Info {}
|
||||
|
||||
#[inline(always)]
|
||||
fn sclk_signal(&self) -> InputSignal {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(esp32)] {
|
||||
InputSignal::VSPICLK
|
||||
} else {
|
||||
InputSignal::SPI3_CLK
|
||||
macro_rules! spi_instance {
|
||||
($num:literal, $sclk:ident, $mosi:ident, $miso:ident, $cs:ident) => {
|
||||
paste::paste! {
|
||||
impl Instance for crate::peripherals::[<SPI $num>] {
|
||||
#[inline(always)]
|
||||
fn info(&self) -> &'static Info {
|
||||
static INFO: Info = Info {
|
||||
register_block: crate::peripherals::[<SPI $num>]::PTR,
|
||||
sclk: InputSignal::$sclk,
|
||||
mosi: InputSignal::$mosi,
|
||||
miso: OutputSignal::$miso,
|
||||
cs: InputSignal::$cs,
|
||||
};
|
||||
|
||||
&INFO
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn mosi_signal(&self) -> InputSignal {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(esp32)] {
|
||||
InputSignal::VSPID
|
||||
} else {
|
||||
InputSignal::SPI3_D
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn miso_signal(&self) -> OutputSignal {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(esp32)] {
|
||||
OutputSignal::VSPIQ
|
||||
} else {
|
||||
OutputSignal::SPI3_Q
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn cs_signal(&self) -> InputSignal {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(esp32)] {
|
||||
InputSignal::VSPICS0
|
||||
} else {
|
||||
InputSignal::SPI3_CS0
|
||||
}
|
||||
}
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(esp32)] {
|
||||
#[cfg(spi2)]
|
||||
spi_instance!(2, HSPICLK, HSPID, HSPIQ, HSPICS0);
|
||||
#[cfg(spi3)]
|
||||
spi_instance!(3, VSPICLK, VSPID, VSPIQ, VSPICS0);
|
||||
} else {
|
||||
#[cfg(spi2)]
|
||||
spi_instance!(2, FSPICLK, FSPID, FSPIQ, FSPICS0);
|
||||
#[cfg(spi3)]
|
||||
spi_instance!(3, SPI3_CLK, SPI3_D, SPI3_Q, SPI3_CS0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -849,11 +828,7 @@ impl Instance for super::AnySpi {
|
||||
#[cfg(spi3)]
|
||||
super::AnySpiInner::Spi3(spi) => spi,
|
||||
} {
|
||||
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 info(&self) -> &'static Info;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user