flipperzero_sys/
lib.rs

1//! Low-level bindings for the Flipper Zero.
2
3#![no_std]
4#![deny(rustdoc::broken_intra_doc_links)]
5
6// Features that identify thumbv7em-none-eabihf.
7// NOTE: `arm_target_feature` is currently unstable (see rust-lang/rust#44839)
8#[cfg(not(any(
9    all(
10        target_arch = "arm",
11        //target_feature = "thumb2",
12        //target_feature = "v7",
13        //target_feature = "dsp",
14        target_os = "none",
15        target_abi = "eabihf",
16    ),
17    miri
18)))]
19core::compile_error!("This crate requires `--target thumbv7em-none-eabihf`");
20
21pub mod furi;
22mod inlines;
23
24#[allow(
25    non_upper_case_globals,
26    non_camel_case_types,
27    non_snake_case,
28    clippy::missing_safety_doc,
29    clippy::transmute_int_to_bool,
30    clippy::useless_transmute,
31    rustdoc::broken_intra_doc_links,
32// https://github.com/rust-lang/rust-bindgen/issues/2807
33    unnecessary_transmutes,
34// https://github.com/rust-lang/rust-bindgen/issues/3053
35    clippy::ptr_offset_with_cast,
36)]
37#[rustfmt::skip]
38mod bindings;
39
40/// Crash the system.
41///
42/// May be provided with an optional message which should not contain NULs.
43/// The following will not compile:
44///
45/// ```compile_fail
46/// flipperzero_sys::crash!("Has a \0 NUL");
47/// ```
48///
49/// # Examples
50///
51/// Crash the system with a *"Hello world!"* message:
52///
53/// ```
54/// flipperzero_sys::crash!("Hello world!");
55/// ```
56///
57/// Crash the system with default *"Fatal Error"* message:
58///
59/// ```
60/// flipperzero_sys::crash!();
61/// ```
62#[macro_export]
63macro_rules! crash {
64    () => {
65        $crate::__crash_implementation!(::core::ptr::null());
66    };
67    ($msg:expr $(,)?) => {{
68        let message = const {
69            match ::core::ffi::CStr::from_bytes_with_nul(::core::concat!($msg, "\0").as_bytes()) {
70                Err(_) => c"nul in crash message",
71                Ok(m) => m,
72            }
73        };
74
75        $crate::__crash_implementation!(message.as_ptr());
76    }};
77}
78
79/// Crash the system.
80///
81/// This is an internal implementation detail.
82#[doc(hidden)]
83#[macro_export]
84macro_rules! __crash_implementation {
85    ($ptr:expr) => {
86        unsafe {
87            // Crash message is passed via r12
88            ::core::arch::asm!(
89                "ldr pc,=__furi_crash_implementation",
90                in("r12") ($ptr),
91                options(nostack),
92            );
93
94            ::core::hint::unreachable_unchecked();
95        }
96    };
97}
98
99/// Halt the system.
100///
101/// May be provided with an optional message which should not contain NULs.
102/// The following will not compile:
103///
104/// ```compile_fail
105/// flipperzero_sys::halt!("Has a \0 NUL");
106/// ```
107///
108/// # Examples
109///
110/// Halt the system with a *"Hello world!"* message:
111///
112/// ```
113/// flipperzero_sys::crash!("Hello world!");
114/// ```
115///
116/// Halt the system with default *"System halt requested."* message:
117///
118/// ```
119/// flipperzero_sys::crash!();
120/// ```
121#[macro_export]
122macro_rules! halt {
123    () => {
124        $crate::__halt_implementation!(::core::ptr::null());
125    };
126    ($msg:expr $(,)?) => {{
127        // Optional message
128        let message = const {
129            match ::core::ffi::CStr::from_bytes_with_nul(::core::concat!($msg, "\0").as_bytes()) {
130                Err(_) => c"nul in halt message",
131                Ok(m) => m,
132            }
133        };
134
135        $crate::__halt_implementation!(message.as_ptr());
136    }};
137}
138
139/// Halt the system.
140///
141/// This is an internal implementation detail.
142#[doc(hidden)]
143#[macro_export]
144macro_rules! __halt_implementation {
145    ($ptr:expr) => {
146        unsafe {
147            // Halt message is passed via r12
148            ::core::arch::asm!(
149                "ldr pc,=__furi_halt_implementation",
150                in("r12") ($ptr),
151                options(nomem, nostack))
152            ;
153
154            ::core::hint::unreachable_unchecked();
155        }
156    };
157}
158
159/// Check if flag is set.
160///
161/// Typically implemented as `(self & flag) == flag`.
162pub trait HasFlag {
163    fn has_flag(self, flag: Self) -> bool;
164}
165
166/// Implement bitfield operations for "bitfield" enums.
167#[doc(hidden)]
168macro_rules! impl_bitfield_enum {
169    ($t:ty) => {
170        impl ::core::default::Default for $t {
171            #[inline]
172            fn default() -> Self {
173                Self(0)
174            }
175        }
176        impl ::core::ops::BitOr<$t> for $t {
177            type Output = Self;
178
179            #[inline]
180            fn bitor(self, other: Self) -> Self {
181                Self(self.0 | other.0)
182            }
183        }
184        impl ::core::ops::BitOrAssign for $t {
185            #[inline]
186            fn bitor_assign(&mut self, rhs: $t) {
187                self.0 |= rhs.0;
188            }
189        }
190        impl ::core::ops::BitAnd<$t> for $t {
191            type Output = Self;
192            #[inline]
193            fn bitand(self, other: Self) -> Self {
194                Self(self.0 & other.0)
195            }
196        }
197        impl ::core::ops::BitAndAssign for $t {
198            #[inline]
199            fn bitand_assign(&mut self, rhs: $t) {
200                self.0 &= rhs.0;
201            }
202        }
203        impl ::core::ops::Not for $t {
204            type Output = Self;
205            #[inline]
206            fn not(self) -> Self::Output {
207                Self(!self.0)
208            }
209        }
210        impl HasFlag for $t {
211            #[inline]
212            fn has_flag(self, flag: Self) -> bool {
213                (self.0 & flag.0) == flag.0
214            }
215        }
216    };
217}
218
219impl_bitfield_enum!(CliCommandFlag);
220impl_bitfield_enum!(FS_AccessMode);
221impl_bitfield_enum!(FS_Flags);
222impl_bitfield_enum!(FS_OpenMode);
223impl_bitfield_enum!(FuriFlag);
224impl_bitfield_enum!(FuriHalNfcEvent);
225impl_bitfield_enum!(FuriHalRtcFlag);
226impl_bitfield_enum!(FuriHalSerialRxEvent);
227impl_bitfield_enum!(iButtonProtocolFeature);
228impl_bitfield_enum!(Light);
229impl_bitfield_enum!(MfUltralightFeatureSupport);
230impl_bitfield_enum!(SubGhzProtocolFlag);
231
232// Re-export bindings
233pub use bindings::*;
234
235// Definition of inline functions
236pub use inlines::furi_hal_gpio::*;