partial alternate function configuration on STM32f1
This commit is contained in:
		@@ -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,15 @@ 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,
 | 
					        // InputFloating,
 | 
				
			||||||
        OpenDrain,
 | 
					        // InputPullUp,
 | 
				
			||||||
 | 
					        // InputPullDown,
 | 
				
			||||||
 | 
					        OutputPushPull,
 | 
				
			||||||
 | 
					        OutputOpenDrain,
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub trait Pin {
 | 
					    pub trait Pin {
 | 
				
			||||||
@@ -394,21 +397,35 @@ 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 = pin.block();
 | 
				
			||||||
 | 
					            let n = pin.pin() as usize;
 | 
				
			||||||
 | 
					            let crlh = if n < 8 { 0 } else { 1 };
 | 
				
			||||||
 | 
					            match af_type {
 | 
				
			||||||
 | 
					                // TODO: Do we need to configure input AF pins differently?
 | 
				
			||||||
 | 
					                AfType::OutputPushPull => {
 | 
				
			||||||
 | 
					                    r.cr(crlh).modify(|w| w.set_cnf(n % 8, vals::Cnf::PUSHPULL));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                AfType::OutputOpenDrain => r
 | 
				
			||||||
 | 
					                    .cr(crlh)
 | 
				
			||||||
 | 
					                    .modify(|w| w.set_cnf(n % 8, vals::Cnf::OPENDRAIN)),
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        #[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::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 {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -105,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);
 | 
				
			||||||
@@ -119,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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
use crate::dma::NoDma;
 | 
					use crate::dma::NoDma;
 | 
				
			||||||
use crate::gpio::{
 | 
					use crate::gpio::{
 | 
				
			||||||
    sealed::{
 | 
					    sealed::{
 | 
				
			||||||
        OutputType::{OpenDrain, PushPull},
 | 
					        AFType::{OutputOpenDrain, OutputPushPull},
 | 
				
			||||||
        Pin,
 | 
					        Pin,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    AnyPin,
 | 
					    AnyPin,
 | 
				
			||||||
@@ -59,9 +59,9 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
 | 
				
			|||||||
        unborrow!(sck, mosi, miso, txdma, rxdma);
 | 
					        unborrow!(sck, mosi, miso, txdma, rxdma);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            sck.set_as_af(sck.af_num(), PushPull);
 | 
					            sck.set_as_af(sck.af_num(), OutputPushPull);
 | 
				
			||||||
            mosi.set_as_af(mosi.af_num(), PushPull);
 | 
					            mosi.set_as_af(mosi.af_num(), OutputPushPull);
 | 
				
			||||||
            miso.set_as_af(miso.af_num(), OpenDrain);
 | 
					            miso.set_as_af(miso.af_num(), OutputOpenDrain);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let sck = sck.degrade();
 | 
					        let sck = sck.degrade();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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| {});
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user