Make miso/mosi optional when for unidirectional spi
Only suported on v1 currently
This commit is contained in:
parent
c44bed300b
commit
259e84e68e
@ -8,7 +8,7 @@ mod _version;
|
|||||||
use crate::{dma, peripherals, rcc::RccPeripheral};
|
use crate::{dma, peripherals, rcc::RccPeripheral};
|
||||||
pub use _version::*;
|
pub use _version::*;
|
||||||
|
|
||||||
use crate::gpio::Pin;
|
use crate::gpio::OptionalPin;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
@ -53,15 +53,15 @@ pub(crate) mod sealed {
|
|||||||
fn regs() -> &'static crate::pac::spi::Spi;
|
fn regs() -> &'static crate::pac::spi::Spi;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait SckPin<T: Instance>: Pin {
|
pub trait SckPin<T: Instance>: OptionalPin {
|
||||||
fn af_num(&self) -> u8;
|
fn af_num(&self) -> u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait MosiPin<T: Instance>: Pin {
|
pub trait MosiPin<T: Instance>: OptionalPin {
|
||||||
fn af_num(&self) -> u8;
|
fn af_num(&self) -> u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait MisoPin<T: Instance>: Pin {
|
pub trait MisoPin<T: Instance>: OptionalPin {
|
||||||
fn af_num(&self) -> u8;
|
fn af_num(&self) -> u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,9 +6,10 @@ use crate::gpio::{
|
|||||||
AFType::{OutputOpenDrain, OutputPushPull},
|
AFType::{OutputOpenDrain, OutputPushPull},
|
||||||
Pin,
|
Pin,
|
||||||
},
|
},
|
||||||
AnyPin,
|
AnyPin, NoPin,
|
||||||
};
|
};
|
||||||
use crate::pac::spi;
|
use crate::pac::spi;
|
||||||
|
use crate::peripherals;
|
||||||
use crate::spi::{
|
use crate::spi::{
|
||||||
ByteOrder, Config, Error, Instance, MisoPin, MosiPin, RxDmaChannel, SckPin, TxDmaChannel,
|
ByteOrder, Config, Error, Instance, MisoPin, MosiPin, RxDmaChannel, SckPin, TxDmaChannel,
|
||||||
WordSize,
|
WordSize,
|
||||||
@ -20,6 +21,7 @@ use core::ptr;
|
|||||||
use embassy::util::Unborrow;
|
use embassy::util::Unborrow;
|
||||||
use embassy_hal_common::unborrow;
|
use embassy_hal_common::unborrow;
|
||||||
use embassy_traits::spi as traits;
|
use embassy_traits::spi as traits;
|
||||||
|
pub use embedded_hal::blocking;
|
||||||
pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
|
pub use embedded_hal::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MODE_3};
|
||||||
use futures::future::join3;
|
use futures::future::join3;
|
||||||
|
|
||||||
@ -32,10 +34,29 @@ impl WordSize {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! impl_nopin {
|
||||||
|
($inst:ident, $signal:ident) => {
|
||||||
|
impl $signal<peripherals::$inst> for NoPin {}
|
||||||
|
|
||||||
|
impl super::sealed::$signal<peripherals::$inst> for NoPin {
|
||||||
|
fn af_num(&self) -> u8 {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
crate::pac::peripherals!(
|
||||||
|
(spi, $inst:ident) => {
|
||||||
|
impl_nopin!($inst, SckPin);
|
||||||
|
impl_nopin!($inst, MosiPin);
|
||||||
|
impl_nopin!($inst, MisoPin);
|
||||||
|
};
|
||||||
|
);
|
||||||
|
|
||||||
pub struct Spi<'d, T: Instance, Tx, Rx> {
|
pub struct Spi<'d, T: Instance, Tx, Rx> {
|
||||||
sck: AnyPin,
|
sck: Option<AnyPin>,
|
||||||
mosi: AnyPin,
|
mosi: Option<AnyPin>,
|
||||||
miso: AnyPin,
|
miso: Option<AnyPin>,
|
||||||
txdma: Tx,
|
txdma: Tx,
|
||||||
rxdma: Rx,
|
rxdma: Rx,
|
||||||
current_word_size: WordSize,
|
current_word_size: WordSize,
|
||||||
@ -58,15 +79,18 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
|
|||||||
{
|
{
|
||||||
unborrow!(sck, mosi, miso, txdma, rxdma);
|
unborrow!(sck, mosi, miso, txdma, rxdma);
|
||||||
|
|
||||||
unsafe {
|
let sck_af = sck.af_num();
|
||||||
sck.set_as_af(sck.af_num(), OutputPushPull);
|
let mosi_af = mosi.af_num();
|
||||||
mosi.set_as_af(mosi.af_num(), OutputPushPull);
|
let miso_af = miso.af_num();
|
||||||
miso.set_as_af(miso.af_num(), OutputOpenDrain);
|
let sck = sck.degrade_optional();
|
||||||
}
|
let mosi = mosi.degrade_optional();
|
||||||
|
let miso = miso.degrade_optional();
|
||||||
|
|
||||||
let sck = sck.degrade();
|
unsafe {
|
||||||
let mosi = mosi.degrade();
|
sck.as_ref().map(|x| x.set_as_af(sck_af, OutputPushPull));
|
||||||
let miso = miso.degrade();
|
mosi.as_ref().map(|x| x.set_as_af(mosi_af, OutputPushPull));
|
||||||
|
miso.as_ref().map(|x| x.set_as_af(miso_af, OutputOpenDrain));
|
||||||
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
T::regs().cr2().modify(|w| {
|
T::regs().cr2().modify(|w| {
|
||||||
@ -103,6 +127,9 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
|
|||||||
w.set_ssm(true);
|
w.set_ssm(true);
|
||||||
w.set_crcen(false);
|
w.set_crcen(false);
|
||||||
w.set_bidimode(spi::vals::Bidimode::UNIDIRECTIONAL);
|
w.set_bidimode(spi::vals::Bidimode::UNIDIRECTIONAL);
|
||||||
|
if mosi.is_none() {
|
||||||
|
w.set_rxonly(spi::vals::Rxonly::OUTPUTDISABLED);
|
||||||
|
}
|
||||||
w.set_dff(WordSize::EightBit.dff())
|
w.set_dff(WordSize::EightBit.dff())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -294,9 +321,9 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
|
|||||||
impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> {
|
impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.sck.set_as_analog();
|
self.sck.as_ref().map(|x| x.set_as_analog());
|
||||||
self.mosi.set_as_analog();
|
self.mosi.as_ref().map(|x| x.set_as_analog());
|
||||||
self.miso.set_as_analog();
|
self.miso.as_ref().map(|x| x.set_as_analog());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,9 +36,9 @@ impl WordSize {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Spi<'d, T: Instance, Tx, Rx> {
|
pub struct Spi<'d, T: Instance, Tx, Rx> {
|
||||||
sck: AnyPin,
|
sck: Option<AnyPin>,
|
||||||
mosi: AnyPin,
|
mosi: Option<AnyPin>,
|
||||||
miso: AnyPin,
|
miso: Option<AnyPin>,
|
||||||
txdma: Tx,
|
txdma: Tx,
|
||||||
rxdma: Rx,
|
rxdma: Rx,
|
||||||
phantom: PhantomData<&'d mut T>,
|
phantom: PhantomData<&'d mut T>,
|
||||||
@ -60,15 +60,21 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
|
|||||||
{
|
{
|
||||||
unborrow!(sck, mosi, miso, txdma, rxdma);
|
unborrow!(sck, mosi, miso, txdma, rxdma);
|
||||||
|
|
||||||
unsafe {
|
let sck_af = sck.af_num();
|
||||||
Self::configure_pin(sck.block(), sck.pin() as _, sck.af_num());
|
let mosi_af = mosi.af_num();
|
||||||
Self::configure_pin(mosi.block(), mosi.pin() as _, mosi.af_num());
|
let miso_af = miso.af_num();
|
||||||
Self::configure_pin(miso.block(), miso.pin() as _, miso.af_num());
|
let sck = sck.degrade_optional();
|
||||||
}
|
let mosi = mosi.degrade_optional();
|
||||||
|
let miso = miso.degrade_optional();
|
||||||
|
|
||||||
let sck = sck.degrade();
|
unsafe {
|
||||||
let mosi = mosi.degrade();
|
sck.as_ref()
|
||||||
let miso = miso.degrade();
|
.map(|x| Self::configure_pin(x.block(), x.pin() as _, sck_af));
|
||||||
|
sck.as_ref()
|
||||||
|
.map(|x| Self::configure_pin(x.block(), x.pin() as _, mosi_af));
|
||||||
|
sck.as_ref()
|
||||||
|
.map(|x| Self::configure_pin(x.block(), x.pin() as _, miso_af));
|
||||||
|
}
|
||||||
|
|
||||||
let pclk = T::frequency();
|
let pclk = T::frequency();
|
||||||
let freq = freq.into();
|
let freq = freq.into();
|
||||||
@ -307,9 +313,15 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
|
|||||||
impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> {
|
impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
Self::unconfigure_pin(self.sck.block(), self.sck.pin() as _);
|
self.sck
|
||||||
Self::unconfigure_pin(self.mosi.block(), self.mosi.pin() as _);
|
.as_ref()
|
||||||
Self::unconfigure_pin(self.miso.block(), self.miso.pin() as _);
|
.map(|x| Self::unconfigure_pin(x.block(), x.pin() as _));
|
||||||
|
self.mosi
|
||||||
|
.as_ref()
|
||||||
|
.map(|x| Self::unconfigure_pin(x.block(), x.pin() as _));
|
||||||
|
self.miso
|
||||||
|
.as_ref()
|
||||||
|
.map(|x| Self::unconfigure_pin(x.block(), x.pin() as _));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,9 +38,9 @@ impl WordSize {
|
|||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub struct Spi<'d, T: Instance, Tx = NoDma, Rx = NoDma> {
|
pub struct Spi<'d, T: Instance, Tx = NoDma, Rx = NoDma> {
|
||||||
sck: AnyPin,
|
sck: Option<AnyPin>,
|
||||||
mosi: AnyPin,
|
mosi: Option<AnyPin>,
|
||||||
miso: AnyPin,
|
miso: Option<AnyPin>,
|
||||||
txdma: Tx,
|
txdma: Tx,
|
||||||
rxdma: Rx,
|
rxdma: Rx,
|
||||||
phantom: PhantomData<&'d mut T>,
|
phantom: PhantomData<&'d mut T>,
|
||||||
@ -62,17 +62,23 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
|
|||||||
{
|
{
|
||||||
unborrow!(sck, mosi, miso, txdma, rxdma);
|
unborrow!(sck, mosi, miso, txdma, rxdma);
|
||||||
|
|
||||||
unsafe {
|
let sck_af = sck.af_num();
|
||||||
Self::configure_pin(sck.block(), sck.pin() as _, sck.af_num());
|
let mosi_af = mosi.af_num();
|
||||||
//sck.block().otyper().modify(|w| w.set_ot(sck.pin() as _, crate::pac::gpio::vals::Ot::PUSHPULL));
|
let miso_af = miso.af_num();
|
||||||
Self::configure_pin(mosi.block(), mosi.pin() as _, mosi.af_num());
|
let sck = sck.degrade_optional();
|
||||||
//mosi.block().otyper().modify(|w| w.set_ot(mosi.pin() as _, crate::pac::gpio::vals::Ot::PUSHPULL));
|
let mosi = mosi.degrade_optional();
|
||||||
Self::configure_pin(miso.block(), miso.pin() as _, miso.af_num());
|
let miso = miso.degrade_optional();
|
||||||
}
|
|
||||||
|
|
||||||
let sck = sck.degrade();
|
unsafe {
|
||||||
let mosi = mosi.degrade();
|
sck.as_ref()
|
||||||
let miso = miso.degrade();
|
.map(|x| Self::configure_pin(x.block(), x.pin() as _, sck_af));
|
||||||
|
//sck.block().otyper().modify(|w| w.set_ot(Pin::pin(sck) as _, crate::pac::gpio::vals::Ot::PUSHPULL));
|
||||||
|
sck.as_ref()
|
||||||
|
.map(|x| Self::configure_pin(x.block(), x.pin() as _, mosi_af));
|
||||||
|
//mosi.block().otyper().modify(|w| w.set_ot(Pin::pin(mosi) as _, crate::pac::gpio::vals::Ot::PUSHPULL));
|
||||||
|
sck.as_ref()
|
||||||
|
.map(|x| Self::configure_pin(x.block(), x.pin() as _, miso_af));
|
||||||
|
}
|
||||||
|
|
||||||
let pclk = T::frequency();
|
let pclk = T::frequency();
|
||||||
let br = Self::compute_baud_rate(pclk, freq.into());
|
let br = Self::compute_baud_rate(pclk, freq.into());
|
||||||
@ -340,9 +346,15 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
|
|||||||
impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> {
|
impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
Self::unconfigure_pin(self.sck.block(), self.sck.pin() as _);
|
self.sck
|
||||||
Self::unconfigure_pin(self.mosi.block(), self.mosi.pin() as _);
|
.as_ref()
|
||||||
Self::unconfigure_pin(self.miso.block(), self.miso.pin() as _);
|
.map(|x| Self::unconfigure_pin(x.block(), x.pin() as _));
|
||||||
|
self.mosi
|
||||||
|
.as_ref()
|
||||||
|
.map(|x| Self::unconfigure_pin(x.block(), x.pin() as _));
|
||||||
|
self.miso
|
||||||
|
.as_ref()
|
||||||
|
.map(|x| Self::unconfigure_pin(x.block(), x.pin() as _));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user