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}