partial alternate function configuration on STM32f1

This commit is contained in:
Tobias Pisani 2021-10-09 11:35:05 +02:00
parent f9a576d13d
commit 39880de958
9 changed files with 72 additions and 28 deletions

View file

@ -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();

View file

@ -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));

View file

@ -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)),
} }

View file

@ -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

View file

@ -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 {

View file

@ -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

View file

@ -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();

View file

@ -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| {

View file

@ -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| {});