Merge pull request #413 from topisani/master
feat: Add spi support for STM32F1 variants
This commit is contained in:
commit
3cf130ecfe
@ -5,7 +5,7 @@ use embassy::util::Unborrow;
|
|||||||
use embassy_hal_common::unborrow;
|
use embassy_hal_common::unborrow;
|
||||||
|
|
||||||
use crate::gpio::{
|
use crate::gpio::{
|
||||||
sealed::OutputType::{OpenDrain, PushPull},
|
sealed::AFType::{OutputOpenDrain, OutputPushPull},
|
||||||
Pin,
|
Pin,
|
||||||
};
|
};
|
||||||
use crate::{peripherals, rcc::RccPeripheral};
|
use crate::{peripherals, rcc::RccPeripheral};
|
||||||
@ -26,8 +26,8 @@ impl<'d, T: Instance + bxcan::Instance> Can<'d, T> {
|
|||||||
unborrow!(peri, rx, tx);
|
unborrow!(peri, rx, tx);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
rx.set_as_af(rx.af_num(), OpenDrain);
|
rx.set_as_af(rx.af_num(), OutputOpenDrain);
|
||||||
tx.set_as_af(tx.af_num(), PushPull);
|
tx.set_as_af(tx.af_num(), OutputPushPull);
|
||||||
}
|
}
|
||||||
|
|
||||||
T::enable();
|
T::enable();
|
||||||
|
@ -10,7 +10,7 @@ use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU};
|
|||||||
|
|
||||||
use crate::gpio::sealed::Pin as __GpioPin;
|
use crate::gpio::sealed::Pin as __GpioPin;
|
||||||
use crate::gpio::Pin as GpioPin;
|
use crate::gpio::Pin as GpioPin;
|
||||||
use crate::gpio::{sealed::OutputType::PushPull, AnyPin};
|
use crate::gpio::{sealed::AFType::OutputPushPull, AnyPin};
|
||||||
use crate::pac::gpio::vals::Ospeedr;
|
use crate::pac::gpio::vals::Ospeedr;
|
||||||
use crate::pac::{ETH, RCC, SYSCFG};
|
use crate::pac::{ETH, RCC, SYSCFG};
|
||||||
use crate::peripherals;
|
use crate::peripherals;
|
||||||
@ -416,7 +416,7 @@ macro_rules! impl_pin {
|
|||||||
fn configure(&mut self) {
|
fn configure(&mut self) {
|
||||||
// NOTE(unsafe) Exclusive access to the registers
|
// NOTE(unsafe) Exclusive access to the registers
|
||||||
critical_section::with(|_| unsafe {
|
critical_section::with(|_| unsafe {
|
||||||
self.set_as_af($af, PushPull);
|
self.set_as_af($af, OutputPushPull);
|
||||||
self.block()
|
self.block()
|
||||||
.ospeedr()
|
.ospeedr()
|
||||||
.modify(|w| w.set_ospeedr(self.pin() as usize, Ospeedr::VERYHIGHSPEED));
|
.modify(|w| w.set_ospeedr(self.pin() as usize, Ospeedr::VERYHIGHSPEED));
|
||||||
|
@ -350,12 +350,13 @@ impl<'d, T: Pin> InputPin for OutputOpenDrain<'d, T> {
|
|||||||
pub(crate) mod sealed {
|
pub(crate) mod sealed {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
/// Output type settings
|
/// Alternate function type settings
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
pub enum OutputType {
|
pub enum AFType {
|
||||||
PushPull,
|
Input,
|
||||||
OpenDrain,
|
OutputPushPull,
|
||||||
|
OutputOpenDrain,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Pin {
|
pub trait Pin {
|
||||||
@ -394,21 +395,47 @@ pub(crate) mod sealed {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(gpio_v1)]
|
#[cfg(gpio_v1)]
|
||||||
unsafe fn set_as_af(&self, _af_num: u8, _af_type: OutputType) {
|
unsafe fn set_as_af(&self, _af_num: u8, af_type: AFType) {
|
||||||
panic!("F1 alternate GPIO functions not supported yet!");
|
// F1 uses the AFIO register for remapping.
|
||||||
|
// For now, this is not implemented, so af_num is ignored
|
||||||
|
// _af_num should be zero here, since it is not set by stm32-data
|
||||||
|
let r = self.block();
|
||||||
|
let n = self._pin() as usize;
|
||||||
|
let crlh = if n < 8 { 0 } else { 1 };
|
||||||
|
match af_type {
|
||||||
|
AFType::Input => {
|
||||||
|
r.cr(crlh).modify(|w| {
|
||||||
|
w.set_mode(n % 8, vals::Mode::INPUT);
|
||||||
|
w.set_cnf(n % 8, vals::Cnf::PUSHPULL);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
AFType::OutputPushPull => {
|
||||||
|
r.cr(crlh).modify(|w| {
|
||||||
|
w.set_mode(n % 8, vals::Mode::OUTPUT50);
|
||||||
|
w.set_cnf(n % 8, vals::Cnf::ALTPUSHPULL);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
AFType::OutputOpenDrain => {
|
||||||
|
r.cr(crlh).modify(|w| {
|
||||||
|
w.set_mode(n % 8, vals::Mode::OUTPUT50);
|
||||||
|
w.set_cnf(n % 8, vals::Cnf::ALTOPENDRAIN);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#[cfg(gpio_v2)]
|
#[cfg(gpio_v2)]
|
||||||
unsafe fn set_as_af(&self, af_num: u8, af_type: OutputType) {
|
unsafe fn set_as_af(&self, af_num: u8, af_type: AFType) {
|
||||||
let pin = self._pin() as usize;
|
let pin = self._pin() as usize;
|
||||||
let block = self.block();
|
let block = self.block();
|
||||||
block
|
block
|
||||||
.afr(pin / 8)
|
.afr(pin / 8)
|
||||||
.modify(|w| w.set_afr(pin % 8, vals::Afr(af_num)));
|
.modify(|w| w.set_afr(pin % 8, vals::Afr(af_num)));
|
||||||
match af_type {
|
match af_type {
|
||||||
OutputType::PushPull => {
|
AFType::Input => {}
|
||||||
|
AFType::OutputPushPull => {
|
||||||
block.otyper().modify(|w| w.set_ot(pin, vals::Ot::PUSHPULL))
|
block.otyper().modify(|w| w.set_ot(pin, vals::Ot::PUSHPULL))
|
||||||
}
|
}
|
||||||
OutputType::OpenDrain => block
|
AFType::OutputOpenDrain => block
|
||||||
.otyper()
|
.otyper()
|
||||||
.modify(|w| w.set_ot(pin, vals::Ot::OPENDRAIN)),
|
.modify(|w| w.set_ot(pin, vals::Ot::OPENDRAIN)),
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,6 @@ crate::pac::interrupts!(
|
|||||||
};
|
};
|
||||||
);
|
);
|
||||||
|
|
||||||
#[cfg(not(rcc_f1))]
|
|
||||||
macro_rules! impl_pin {
|
macro_rules! impl_pin {
|
||||||
($inst:ident, $pin:ident, $signal:ident, $af:expr) => {
|
($inst:ident, $pin:ident, $signal:ident, $af:expr) => {
|
||||||
impl $signal<peripherals::$inst> for peripherals::$pin {}
|
impl $signal<peripherals::$inst> for peripherals::$pin {}
|
||||||
@ -109,6 +108,7 @@ macro_rules! impl_pin {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(rcc_f1))]
|
||||||
crate::pac::peripheral_pins!(
|
crate::pac::peripheral_pins!(
|
||||||
($inst:ident, i2c, I2C, $pin:ident, SDA, $af:expr) => {
|
($inst:ident, i2c, I2C, $pin:ident, SDA, $af:expr) => {
|
||||||
impl_pin!($inst, $pin, SdaPin, $af);
|
impl_pin!($inst, $pin, SdaPin, $af);
|
||||||
@ -119,6 +119,17 @@ crate::pac::peripheral_pins!(
|
|||||||
};
|
};
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#[cfg(rcc_f1)]
|
||||||
|
crate::pac::peripheral_pins!(
|
||||||
|
($inst:ident, i2c, I2C, $pin:ident, SDA) => {
|
||||||
|
impl_pin!($inst, $pin, SdaPin, 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
($inst:ident, i2c, I2C, $pin:ident, SCL) => {
|
||||||
|
impl_pin!($inst, $pin, SclPin, 0);
|
||||||
|
};
|
||||||
|
);
|
||||||
|
|
||||||
macro_rules! impl_dma {
|
macro_rules! impl_dma {
|
||||||
($inst:ident, {dmamux: $dmamux:ident}, $signal:ident, $request:expr) => {
|
($inst:ident, {dmamux: $dmamux:ident}, $signal:ident, $request:expr) => {
|
||||||
impl<T> sealed::$signal<peripherals::$inst> for T
|
impl<T> sealed::$signal<peripherals::$inst> for T
|
||||||
|
@ -9,7 +9,7 @@ use embedded_hal::blocking::i2c::WriteRead;
|
|||||||
|
|
||||||
use crate::pac::i2c;
|
use crate::pac::i2c;
|
||||||
|
|
||||||
use crate::gpio::sealed::OutputType::OpenDrain;
|
use crate::gpio::sealed::AFType::OutputOpenDrain;
|
||||||
|
|
||||||
pub struct I2c<'d, T: Instance> {
|
pub struct I2c<'d, T: Instance> {
|
||||||
phantom: PhantomData<&'d mut T>,
|
phantom: PhantomData<&'d mut T>,
|
||||||
@ -30,8 +30,8 @@ impl<'d, T: Instance> I2c<'d, T> {
|
|||||||
T::enable();
|
T::enable();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
scl.set_as_af(scl.af_num(), OpenDrain);
|
scl.set_as_af(scl.af_num(), OutputOpenDrain);
|
||||||
sda.set_as_af(sda.af_num(), OpenDrain);
|
sda.set_as_af(sda.af_num(), OutputOpenDrain);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
#![macro_use]
|
#![macro_use]
|
||||||
|
|
||||||
#[cfg_attr(spi_v1, path = "v1.rs")]
|
#[cfg_attr(spi_v1, path = "v1.rs")]
|
||||||
|
#[cfg_attr(spi_f1, path = "v1.rs")]
|
||||||
#[cfg_attr(spi_v2, path = "v2.rs")]
|
#[cfg_attr(spi_v2, path = "v2.rs")]
|
||||||
#[cfg_attr(spi_v3, path = "v3.rs")]
|
#[cfg_attr(spi_v3, path = "v3.rs")]
|
||||||
mod _version;
|
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))]
|
||||||
@ -52,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,6 +105,7 @@ macro_rules! impl_pin {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(rcc_f1))]
|
||||||
crate::pac::peripheral_pins!(
|
crate::pac::peripheral_pins!(
|
||||||
($inst:ident, spi, SPI, $pin:ident, SCK, $af:expr) => {
|
($inst:ident, spi, SPI, $pin:ident, SCK, $af:expr) => {
|
||||||
impl_pin!($inst, $pin, SckPin, $af);
|
impl_pin!($inst, $pin, SckPin, $af);
|
||||||
@ -118,6 +120,21 @@ crate::pac::peripheral_pins!(
|
|||||||
};
|
};
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#[cfg(rcc_f1)]
|
||||||
|
crate::pac::peripheral_pins!(
|
||||||
|
($inst:ident, spi, SPI, $pin:ident, SCK) => {
|
||||||
|
impl_pin!($inst, $pin, SckPin, 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
($inst:ident, spi, SPI, $pin:ident, MOSI) => {
|
||||||
|
impl_pin!($inst, $pin, MosiPin, 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
($inst:ident, spi, SPI, $pin:ident, MISO) => {
|
||||||
|
impl_pin!($inst, $pin, MisoPin, 0);
|
||||||
|
};
|
||||||
|
);
|
||||||
|
|
||||||
macro_rules! impl_dma {
|
macro_rules! impl_dma {
|
||||||
($inst:ident, {dmamux: $dmamux:ident}, $signal:ident, $request:expr) => {
|
($inst:ident, {dmamux: $dmamux:ident}, $signal:ident, $request:expr) => {
|
||||||
impl<T> sealed::$signal<peripherals::$inst> for T
|
impl<T> sealed::$signal<peripherals::$inst> for T
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
#![macro_use]
|
#![macro_use]
|
||||||
|
|
||||||
use crate::dma::NoDma;
|
use crate::dma::NoDma;
|
||||||
use crate::gpio::{
|
use crate::gpio::sealed::AFType;
|
||||||
sealed::{
|
use crate::gpio::sealed::Pin;
|
||||||
OutputType::{OpenDrain, PushPull},
|
use crate::gpio::{AnyPin, NoPin};
|
||||||
Pin,
|
|
||||||
},
|
|
||||||
AnyPin,
|
|
||||||
};
|
|
||||||
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 +17,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 +30,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 +75,20 @@ 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(), PushPull);
|
let mosi_af = mosi.af_num();
|
||||||
mosi.set_as_af(mosi.af_num(), PushPull);
|
let miso_af = miso.af_num();
|
||||||
miso.set_as_af(miso.af_num(), OpenDrain);
|
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| x.set_as_af(sck_af, AFType::OutputPushPull));
|
||||||
|
mosi.as_ref()
|
||||||
|
.map(|x| x.set_as_af(mosi_af, AFType::OutputPushPull));
|
||||||
|
miso.as_ref().map(|x| x.set_as_af(miso_af, AFType::Input));
|
||||||
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
T::regs().cr2().modify(|w| {
|
T::regs().cr2().modify(|w| {
|
||||||
@ -103,6 +125,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 +319,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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -414,13 +439,18 @@ fn write_word<W: Word>(regs: &'static crate::pac::spi::Spi, word: W) -> Result<(
|
|||||||
let sr = unsafe { regs.sr().read() };
|
let sr = unsafe { regs.sr().read() };
|
||||||
if sr.ovr() {
|
if sr.ovr() {
|
||||||
return Err(Error::Overrun);
|
return Err(Error::Overrun);
|
||||||
} else if sr.fre() {
|
}
|
||||||
|
#[cfg(not(spi_f1))]
|
||||||
|
if sr.fre() {
|
||||||
return Err(Error::Framing);
|
return Err(Error::Framing);
|
||||||
} else if sr.modf() {
|
}
|
||||||
|
if sr.modf() {
|
||||||
return Err(Error::ModeFault);
|
return Err(Error::ModeFault);
|
||||||
} else if sr.crcerr() {
|
}
|
||||||
|
if sr.crcerr() {
|
||||||
return Err(Error::Crc);
|
return Err(Error::Crc);
|
||||||
} else if sr.txe() {
|
}
|
||||||
|
if sr.txe() {
|
||||||
unsafe {
|
unsafe {
|
||||||
let dr = regs.dr().ptr() as *mut W;
|
let dr = regs.dr().ptr() as *mut W;
|
||||||
ptr::write_volatile(dr, word);
|
ptr::write_volatile(dr, word);
|
||||||
@ -436,13 +466,18 @@ fn read_word<W: Word>(regs: &'static crate::pac::spi::Spi) -> Result<W, Error> {
|
|||||||
let sr = unsafe { regs.sr().read() };
|
let sr = unsafe { regs.sr().read() };
|
||||||
if sr.ovr() {
|
if sr.ovr() {
|
||||||
return Err(Error::Overrun);
|
return Err(Error::Overrun);
|
||||||
} else if sr.modf() {
|
}
|
||||||
return Err(Error::ModeFault);
|
#[cfg(not(spi_f1))]
|
||||||
} else if sr.fre() {
|
if sr.fre() {
|
||||||
return Err(Error::Framing);
|
return Err(Error::Framing);
|
||||||
} else if sr.crcerr() {
|
}
|
||||||
|
if sr.modf() {
|
||||||
|
return Err(Error::ModeFault);
|
||||||
|
}
|
||||||
|
if sr.crcerr() {
|
||||||
return Err(Error::Crc);
|
return Err(Error::Crc);
|
||||||
} else if sr.rxne() {
|
}
|
||||||
|
if sr.rxne() {
|
||||||
unsafe {
|
unsafe {
|
||||||
let dr = regs.dr().ptr() as *const W;
|
let dr = regs.dr().ptr() as *const W;
|
||||||
return Ok(ptr::read_volatile(dr));
|
return Ok(ptr::read_volatile(dr));
|
||||||
|
@ -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 _));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,6 @@ crate::pac::interrupts!(
|
|||||||
};
|
};
|
||||||
);
|
);
|
||||||
|
|
||||||
#[cfg(not(rcc_f1))]
|
|
||||||
macro_rules! impl_pin {
|
macro_rules! impl_pin {
|
||||||
($inst:ident, $pin:ident, $signal:ident, $af:expr) => {
|
($inst:ident, $pin:ident, $signal:ident, $af:expr) => {
|
||||||
impl sealed::$signal<peripherals::$inst> for peripherals::$pin {
|
impl sealed::$signal<peripherals::$inst> for peripherals::$pin {
|
||||||
@ -140,6 +139,7 @@ macro_rules! impl_pin {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(rcc_f1))]
|
||||||
crate::pac::peripheral_pins!(
|
crate::pac::peripheral_pins!(
|
||||||
|
|
||||||
// USART
|
// USART
|
||||||
@ -177,6 +177,44 @@ crate::pac::peripheral_pins!(
|
|||||||
};
|
};
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#[cfg(rcc_f1)]
|
||||||
|
crate::pac::peripheral_pins!(
|
||||||
|
|
||||||
|
// USART
|
||||||
|
($inst:ident, usart, USART, $pin:ident, TX) => {
|
||||||
|
impl_pin!($inst, $pin, TxPin, 0);
|
||||||
|
};
|
||||||
|
($inst:ident, usart, USART, $pin:ident, RX) => {
|
||||||
|
impl_pin!($inst, $pin, RxPin, 0);
|
||||||
|
};
|
||||||
|
($inst:ident, usart, USART, $pin:ident, CTS) => {
|
||||||
|
impl_pin!($inst, $pin, CtsPin, 0);
|
||||||
|
};
|
||||||
|
($inst:ident, usart, USART, $pin:ident, RTS) => {
|
||||||
|
impl_pin!($inst, $pin, RtsPin, 0);
|
||||||
|
};
|
||||||
|
($inst:ident, usart, USART, $pin:ident, CK) => {
|
||||||
|
impl_pin!($inst, $pin, CkPin, 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
// UART
|
||||||
|
($inst:ident, uart, UART, $pin:ident, TX) => {
|
||||||
|
impl_pin!($inst, $pin, TxPin, 0);
|
||||||
|
};
|
||||||
|
($inst:ident, uart, UART, $pin:ident, RX) => {
|
||||||
|
impl_pin!($inst, $pin, RxPin, 0);
|
||||||
|
};
|
||||||
|
($inst:ident, uart, UART, $pin:ident, CTS) => {
|
||||||
|
impl_pin!($inst, $pin, CtsPin, 0);
|
||||||
|
};
|
||||||
|
($inst:ident, uart, UART, $pin:ident, RTS) => {
|
||||||
|
impl_pin!($inst, $pin, RtsPin, 0);
|
||||||
|
};
|
||||||
|
($inst:ident, uart, UART, $pin:ident, CK) => {
|
||||||
|
impl_pin!($inst, $pin, CkPin, 0);
|
||||||
|
};
|
||||||
|
);
|
||||||
|
|
||||||
macro_rules! impl_dma {
|
macro_rules! impl_dma {
|
||||||
($inst:ident, {dmamux: $dmamux:ident}, $signal:ident, $request:expr) => {
|
($inst:ident, {dmamux: $dmamux:ident}, $signal:ident, $request:expr) => {
|
||||||
impl<T> sealed::$signal<peripherals::$inst> for T
|
impl<T> sealed::$signal<peripherals::$inst> for T
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::gpio::sealed::OutputType::{OpenDrain, PushPull};
|
use crate::gpio::sealed::AFType::{OutputOpenDrain, OutputPushPull};
|
||||||
use core::future::Future;
|
use core::future::Future;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use embassy::util::Unborrow;
|
use embassy::util::Unborrow;
|
||||||
@ -37,8 +37,8 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
|
|||||||
let r = inner.regs();
|
let r = inner.regs();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
rx.set_as_af(rx.af_num(), OpenDrain);
|
rx.set_as_af(rx.af_num(), OutputOpenDrain);
|
||||||
tx.set_as_af(tx.af_num(), PushPull);
|
tx.set_as_af(tx.af_num(), OutputPushPull);
|
||||||
|
|
||||||
r.brr().write_value(regs::Brr(div));
|
r.brr().write_value(regs::Brr(div));
|
||||||
r.cr1().write(|w| {
|
r.cr1().write(|w| {
|
||||||
|
@ -13,7 +13,7 @@ use futures::TryFutureExt;
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::dma::NoDma;
|
use crate::dma::NoDma;
|
||||||
use crate::gpio::sealed::OutputType::{OpenDrain, PushPull};
|
use crate::gpio::sealed::AFType::{OutputOpenDrain, OutputPushPull};
|
||||||
use crate::pac::usart::{regs, vals};
|
use crate::pac::usart::{regs, vals};
|
||||||
|
|
||||||
pub struct Uart<'d, T: Instance, TxDma = NoDma, RxDma = NoDma> {
|
pub struct Uart<'d, T: Instance, TxDma = NoDma, RxDma = NoDma> {
|
||||||
@ -43,8 +43,8 @@ impl<'d, T: Instance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
|
|||||||
let r = inner.regs();
|
let r = inner.regs();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
rx.set_as_af(rx.af_num(), OpenDrain);
|
rx.set_as_af(rx.af_num(), OutputOpenDrain);
|
||||||
tx.set_as_af(tx.af_num(), PushPull);
|
tx.set_as_af(tx.af_num(), OutputPushPull);
|
||||||
|
|
||||||
r.cr2().write(|_w| {});
|
r.cr2().write(|_w| {});
|
||||||
r.cr3().write(|_w| {});
|
r.cr3().write(|_w| {});
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit e78ea6f05058dc1eff1dd4a4f07227d502a3b657
|
Subproject commit bae2d34445f87e7b9a88b683c789c5d0c7560fb6
|
Loading…
Reference in New Issue
Block a user