Skip to content

Commit

Permalink
Merge pull request #511 from stm32-rs/remap
Browse files Browse the repository at this point in the history
Remap trait
  • Loading branch information
burrbull authored Oct 9, 2024
2 parents c207345 + d327eec commit 51321ac
Show file tree
Hide file tree
Showing 6 changed files with 209 additions and 127 deletions.
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

0 comments on commit 51321ac

Please sign in to comment.