stm32_hal2/macros.rs
1//! This module contains utility macros that are not STM32-specific, or specific
2//! to this library.
3
4/// Syntax helper for getting global variables of the form `Mutex<RefCell<Option>>>` from an interrupt-free
5/// context - eg in interrupt handlers.
6///
7/// Example: `access_global!(DELAY, delay, cs)`
8#[macro_export]
9macro_rules! access_global {
10 ($NAME_GLOBAL:ident, $name_local:ident, $cs:expr) => {
11 let mut part1 = $NAME_GLOBAL.borrow($cs).borrow_mut();
12 let $name_local = part1.as_mut().unwrap();
13 };
14}
15
16/// Similar to `access_global`, but combining multiple calls.
17///
18/// Example: `access_globals!([
19/// (USB_DEV, usb_dev),
20/// (USB_SERIAL, usb_serial),
21/// ], cs);`
22#[macro_export]
23macro_rules! access_globals {
24 ([$(($NAME_GLOBAL:ident, $name_local:ident)),* $(,)?], $cs:expr) => {
25 $(
26 let mut part = $NAME_GLOBAL.borrow($cs).borrow_mut();
27 let $name_local = part.as_mut().unwrap();
28 )*
29 };
30}
31
32/// Syntax helper for setting global variables of the form `Mutex<RefCell<Option>>>`.
33/// eg in interrupt handlers. Ideal for non-copy-type variables that can't be initialized
34/// immediatiately.
35///
36/// Example: `make_globals!(
37/// (USB_SERIAL, SerialPort<UsbBusType>),
38/// (DELAY, Delay),
39/// )`
40#[macro_export]
41macro_rules! make_globals {
42 ($(($NAME:ident, $type:ty)),+ $(,)?) => {
43 $(
44 static $NAME: ::critical_section::Mutex<core::cell::RefCell<Option<$type>>> = ::critical_section::Mutex::new(core::cell::RefCell::new(None));
45 )+
46 };
47}
48
49/// Syntax helper for setting global variables of the form `Mutex<Cell<>>>`.
50/// eg in interrupt handlers. Ideal for copy-type variables.
51///
52/// Example: `make_simple_globals!(
53/// (VALUE, f32, 2.),
54/// (SETTING, Setting, Setting::A),
55/// )`
56#[macro_export]
57macro_rules! make_simple_globals {
58 ($(($NAME:ident, $type:ty, $val:expr)),+ $(,)?) => {
59 $(
60 static $NAME: ::critical_section::Mutex<core::cell::Cell<$type>> = ::critical_section::Mutex::new(core::cell::Cell::new($val));
61 )+
62 };
63}
64
65/// Initialize one or more globals inside a critical section.
66///
67/// Usage:
68/// ```rust
69/// init_globals!(
70/// (FLASH, flash),
71/// (SPI_IMU, spi1),
72/// (I2C_MAG, i2c1),
73/// // …
74/// );
75/// ```
76#[macro_export]
77macro_rules! init_globals {
78 ($(($NAME:ident, $val:expr)),* $(,)?) => {
79 ::critical_section::with(|cs| {
80 $(
81 $NAME.borrow(cs).replace(Some($val));
82 )*
83 });
84 };
85}
86
87/// Automates Cortex-M NVIC setup. The second value is NVIC priority; lower
88/// is higher priority. Example use:
89/// setup_nvic!([
90/// (TIM2, 6),
91/// (TIM3, 7),
92/// (EXTI0, 4),
93/// ], cp);
94#[macro_export]
95macro_rules! setup_nvic {
96 (
97 [ $( ($int:ident, $prio:expr) ),* $(,)? ],
98 $cp:ident
99 ) => {
100 unsafe {
101 $(
102 cortex_m::peripheral::NVIC::unmask(pac::Interrupt::$int);
103 )*
104 $(
105 $cp.NVIC.set_priority(pac::Interrupt::$int, $prio);
106 )*
107 }
108 };
109}
110
111/// Syntax helper for parsing multi-byte fields into primitives.
112///
113/// Example: `parse_le!(bytes, i32, 5..9);`
114#[macro_export]
115macro_rules! parse_le {
116 ($bytes:expr, $t:ty, $range:expr) => {{ <$t>::from_le_bytes($bytes[$range].try_into().unwrap()) }};
117}
118
119/// Syntax helper for parsing multi-byte fields into primitives.
120///
121/// Example: `parse_be!(bytes, i32, 5..9);`
122#[macro_export]
123macro_rules! parse_be {
124 ($bytes:expr, $t:ty, $range:expr) => {{ <$t>::from_be_bytes($bytes[$range].try_into().unwrap()) }};
125}
126
127/// Syntax helper for converting primitives to multi-byte fields.
128///
129/// Example: `copy_le!(bytes, self.position, 5..9);`
130#[macro_export]
131macro_rules! copy_le {
132 ($dest:expr, $src:expr, $range:expr) => {{ $dest[$range].copy_from_slice(&$src.to_le_bytes()) }};
133}
134
135/// Syntax helper for converting primitives to multi-byte fields.
136///
137/// Example: `copy_be!(bytes, self.position, 5..9);`
138#[macro_export]
139macro_rules! copy_be {
140 ($dest:expr, $src:expr, $range:expr) => {{ $dest[$range].copy_from_slice(&$src.to_be_bytes()) }};
141}