SPI slave with_pin functions (#2485)
This commit is contained in:
parent
4233bddf23
commit
d5e6ba5ceb
@ -34,6 +34,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- GPIO ETM tasks and events now accept `InputSignal` and `OutputSignal` (#2427)
|
- GPIO ETM tasks and events now accept `InputSignal` and `OutputSignal` (#2427)
|
||||||
- `spi::master::Config` and `{Spi, SpiDma, SpiDmaBus}::apply_config` (#2448)
|
- `spi::master::Config` and `{Spi, SpiDma, SpiDmaBus}::apply_config` (#2448)
|
||||||
- `embassy_embedded_hal::SetConfig` is now implemented for `{Spi, SpiDma, SpiDmaBus}` (#2448)
|
- `embassy_embedded_hal::SetConfig` is now implemented for `{Spi, SpiDma, SpiDmaBus}` (#2448)
|
||||||
|
- `slave::Spi::{with_mosi(), with_miso(), with_sclk(), with_cs()}` functions (#2485)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
@ -55,6 +56,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- `spi::master::Spi::new()` no longer takes `frequency` and `mode` as a parameter. (#2448)
|
- `spi::master::Spi::new()` no longer takes `frequency` and `mode` as a parameter. (#2448)
|
||||||
- Peripheral interconnections via GPIO pins now use the GPIO matrix. (#2419)
|
- Peripheral interconnections via GPIO pins now use the GPIO matrix. (#2419)
|
||||||
- The I2S driver has been moved to `i2s::master` (#2472)
|
- The I2S driver has been moved to `i2s::master` (#2472)
|
||||||
|
- `slave::Spi` constructors no longer take pins (#2485)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
|||||||
@ -84,7 +84,6 @@ drivers. It is now possible to execute half-duplex and full-duplex operations on
|
|||||||
- The `Spi::new_half_duplex` constructor has been removed. Use `new` (or `new_typed`) instead.
|
- The `Spi::new_half_duplex` constructor has been removed. Use `new` (or `new_typed`) instead.
|
||||||
- The `with_pins` methods have been removed. Use the individual `with_*` functions instead.
|
- The `with_pins` methods have been removed. Use the individual `with_*` functions instead.
|
||||||
- The `with_mosi` and `with_miso` functions now take input-output peripheral signals to support half-duplex mode.
|
- The `with_mosi` and `with_miso` functions now take input-output peripheral signals to support half-duplex mode.
|
||||||
> TODO(danielb): this means they are currently only usable with GPIO pins, but upcoming GPIO changes should allow using any output signal.
|
|
||||||
|
|
||||||
```diff
|
```diff
|
||||||
- let mut spi = Spi::new_half_duplex(peripherals.SPI2, 100.kHz(), SpiMode::Mode0)
|
- let mut spi = Spi::new_half_duplex(peripherals.SPI2, 100.kHz(), SpiMode::Mode0)
|
||||||
@ -131,6 +130,28 @@ The `Spi<'_, SPI, HalfDuplexMode>::read` and `Spi<'_, SPI, HalfDuplexMode>::writ
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Slave-mode SPI
|
||||||
|
|
||||||
|
### Driver construction
|
||||||
|
|
||||||
|
The constructors no longer accept pins. Use the `with_pin_name` setters instead.
|
||||||
|
|
||||||
|
```diff
|
||||||
|
let mut spi = Spi::new(
|
||||||
|
peripherals.SPI2,
|
||||||
|
- sclk,
|
||||||
|
- mosi,
|
||||||
|
- miso,
|
||||||
|
- cs,
|
||||||
|
SpiMode::Mode0,
|
||||||
|
-);
|
||||||
|
+)
|
||||||
|
+.with_sclk(sclk)
|
||||||
|
+.with_mosi(mosi)
|
||||||
|
+.with_miso(miso)
|
||||||
|
+.with_cs(cs);
|
||||||
|
```
|
||||||
|
|
||||||
## UART event listening
|
## UART event listening
|
||||||
|
|
||||||
The following functions have been removed:
|
The following functions have been removed:
|
||||||
|
|||||||
@ -34,16 +34,20 @@
|
|||||||
//! dma_buffers!(32000);
|
//! dma_buffers!(32000);
|
||||||
//! let mut spi = Spi::new(
|
//! let mut spi = Spi::new(
|
||||||
//! peripherals.SPI2,
|
//! peripherals.SPI2,
|
||||||
//! sclk,
|
|
||||||
//! mosi,
|
|
||||||
//! miso,
|
|
||||||
//! cs,
|
|
||||||
//! SpiMode::Mode0,
|
//! SpiMode::Mode0,
|
||||||
//! )
|
//! )
|
||||||
//! .with_dma(dma_channel.configure(
|
//! .with_sck(sclk)
|
||||||
//! false,
|
//! .with_mosi(mosi)
|
||||||
//! DmaPriority::Priority0,
|
//! .with_miso(miso)
|
||||||
//! ), rx_descriptors, tx_descriptors);
|
//! .with_cs(cs)
|
||||||
|
//! .with_dma(
|
||||||
|
//! dma_channel.configure(
|
||||||
|
//! false,
|
||||||
|
//! DmaPriority::Priority0,
|
||||||
|
//! ),
|
||||||
|
//! rx_descriptors,
|
||||||
|
//! tx_descriptors,
|
||||||
|
//! );
|
||||||
//!
|
//!
|
||||||
//! let mut receive = rx_buffer;
|
//! let mut receive = rx_buffer;
|
||||||
//! let mut send = tx_buffer;
|
//! let mut send = tx_buffer;
|
||||||
@ -79,6 +83,7 @@ use crate::{
|
|||||||
gpio::{
|
gpio::{
|
||||||
interconnect::{PeripheralInput, PeripheralOutput},
|
interconnect::{PeripheralInput, PeripheralOutput},
|
||||||
InputSignal,
|
InputSignal,
|
||||||
|
NoPin,
|
||||||
OutputSignal,
|
OutputSignal,
|
||||||
},
|
},
|
||||||
peripheral::{Peripheral, PeripheralRef},
|
peripheral::{Peripheral, PeripheralRef},
|
||||||
@ -103,20 +108,8 @@ pub struct Spi<'d, M, T = AnySpi> {
|
|||||||
|
|
||||||
impl<'d> Spi<'d, Blocking> {
|
impl<'d> Spi<'d, Blocking> {
|
||||||
/// Constructs an SPI instance in 8bit dataframe mode.
|
/// Constructs an SPI instance in 8bit dataframe mode.
|
||||||
pub fn new<
|
pub fn new(spi: impl Peripheral<P = impl Instance> + 'd, mode: SpiMode) -> Spi<'d, Blocking> {
|
||||||
SCK: PeripheralInput,
|
Self::new_typed(spi.map_into(), mode)
|
||||||
MOSI: PeripheralInput,
|
|
||||||
MISO: PeripheralOutput,
|
|
||||||
CS: PeripheralInput,
|
|
||||||
>(
|
|
||||||
spi: impl Peripheral<P = impl Instance> + 'd,
|
|
||||||
sclk: 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, Blocking> {
|
|
||||||
Self::new_typed(spi.map_into(), sclk, mosi, miso, cs, mode)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,55 +118,57 @@ where
|
|||||||
T: Instance,
|
T: Instance,
|
||||||
{
|
{
|
||||||
/// Constructs an SPI instance in 8bit dataframe mode.
|
/// Constructs an SPI instance in 8bit dataframe mode.
|
||||||
pub fn new_typed<
|
pub fn new_typed(spi: impl Peripheral<P = T> + 'd, mode: SpiMode) -> Spi<'d, M, T> {
|
||||||
SCK: PeripheralInput,
|
|
||||||
MOSI: PeripheralInput,
|
|
||||||
MISO: PeripheralOutput,
|
|
||||||
CS: PeripheralInput,
|
|
||||||
>(
|
|
||||||
spi: impl Peripheral<P = T> + 'd,
|
|
||||||
sclk: 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, M, T> {
|
|
||||||
crate::into_mapped_ref!(sclk, mosi, miso, cs);
|
|
||||||
|
|
||||||
let this = Self::new_internal(spi, mode);
|
|
||||||
|
|
||||||
// TODO: with_pins et. al.
|
|
||||||
sclk.enable_input(true, private::Internal);
|
|
||||||
this.spi.info().sclk.connect_to(sclk);
|
|
||||||
|
|
||||||
mosi.enable_input(true, private::Internal);
|
|
||||||
this.spi.info().mosi.connect_to(mosi);
|
|
||||||
|
|
||||||
miso.set_to_push_pull_output(private::Internal);
|
|
||||||
this.spi.info().miso.connect_to(miso);
|
|
||||||
|
|
||||||
cs.enable_input(true, private::Internal);
|
|
||||||
this.spi.info().cs.connect_to(cs);
|
|
||||||
|
|
||||||
this
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn new_internal(spi: impl Peripheral<P = T> + 'd, mode: SpiMode) -> Spi<'d, M, T> {
|
|
||||||
crate::into_ref!(spi);
|
crate::into_ref!(spi);
|
||||||
|
|
||||||
let spi = Spi {
|
let this = Spi {
|
||||||
spi,
|
spi,
|
||||||
data_mode: mode,
|
data_mode: mode,
|
||||||
_mode: PhantomData,
|
_mode: PhantomData,
|
||||||
};
|
};
|
||||||
|
|
||||||
PeripheralClockControl::reset(spi.spi.info().peripheral);
|
PeripheralClockControl::reset(this.spi.info().peripheral);
|
||||||
PeripheralClockControl::enable(spi.spi.info().peripheral);
|
PeripheralClockControl::enable(this.spi.info().peripheral);
|
||||||
|
|
||||||
spi.spi.info().init();
|
this.spi.info().init();
|
||||||
spi.spi.info().set_data_mode(mode, false);
|
this.spi.info().set_data_mode(mode, false);
|
||||||
|
|
||||||
spi
|
this.with_mosi(NoPin)
|
||||||
|
.with_miso(NoPin)
|
||||||
|
.with_sck(NoPin)
|
||||||
|
.with_cs(NoPin)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Assign the SCK (Serial Clock) pin for the SPI instance.
|
||||||
|
pub fn with_sck(self, sclk: impl Peripheral<P = impl PeripheralInput> + 'd) -> Self {
|
||||||
|
crate::into_mapped_ref!(sclk);
|
||||||
|
sclk.enable_input(true, private::Internal);
|
||||||
|
self.spi.info().sclk.connect_to(sclk);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Assign the MOSI (Master Out Slave In) pin for the SPI instance.
|
||||||
|
pub fn with_mosi(self, mosi: impl Peripheral<P = impl PeripheralInput> + 'd) -> Self {
|
||||||
|
crate::into_mapped_ref!(mosi);
|
||||||
|
mosi.enable_input(true, private::Internal);
|
||||||
|
self.spi.info().mosi.connect_to(mosi);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Assign the MISO (Master In Slave Out) pin for the SPI instance.
|
||||||
|
pub fn with_miso(self, miso: impl Peripheral<P = impl PeripheralOutput> + 'd) -> Self {
|
||||||
|
crate::into_mapped_ref!(miso);
|
||||||
|
miso.set_to_push_pull_output(private::Internal);
|
||||||
|
self.spi.info().miso.connect_to(miso);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Assign the CS (Chip Select) pin for the SPI instance.
|
||||||
|
pub fn with_cs(self, cs: impl Peripheral<P = impl PeripheralInput> + 'd) -> Self {
|
||||||
|
crate::into_mapped_ref!(cs);
|
||||||
|
cs.enable_input(true, private::Internal);
|
||||||
|
self.spi.info().cs.connect_to(cs);
|
||||||
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -67,19 +67,16 @@ fn main() -> ! {
|
|||||||
|
|
||||||
let (rx_buffer, rx_descriptors, tx_buffer, tx_descriptors) = dma_buffers!(32000);
|
let (rx_buffer, rx_descriptors, tx_buffer, tx_descriptors) = dma_buffers!(32000);
|
||||||
|
|
||||||
let mut spi = Spi::new(
|
let mut spi = Spi::new(peripherals.SPI2, SpiMode::Mode0)
|
||||||
peripherals.SPI2,
|
.with_sck(slave_sclk)
|
||||||
slave_sclk,
|
.with_mosi(slave_mosi)
|
||||||
slave_mosi,
|
.with_miso(slave_miso)
|
||||||
slave_miso,
|
.with_cs(slave_cs)
|
||||||
slave_cs,
|
.with_dma(
|
||||||
SpiMode::Mode0,
|
dma_channel.configure(false, DmaPriority::Priority0),
|
||||||
)
|
rx_descriptors,
|
||||||
.with_dma(
|
tx_descriptors,
|
||||||
dma_channel.configure(false, DmaPriority::Priority0),
|
);
|
||||||
tx_descriptors,
|
|
||||||
rx_descriptors,
|
|
||||||
);
|
|
||||||
|
|
||||||
let delay = Delay::new();
|
let delay = Delay::new();
|
||||||
|
|
||||||
|
|||||||
@ -130,7 +130,11 @@ mod tests {
|
|||||||
let miso = unsafe { miso_gpio.clone_unchecked() }.into_peripheral_output();
|
let miso = unsafe { miso_gpio.clone_unchecked() }.into_peripheral_output();
|
||||||
|
|
||||||
Context {
|
Context {
|
||||||
spi: Spi::new(peripherals.SPI2, sclk, mosi, miso, cs, SpiMode::Mode1),
|
spi: Spi::new(peripherals.SPI2, SpiMode::Mode1)
|
||||||
|
.with_sck(sclk)
|
||||||
|
.with_mosi(mosi)
|
||||||
|
.with_miso(miso)
|
||||||
|
.with_cs(cs),
|
||||||
bitbang_spi: BitbangSpi::new(sclk_gpio, mosi_gpio, miso_gpio, cs_gpio),
|
bitbang_spi: BitbangSpi::new(sclk_gpio, mosi_gpio, miso_gpio, cs_gpio),
|
||||||
dma_channel,
|
dma_channel,
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user