Skip to main content

ws63_hal/
peripherals.rs

1//! Peripheral singletons wrapping the WS63 PAC.
2//!
3//! Each peripheral is a zero-sized type that grants safe, exclusive access to
4//! the underlying hardware registers. The [`Peripherals`] struct is obtained
5//! once via [`Peripherals::take()`].
6
7pub use crate::soc::ws63::Interrupt;
8use core::marker::PhantomData;
9
10macro_rules! peripheral {
11    ($name:ident, $pac_ty:ty) => {
12        #[doc = concat!("Peripheral singleton for ", stringify!($name))]
13        #[derive(Debug)]
14        pub struct $name<'d> {
15            _marker: PhantomData<&'d ()>,
16        }
17
18        impl<'d> $name<'d> {
19            /// Unsafely create a peripheral instance.
20            ///
21            /// # Safety
22            /// Must not create multiple instances of the same peripheral.
23            #[inline]
24            pub unsafe fn steal() -> Self {
25                Self { _marker: PhantomData }
26            }
27
28            /// Pointer to the PAC register block.
29            #[inline]
30            pub fn ptr() -> *const <$pac_ty as core::ops::Deref>::Target {
31                <$pac_ty>::PTR
32            }
33
34            /// Return a reference to the PAC register block.
35            ///
36            /// # Safety
37            /// The PAC pointer must be valid. It points to a static physical
38            /// MMIO address provided by the svd2rust-generated PAC.
39            #[inline]
40            pub fn register_block(&self) -> &<$pac_ty as core::ops::Deref>::Target {
41                // SAFETY: PAC peripheral pointer is a static physical MMIO address, always valid
42                unsafe { &*Self::ptr() }
43            }
44        }
45
46        unsafe impl<'d> Send for $name<'d> {}
47    };
48}
49
50macro_rules! peripherals {
51    ($($field:ident => $ty:ident),* $(,)?) => {
52        #[allow(non_snake_case)]
53        pub struct Peripherals {
54            $(
55                #[doc = concat!("`", stringify!($field), "` peripheral")]
56                pub $field: $ty<'static>,
57            )*
58        }
59
60        impl Peripherals {
61            pub fn take() -> Option<Self> {
62                let pac = ws63_pac::Peripherals::take()?;
63                Some(Self::from_pac(pac))
64            }
65
66            /// Unchecked version of `take`. Does not check singleton.
67            ///
68            /// # Safety
69            ///
70            /// Each peripheral must be used at most once.
71            pub unsafe fn steal() -> Self {
72                let pac = unsafe { ws63_pac::Peripherals::steal() };
73                Self::from_pac(pac)
74            }
75
76            fn from_pac(_pac: ws63_pac::Peripherals) -> Self {
77                unsafe {
78                    Self {
79                        $(
80                            $field: $ty::steal(),
81                        )*
82                    }
83                }
84            }
85        }
86    };
87}
88
89peripheral!(SysCtl0, ws63_pac::SysCtl0);
90peripheral!(SysCtl1, ws63_pac::SysCtl1);
91peripheral!(GlbCtlM, ws63_pac::GlbCtlM);
92peripheral!(CldoCrg, ws63_pac::CldoCrg);
93peripheral!(IoConfig, ws63_pac::IoConfig);
94peripheral!(Gpio0, ws63_pac::Gpio0);
95peripheral!(Gpio1, ws63_pac::Gpio1);
96peripheral!(Gpio2, ws63_pac::Gpio2);
97peripheral!(UlpGpio, ws63_pac::UlpGpio);
98peripheral!(Uart0, ws63_pac::Uart0);
99peripheral!(Uart1, ws63_pac::Uart1);
100peripheral!(Uart2, ws63_pac::Uart2);
101peripheral!(I2c0, ws63_pac::I2c0);
102peripheral!(I2c1, ws63_pac::I2c1);
103peripheral!(Spi0, ws63_pac::Spi0);
104peripheral!(Spi1, ws63_pac::Spi1);
105peripheral!(Pwm, ws63_pac::Pwm);
106peripheral!(I2s, ws63_pac::I2s);
107peripheral!(Lsadc, ws63_pac::Lsadc);
108peripheral!(Dma, ws63_pac::Dma);
109peripheral!(Sdma, ws63_pac::Sdma);
110peripheral!(SfcCfg, ws63_pac::SfcCfg);
111peripheral!(Timer, ws63_pac::Timer);
112peripheral!(Wdt, ws63_pac::Wdt);
113peripheral!(Rtc, ws63_pac::Rtc);
114peripheral!(Tcxo, ws63_pac::Tcxo);
115peripheral!(Tsensor, ws63_pac::Tsensor);
116peripheral!(Efuse, ws63_pac::Efuse);
117peripheral!(Spacc, ws63_pac::Spacc);
118peripheral!(Pke, ws63_pac::Pke);
119peripheral!(Km, ws63_pac::Km);
120peripheral!(Trng, ws63_pac::Trng);
121peripheral!(RfWbCtl, ws63_pac::RfWbCtl);
122peripheral!(ShareMemCtl, ws63_pac::ShareMemCtl);
123peripheral!(FamaRemap, ws63_pac::FamaRemap);
124
125peripherals!(
126    SYS_CTL0 => SysCtl0,
127    SYS_CTL1 => SysCtl1,
128    GLB_CTL_M => GlbCtlM,
129    CLDO_CRG => CldoCrg,
130    IO_CONFIG => IoConfig,
131    GPIO0 => Gpio0,
132    GPIO1 => Gpio1,
133    GPIO2 => Gpio2,
134    ULP_GPIO => UlpGpio,
135    UART0 => Uart0,
136    UART1 => Uart1,
137    UART2 => Uart2,
138    I2C0 => I2c0,
139    I2C1 => I2c1,
140    SPI0 => Spi0,
141    SPI1 => Spi1,
142    PWM => Pwm,
143    I2S => I2s,
144    LSADC => Lsadc,
145    DMA => Dma,
146    SDMA => Sdma,
147    SFC_CFG => SfcCfg,
148    TIMER => Timer,
149    WDT => Wdt,
150    RTC => Rtc,
151    TCXO => Tcxo,
152    TSENSOR => Tsensor,
153    EFUSE => Efuse,
154    SPACC => Spacc,
155    PKE => Pke,
156    KM => Km,
157    TRNG => Trng,
158    RF_WB_CTL => RfWbCtl,
159    SHARE_MEM_CTL => ShareMemCtl,
160    FAMA_REMAP => FamaRemap,
161);