stm32f1_hal/afio/
mod.rs

1//! # Alternate Function I/Os
2
3pub mod i2c_remap;
4pub mod timer_remap;
5pub mod uart_remap;
6
7use crate::gpio::{self, Debugger};
8use crate::pac::{AFIO, afio};
9use crate::rcc::Rcc;
10use core::marker::PhantomData;
11
12pub trait AfioInit {
13    fn init(self, rcc: &mut Rcc) -> Afio;
14}
15
16impl AfioInit for AFIO {
17    fn init(self, rcc: &mut Rcc) -> Afio {
18        rcc.enable(&self);
19        rcc.reset(&self);
20
21        Afio {
22            _reg: self,
23            evcr: EVCR,
24            mapr: MAPR { jtag_enabled: true },
25            exticr1: EXTICR1,
26            exticr2: EXTICR2,
27            exticr3: EXTICR3,
28            exticr4: EXTICR4,
29            mapr2: MAPR2,
30        }
31    }
32}
33
34/// HAL wrapper around the AFIO registers
35///
36/// Aquired by calling [init](trait.AfioInit.html#init) on the [AFIO
37/// registers](../pac/struct.AFIO.html)
38///
39/// ```rust
40/// let p = pac::Peripherals::take().unwrap();
41/// let mut rcc = p.RCC.init();
42/// let mut afio = p.AFIO.init();
43pub struct Afio {
44    _reg: AFIO,
45    pub evcr: EVCR,
46    pub mapr: MAPR,
47    pub exticr1: EXTICR1,
48    pub exticr2: EXTICR2,
49    pub exticr3: EXTICR3,
50    pub exticr4: EXTICR4,
51    pub mapr2: MAPR2,
52}
53
54#[non_exhaustive]
55pub struct EVCR;
56
57impl EVCR {
58    pub fn evcr(&mut self) -> &afio::EVCR {
59        unsafe { (*AFIO::ptr()).evcr() }
60    }
61}
62
63// Remap Mode
64pub trait RemapMode<REG> {
65    fn remap(afio: &mut Afio);
66}
67pub struct RemapDefault<REG>(PhantomData<REG>);
68pub struct RemapPartial1<REG>(PhantomData<REG>);
69pub struct RemapPartial2<REG>(PhantomData<REG>);
70pub struct RemapFull<REG>(PhantomData<REG>);
71pub struct NonePin {}
72pub const NONE_PIN: NonePin = NonePin {};
73
74/// AF remap and debug I/O configuration register (MAPR)
75///
76/// Aquired through the [Afio](struct.Afio.html) struct.
77///
78/// ```rust
79/// let dp = pac::Peripherals::take().unwrap();
80/// let mut rcc = dp.RCC.init();
81/// let mut afio = dp.AFIO.init();
82/// function_using_mapr(&mut afio.mapr);
83/// ```
84#[non_exhaustive]
85pub struct MAPR {
86    jtag_enabled: bool,
87}
88
89impl MAPR {
90    fn mapr(&mut self) -> &afio::MAPR {
91        unsafe { (*AFIO::ptr()).mapr() }
92    }
93
94    pub fn modify_mapr<F>(&mut self, mod_fn: F)
95    where
96        F: for<'w> FnOnce(&afio::mapr::R, &'w mut afio::mapr::W) -> &'w mut afio::mapr::W,
97    {
98        let debug_bits = if self.jtag_enabled { 0b000 } else { 0b010 };
99        self.mapr()
100            .modify(unsafe { |r, w| mod_fn(r, w).swj_cfg().bits(debug_bits) });
101    }
102
103    /// Disables the JTAG to free up pa15, pb3 and pb4 for normal use
104    #[allow(clippy::redundant_field_names, clippy::type_complexity)]
105    pub fn disable_jtag(
106        &mut self,
107        pa15: gpio::PA15<Debugger>,
108        pb3: gpio::PB3<Debugger>,
109        pb4: gpio::PB4<Debugger>,
110    ) -> (gpio::PA15, gpio::PB3, gpio::PB4) {
111        self.jtag_enabled = false;
112        // Avoid duplicating swj_cfg write code
113        self.modify_mapr(|_, w| w);
114
115        // NOTE(unsafe) The pins are now in the good state.
116        unsafe { (pa15.activate(), pb3.activate(), pb4.activate()) }
117    }
118}
119
120#[non_exhaustive]
121pub struct EXTICR1;
122
123impl EXTICR1 {
124    pub fn exticr1(&mut self) -> &afio::EXTICR1 {
125        unsafe { (*AFIO::ptr()).exticr1() }
126    }
127}
128
129#[non_exhaustive]
130pub struct EXTICR2;
131
132impl EXTICR2 {
133    pub fn exticr2(&mut self) -> &afio::EXTICR2 {
134        unsafe { (*AFIO::ptr()).exticr2() }
135    }
136}
137
138#[non_exhaustive]
139pub struct EXTICR3;
140
141impl EXTICR3 {
142    pub fn exticr3(&mut self) -> &afio::EXTICR3 {
143        unsafe { (*AFIO::ptr()).exticr3() }
144    }
145}
146
147#[non_exhaustive]
148pub struct EXTICR4;
149
150impl EXTICR4 {
151    pub fn exticr4(&mut self) -> &afio::EXTICR4 {
152        unsafe { (*AFIO::ptr()).exticr4() }
153    }
154}
155
156#[non_exhaustive]
157pub struct MAPR2;
158
159impl MAPR2 {
160    pub fn mapr2(&mut self) -> &afio::MAPR2 {
161        unsafe { (*AFIO::ptr()).mapr2() }
162    }
163
164    pub fn modify_mapr<F>(&mut self, mod_fn: F)
165    where
166        F: for<'w> FnOnce(&afio::mapr2::R, &'w mut afio::mapr2::W) -> &'w mut afio::mapr2::W,
167    {
168        self.mapr2().modify(|r, w| mod_fn(r, w));
169    }
170}