1#[doc(hidden)]
8#[macro_export]
10macro_rules! before_snippet {
11 () => {
12 r#"
13# #![no_std]
14# use esp_hal::{interrupt::{self, InterruptConfigurable}, time::{Duration, Instant, Rate}};
15# macro_rules! println {
16# ($($tt:tt)*) => { };
17# }
18# macro_rules! print {
19# ($($tt:tt)*) => { };
20# }
21# #[panic_handler]
22# fn panic(_ : &core::panic::PanicInfo) -> ! {
23# loop {}
24# }
25# fn main() {
26# let _ = example();
27# }
28# struct ExampleError {}
29# impl <T> From<T> for ExampleError where T: core::fmt::Debug {
30# fn from(_value: T) -> Self {
31# Self{}
32# }
33# }
34# async fn example() -> Result<(), ExampleError> {
35# let mut peripherals = esp_hal::init(esp_hal::Config::default());
36"#
37 };
38}
39
40#[doc(hidden)]
41#[macro_export]
42macro_rules! after_snippet {
43 () => {
44 r#"
45# Ok(())
46# }
47"#
48 };
49}
50
51#[doc(hidden)]
52#[macro_export]
53macro_rules! trm_markdown_link {
54 () => {
55 concat!("[Technical Reference Manual](", property!("trm"), ")")
56 };
57 ($anchor:literal) => {
58 concat!(
59 "[Technical Reference Manual](",
60 property!("trm"),
61 "#",
62 $anchor,
63 ")"
64 )
65 };
66}
67
68#[doc(hidden)]
69#[macro_export]
79macro_rules! any_peripheral {
80 ($(#[$meta:meta])* $vis:vis peripheral $name:ident<'d> {
81 $(
82 $(#[cfg($variant_meta:meta)])*
83 $variant:ident($inner:ty)
84 ),* $(,)?
85 }) => {
86 #[doc = concat!("Utilities related to [`", stringify!($name), "`]")]
87 #[doc(hidden)]
88 #[instability::unstable]
89 pub mod any {
90 #[allow(unused_imports)]
91 use super::*;
92
93 macro_rules! delegate {
94 ($any:ident, $inner_ident:ident => $code:tt) => {
95 match &$any.0 {
96 $(
97 $(#[cfg($variant_meta)])*
98 any::Inner::$variant($inner_ident) => $code,
99 )*
100 }
101 }
102 }
103
104 pub(crate) use delegate;
105
106 $(#[$meta])*
107 #[derive(Debug)]
108 pub(crate) enum Inner<'d> {
109 $(
110 $(#[cfg($variant_meta)])*
111 $variant($inner),
112 )*
113 }
114
115 #[cfg(feature = "defmt")]
116 impl defmt::Format for Inner<'_> {
117 fn format(&self, fmt: defmt::Formatter<'_>) {
118 match self {
119 $(
120 $(#[cfg($variant_meta)])*
121 Self::$variant(inner) => inner.format(fmt),
122 )*
123 }
124 }
125 }
126
127 #[allow(unused)]
133 pub trait Degrade: Sized + $crate::private::Sealed {
134 fn degrade<'a>(self) -> super::$name<'a>
135 where
136 Self: 'a;
137 }
138 }
139
140 $(#[$meta])*
141 #[doc = concat!("let any_peripheral = ", stringify!($name), "::from(peripheral);")]
148 #[derive(Debug)]
150 #[cfg_attr(feature = "defmt", derive(defmt::Format))]
151 $vis struct $name<'d>(any::Inner<'d>);
152
153 impl $name<'_> {
154 #[inline]
160 pub unsafe fn clone_unchecked(&self) -> Self { unsafe {
161 any::delegate!(self, inner => { Self::from(inner.clone_unchecked()) })
162 }}
163
164 #[inline]
173 pub fn reborrow(&mut self) -> $name<'_> {
174 unsafe { self.clone_unchecked() }
175 }
176
177 #[procmacros::doc_replace]
178 #[cfg_attr(
180 uart_driver_supported,
184 doc = r#"
185## Example
186
187```rust,no_run
188# {before_snippet}
189#
190# use esp_hal::{
191# uart::AnyUart as AnyPeripheral,
192# peripherals::{UART0 as PERI0, UART1 as PERI1},
193# };
194#
195# let peri0 = peripherals.UART0;
196# let peri1 = peripherals.UART1;
197// let peri0 = peripherals.PERI0;
198// let peri1 = peripherals.PERI1;
199let any_peri0 = AnyPeripheral::from(peri0);
200let any_peri1 = AnyPeripheral::from(peri1);
201
202let uart0 = any_peri0
203 .downcast::<PERI0>()
204 .expect("This downcast succeeds because AnyPeripheral was created from Peri0");
205let uart0 = any_peri1
206 .downcast::<PERI0>()
207 .expect_err("This AnyPeripheral was created from Peri1, it cannot be downcast to Peri0");
208#
209# {after_snippet}
210```
211"#
212 )]
213 #[inline]
214 pub fn downcast<P>(self) -> Result<P, Self>
215 where
216 Self: TryInto<P, Error = Self>
217 {
218 self.try_into()
219 }
220 }
221
222 impl $crate::private::Sealed for $name<'_> {}
223
224 impl<'d> any::Degrade for $name<'d> {
226 #[inline]
227 fn degrade<'a>(self) -> $name<'a>
228 where
229 Self: 'a,
230 {
231 self
232 }
233 }
234
235 $(
236 $(#[cfg($variant_meta)])*
238 impl<'d> any::Degrade for $inner {
239 #[inline]
240 fn degrade<'a>(self) -> $name<'a>
241 where
242 Self: 'a,
243 {
244 $name::from(self)
245 }
246 }
247
248 $(#[cfg($variant_meta)])*
249 impl<'d> From<$inner> for $name<'d> {
250 #[inline]
251 fn from(inner: $inner) -> Self {
252 Self(any::Inner::$variant(inner))
253 }
254 }
255
256 $(#[cfg($variant_meta)])*
257 impl<'d> TryFrom<$name<'d>> for $inner {
258 type Error = $name<'d>;
259
260 #[inline]
261 fn try_from(any: $name<'d>) -> Result<Self, $name<'d>> {
262 #[allow(irrefutable_let_patterns)]
263 if let $name(any::Inner::$variant(inner)) = any {
264 Ok(inner)
265 } else {
266 Err(any)
267 }
268 }
269 }
270 )*
271 };
272}
273
274#[macro_export]
277#[doc(hidden)]
278macro_rules! if_set {
279 (, $not_set:expr) => {
280 $not_set
281 };
282 ($set:expr, $not_set:expr) => {
283 $set
284 };
285}
286
287#[macro_export]
292#[doc(hidden)]
293macro_rules! ignore {
294 ($($item:tt)*) => {};
295}
296
297#[macro_export]
305#[doc(hidden)]
306macro_rules! metadata {
307 ($category:literal, $key:ident, $value:expr) => {
308 #[cfg(feature = "rt")]
309 #[unsafe(link_section = concat!(".espressif.metadata"))]
310 #[used]
311 #[unsafe(export_name = concat!($category, ".", stringify!($key)))]
312 static $key: [u8; $value.len()] = const {
313 let val_bytes = $value.as_bytes();
314 let mut val_bytes_array = [0; $value.len()];
315 let mut i = 0;
316 while i < val_bytes.len() {
317 val_bytes_array[i] = val_bytes[i];
318 i += 1;
319 }
320 val_bytes_array
321 };
322 };
323}
324
325#[procmacros::doc_replace]
326#[cfg_attr(
328 all(soc_has_spi2, soc_has_i2c0, gpio_driver_supported),
332 doc = r#"
333## Example
334
335```rust,no_run
336# {before_snippet}
337#
338use esp_hal::assign_resources;
339
340assign_resources! {
341 Resources<'d> {
342 display: DisplayResources<'d> {
343 spi: SPI2,
344 sda: GPIO5,
345 sclk: GPIO4,
346 cs: GPIO3,
347 dc: GPIO2,
348 },
349 axl: AccelerometerResources<'d> {
350 i2c: I2C0,
351 sda: GPIO0,
352 scl: GPIO1,
353 },
354 }
355}
356
357# struct Display<'d>(core::marker::PhantomData<&'d ()>);
358fn init_display<'d>(r: DisplayResources<'d>) -> Display<'d> {
359 // use `r.spi`, `r.sda`, `r.sclk`, `r.cs`, `r.dc`
360 todo!()
361}
362
363# struct Accelerometer<'d>(core::marker::PhantomData<&'d ()>);
364fn init_accelerometer<'d>(r: AccelerometerResources<'d>) -> Accelerometer<'d> {
365 // use `r.i2c`, `r.sda`, `r.scl`
366 todo!()
367}
368
369// let peripherals = esp_hal::init(...);
370let resources = split_resources!(peripherals);
371
372let display = init_display(resources.display);
373let axl = init_accelerometer(resources.axl);
374
375// Other fields (`peripherals.UART0`, ...) of the `peripherals` struct can still be accessed.
376# {after_snippet}
377```
378"#
379)]
380#[macro_export]
382#[cfg(feature = "unstable")]
383#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
384macro_rules! assign_resources {
385 {
386 $(#[$struct_meta:meta])*
387 $vis:vis $struct_name:ident<$struct_lt:lifetime> {
388 $(
389 $(#[$group_meta:meta])*
390 $group_name:ident : $group_struct:ident<$group_lt:lifetime> {
391 $(
392 $(#[$resource_meta:meta])*
393 $resource_name:ident : $resource_field:ident
394 ),*
395 $(,)?
396 }
397 ),+
398 $(,)?
399 }
400 } => {
401 $(
403 $(#[$group_meta])*
404 #[allow(missing_docs)]
405 $vis struct $group_struct<$group_lt> {
406 $(
407 $(#[$resource_meta])*
408 pub $resource_name: $crate::peripherals::$resource_field<$group_lt>,
409 )+
410 }
411
412 impl<$group_lt> $group_struct<$group_lt> {
413 pub unsafe fn steal() -> Self {
419 unsafe {
420 Self {
421 $($resource_name: $crate::peripherals::$resource_field::steal()),*
422 }
423 }
424 }
425
426 pub fn reborrow(&mut self) -> $group_struct<'_> {
431 $group_struct {
432 $($resource_name: self.$resource_name.reborrow()),*
433 }
434 }
435 }
436 )+
437
438 $(#[$struct_meta])*
440 $vis struct $struct_name<$struct_lt> {
442 $( pub $group_name: $group_struct<$struct_lt>, )+
443 }
444
445 impl<$struct_lt> $struct_name<$struct_lt> {
446 pub unsafe fn steal() -> Self {
452 unsafe {
453 Self {
454 $($group_name: $group_struct::steal()),*
455 }
456 }
457 }
458
459 pub fn reborrow(&mut self) -> $struct_name<'_> {
464 $struct_name {
465 $($group_name: self.$group_name.reborrow()),*
466 }
467 }
468 }
469
470 #[macro_export]
472 macro_rules! split_resources {
473 ($peris:ident) => {
474 $struct_name {
475 $($group_name: $group_struct {
476 $($resource_name: $peris.$resource_field),*
477 }),*
478 }
479 }
480 }
481 };
482}