stm32f3xx_hal/
syscfg.rs

1//! # System configuration controller
2
3use core::fmt;
4use core::ops::Deref;
5
6use crate::gpio::{marker, Pin};
7use crate::{
8    pac::SYSCFG,
9    rcc::{Enable, APB2},
10};
11
12/// Extension trait that constrains the `SYSCFG` peripheral
13pub trait SysCfgExt {
14    /// Constrains the `SYSCFG` peripheral so it plays nicely with the other abstractions
15    fn constrain(self, apb2: &mut APB2) -> SysCfg;
16}
17
18impl SysCfgExt for SYSCFG {
19    fn constrain(self, apb2: &mut APB2) -> SysCfg {
20        SYSCFG::enable(apb2);
21
22        SysCfg(self)
23    }
24}
25
26/// Constrained SYSCFG peripheral
27///
28/// An instance of this struct is acquired by calling the
29/// [`constrain`](SysCfgExt::constrain) function on the
30/// [`SYSCFG`](crate::pac::SYSCFG) struct.
31///
32/// ```
33/// let dp = pac::Peripherals::take().unwrap();
34/// let mut rcc = dp.RCC.constrain();
35/// let syscfg = dp.SYSCFG.constrain(&mut rcc.apb2);
36/// ```
37pub struct SysCfg(SYSCFG);
38
39#[cfg(feature = "defmt")]
40impl defmt::Format for SysCfg {
41    fn format(&self, f: defmt::Formatter) {
42        defmt::write!(f, "SysCfg(SYSCFG)");
43    }
44}
45
46impl fmt::Debug for SysCfg {
47    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48        f.debug_struct("SysCfg").finish()
49    }
50}
51
52impl Deref for SysCfg {
53    type Target = SYSCFG;
54
55    fn deref(&self) -> &Self::Target {
56        &self.0
57    }
58}
59
60impl SysCfg {
61    /// Make corresponding EXTI (external interrupt) line sensitive to the selected pin.
62    ///
63    /// # Note
64    ///
65    /// Only **one** Pin index of all banks can be activated
66    /// for interrupts at the same time.
67    ///
68    /// This means, that only on of `PA1`, `PB1`, `PC1`, ... can be activated.
69    ///
70    /// For example, if first [`crate::gpio::gpioa::PA1`] and than [`crate::gpio::gpiob::PB1`]
71    /// would be configured, the former configuration would be overwritten.
72    ///
73    /// But configuring `PA1` and and `PB2` works!
74    #[doc(alias = "enable_interrupt")]
75    pub fn select_exti_interrupt_source<Gpio, Index, Mode>(&mut self, pin: &Pin<Gpio, Index, Mode>)
76    where
77        Gpio: marker::Gpio,
78        Index: marker::Index,
79    {
80        const BITWIDTH: u8 = 4;
81        let index = pin.index.index() % 4;
82        let extigpionr = u32::from(pin.gpio.port_index());
83        // SAFETY: These are all unguarded writes directly to the register,
84        // without leveraging the safety of stm32f3 generated values.
85        unsafe {
86            match pin.index.index() {
87                0..=3 => crate::modify_at!(self.exticr1, BITWIDTH, index, extigpionr),
88                4..=7 => crate::modify_at!(self.exticr2, BITWIDTH, index, extigpionr),
89                8..=11 => crate::modify_at!(self.exticr3, BITWIDTH, index, extigpionr),
90                12..=15 => crate::modify_at!(self.exticr4, BITWIDTH, index, extigpionr),
91                _ => crate::unreachable!(),
92            };
93        }
94    }
95}