Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Check "device selected" in `build.rs` [#502]
- Use gpio field enums internally [#506]
- Unmacro `dma.rs` [#505]
- Rework USART remap,
- Rework pin remaps, fix CAN1 remap [#511]

### Added

Expand Down Expand Up @@ -57,6 +57,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
[#505]: https://github.com/stm32-rs/stm32f1xx-hal/pull/505
[#506]: https://github.com/stm32-rs/stm32f1xx-hal/pull/506
[#509]: https://github.com/stm32-rs/stm32f1xx-hal/pull/509
[#511]: https://github.com/stm32-rs/stm32f1xx-hal/pull/511

## [v0.10.0] - 2022-12-12

Expand Down
87 changes: 86 additions & 1 deletion src/afio.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
//! # Alternate Function I/Os
use crate::pac::{afio, AFIO, RCC};
use crate::pac::{self, afio, AFIO, RCC};

use crate::rcc::{Enable, Reset};

use crate::gpio::{
Debugger, Floating, Input, PA15, {PB3, PB4},
};
use crate::sealed::Sealed;

pub trait AfioExt {
fn constrain(self) -> Parts;
Expand Down Expand Up @@ -150,4 +151,88 @@ impl MAPR2 {
pub fn mapr2(&mut self) -> &afio::MAPR2 {
unsafe { (*AFIO::ptr()).mapr2() }
}

pub fn modify_mapr<F>(&mut self, mod_fn: F)
where
F: for<'w> FnOnce(&afio::mapr2::R, &'w mut afio::mapr2::W) -> &'w mut afio::mapr2::W,
{
self.mapr2().modify(|r, w| mod_fn(r, w));
}
}

pub trait Remap: Sealed {
type Mapr;
fn remap(mapr: &mut Self::Mapr, to: u8);
}

macro_rules! remap {
($(
$PER:ty: $MAPR:ident, $w:ident: $field:ident;
)+) => {
$(
remap!($PER: $MAPR, $w: $field);
)+
};
($PER:ty: $MAPR:ident, bool: $field:ident) => {
impl Remap for $PER {
type Mapr = $MAPR;
fn remap(mapr: &mut Self::Mapr, to: u8) {
mapr.modify_mapr(|_, w| w.$field().bit(to != 0));
}
}
};
($PER:ty: $MAPR:ident, u8: $field:ident) => {
impl Remap for $PER {
type Mapr = $MAPR;
fn remap(mapr: &mut Self::Mapr, to: u8) {
mapr.modify_mapr(|_, w| unsafe { w.$field().bits(to) });
}
}
};
}
use remap;

remap! {
pac::SPI1: MAPR, bool: spi1_remap;
pac::I2C1: MAPR, bool: i2c1_remap;
pac::USART1: MAPR, bool: usart1_remap;
pac::USART2: MAPR, bool: usart2_remap;
pac::USART3: MAPR, u8: usart3_remap;
pac::TIM2: MAPR, u8: tim2_remap;
pac::TIM3: MAPR, u8: tim3_remap;
}

#[cfg(feature = "medium")]
remap! {
pac::TIM4: MAPR, bool: tim4_remap;
}

#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity"))]
remap! {
pac::TIM1: MAPR, u8: tim1_remap;
}

#[cfg(feature = "stm32f103")]
remap! {
pac::CAN1: MAPR, u8: can_remap;
}

#[cfg(feature = "connectivity")]
remap! {
pac::CAN1: MAPR, u8: can1_remap;
//pac::ETHERNET_MAC: MAPR, bool: eth_remap;
pac::CAN2: MAPR, bool: can2_remap;
pac::SPI3: MAPR, bool: spi3_remap;
}

#[cfg(feature = "xl")]
remap! {
pac::TIM9: MAPR2, bool: tim9_remap;
pac::TIM10: MAPR2, bool: tim10_remap;
pac::TIM11: MAPR2, bool: tim11_remap;
}
#[cfg(any(feature = "xl", all(feature = "stm32f100", feature = "high")))]
remap! {
pac::TIM13: MAPR2, bool: tim13_remap;
pac::TIM14: MAPR2, bool: tim14_remap;
}
52 changes: 22 additions & 30 deletions src/can.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
//! | TX | PB6 | PB13 |
//! | RX | PB5 | PB12 |

use crate::afio::MAPR;
use crate::afio::Remap;
use crate::gpio::{self, Alternate, Cr, Floating, Input, NoPin, PinMode, PullUp, PushPull};
use crate::pac::{self, RCC};

Expand All @@ -45,14 +45,10 @@ pub mod can1 {
use super::*;

remap! {
#[cfg(not(feature = "connectivity"))]
PA12, PA11 => { |_, w| unsafe { w.can_remap().bits(0) } };
#[cfg(feature = "connectivity")]
PA12, PA11 => { |_, w| unsafe { w.can1_remap().bits(0) } };
#[cfg(not(feature = "connectivity"))]
PB9, PB8 => { |_, w| unsafe { w.can_remap().bits(10) } };
#[cfg(feature = "connectivity")]
PB9, PB8 => { |_, w| unsafe { w.can1_remap().bits(10) } };
pac::CAN1: [
PA12, PA11 => 0;
PB9, PB8 => 2;
]
}
}

Expand All @@ -61,70 +57,66 @@ pub mod can2 {
use super::*;

remap! {
PB6, PB5 => { |_, w| w.can2_remap().bit(false) };
PB13, PB12 => { |_, w| w.can2_remap().bit(true) };
pac::CAN2: [
PB6, PB5 => 0;
PB13, PB12 => 1;
]
}
}

macro_rules! remap {
($($(#[$attr:meta])* $TX:ident, $RX:ident => { $remapex:expr };)+) => {
($PER:ty: [$($TX:ident, $RX:ident => $remap:literal;)+]) => {
pub enum Tx {
$(
$(#[$attr])*
$TX(gpio::$TX<Alternate>),
)+
None(NoPin<PushPull>),
}
pub enum Rx<PULL> {
$(
$(#[$attr])*
$RX(gpio::$RX<Input<PULL>>),
)+
None(NoPin<PULL>),
}

$(
$(#[$attr])*
impl<PULL: InMode> From<(gpio::$TX<Alternate>, gpio::$RX<Input<PULL>>, &mut MAPR)> for Pins<Tx, Rx<PULL>> {
fn from(p: (gpio::$TX<Alternate>, gpio::$RX<Input<PULL>>, &mut MAPR)) -> Self {
p.2.modify_mapr($remapex);
impl<PULL: InMode> From<(gpio::$TX<Alternate>, gpio::$RX<Input<PULL>>, &mut <$PER as Remap>::Mapr)> for Pins<Tx, Rx<PULL>> {
fn from(p: (gpio::$TX<Alternate>, gpio::$RX<Input<PULL>>, &mut <$PER as Remap>::Mapr)) -> Self {
<$PER>::remap(p.2, $remap);
Self { tx: Tx::$TX(p.0), rx: Rx::$RX(p.1) }
}
}

$(#[$attr])*
impl<PULL> From<(gpio::$TX, gpio::$RX, &mut MAPR)> for Pins<Tx, Rx<PULL>>
impl<PULL> From<(gpio::$TX, gpio::$RX, &mut <$PER as Remap>::Mapr)> for Pins<Tx, Rx<PULL>>
where
Input<PULL>: PinMode,
PULL: InMode,
{
fn from(p: (gpio::$TX, gpio::$RX, &mut MAPR)) -> Self {
fn from(p: (gpio::$TX, gpio::$RX, &mut <$PER as Remap>::Mapr)) -> Self {
let mut cr = Cr;
let tx = p.0.into_mode(&mut cr);
let rx = p.1.into_mode(&mut cr);
p.2.modify_mapr($remapex);
<$PER>::remap(p.2, $remap);
Self { tx: Tx::$TX(tx), rx: Rx::$RX(rx) }
}
}

$(#[$attr])*
impl From<(gpio::$TX, &mut MAPR)> for Pins<Tx, Rx<Floating>> {
fn from(p: (gpio::$TX, &mut MAPR)) -> Self {
impl From<(gpio::$TX, &mut <$PER as Remap>::Mapr)> for Pins<Tx, Rx<Floating>> {
fn from(p: (gpio::$TX, &mut <$PER as Remap>::Mapr)) -> Self {
let tx = p.0.into_mode(&mut Cr);
p.1.modify_mapr($remapex);
<$PER>::remap(p.1, $remap);
Self { tx: Tx::$TX(tx), rx: Rx::None(NoPin::new()) }
}
}

$(#[$attr])*
impl<PULL> From<(gpio::$RX, &mut MAPR)> for Pins<Tx, Rx<PULL>>
impl<PULL> From<(gpio::$RX, &mut <$PER as Remap>::Mapr)> for Pins<Tx, Rx<PULL>>
where
Input<PULL>: PinMode,
PULL: InMode,
{
fn from(p: (gpio::$RX, &mut MAPR)) -> Self {
fn from(p: (gpio::$RX, &mut <$PER as Remap>::Mapr)) -> Self {
let rx = p.0.into_mode(&mut Cr);
p.1.modify_mapr($remapex);
<$PER>::remap(p.1, $remap);
Self { tx: Tx::None(NoPin::new()), rx: Rx::$RX(rx) }
}
}
Expand Down
25 changes: 12 additions & 13 deletions src/i2c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
// parts of this code is based on
// https://www.st.com/content/ccc/resource/technical/document/application_note/5d/ae/a3/6f/08/69/4e/9b/CD00209826.pdf/files/CD00209826.pdf/jcr:content/translations/en.CD00209826.pdf

use crate::afio::{Remap, MAPR};
use crate::gpio::{self, Alternate, Cr, OpenDrain};
use crate::pac::{DWT, I2C1, I2C2, RCC};
use crate::pac::{self, DWT, RCC};
use crate::rcc::{BusClock, Clocks, Enable, Reset};
use crate::time::{kHz, Hertz};
use core::ops::Deref;
Expand Down Expand Up @@ -100,30 +101,28 @@ impl<SCL, SDA> From<(SCL, SDA)> for Pins<SCL, SDA> {
}

pub mod i2c1 {
use crate::afio::MAPR;

use super::*;

remap! {
[
PB6, PB7 => MAPR { |_, w| w.i2c1_remap().bit(false) };
PB8, PB9 => MAPR { |_, w| w.i2c1_remap().bit(true) };
pac::I2C1: [
PB6, PB7 => MAPR: 0;
PB8, PB9 => MAPR: 1;
]
}
}
pub mod i2c2 {
use super::*;

remap! {
[
pac::I2C2: [
PB10, PB11;
]
}
}

macro_rules! remap {
([
$($SCL:ident, $SDA:ident $( => $MAPR:ident { $remapex:expr })?;)+
($PER:ty: [
$($SCL:ident, $SDA:ident $( => $MAPR:ident: $remap:literal)?;)+
]) => {
pub enum Scl {
$(
Expand All @@ -139,7 +138,7 @@ macro_rules! remap {
$(
impl From<(gpio::$SCL<Alternate<OpenDrain>>, gpio::$SDA<Alternate<OpenDrain>> $(, &mut $MAPR)?)> for Pins<Scl, Sda> {
fn from(p: (gpio::$SCL<Alternate<OpenDrain>>, gpio::$SDA<Alternate<OpenDrain>> $(, &mut $MAPR)?)) -> Self {
$(p.2.modify_mapr($remapex);)?
$(<$PER>::remap(p.2, $remap);)?
Self { scl: Scl::$SCL(p.0), sda: Sda::$SDA(p.1) }
}
}
Expand All @@ -149,7 +148,7 @@ macro_rules! remap {
let mut cr = Cr;
let scl = p.0.into_mode(&mut cr);
let sda = p.1.into_mode(&mut cr);
$(p.2.modify_mapr($remapex);)?
$(<$PER>::remap(p.2, $remap);)?
Self { scl: Scl::$SCL(scl), sda: Sda::$SDA(sda) }
}
}
Expand Down Expand Up @@ -213,11 +212,11 @@ pub trait Instance:
type Sda;
}

impl Instance for I2C1 {
impl Instance for pac::I2C1 {
type Scl = i2c1::Scl;
type Sda = i2c1::Sda;
}
impl Instance for I2C2 {
impl Instance for pac::I2C2 {
type Scl = i2c2::Scl;
type Sda = i2c2::Sda;
}
Expand Down
Loading
Loading