1#![no_std]
4#![deny(rustdoc::broken_intra_doc_links)]
5
6#[cfg(not(any(
9 all(
10 target_arch = "arm",
11 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,
32unnecessary_transmutes,
34clippy::ptr_offset_with_cast,
36)]
37#[rustfmt::skip]
38mod bindings;
39
40#[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#[doc(hidden)]
83#[macro_export]
84macro_rules! __crash_implementation {
85 ($ptr:expr) => {
86 unsafe {
87 ::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#[macro_export]
122macro_rules! halt {
123 () => {
124 $crate::__halt_implementation!(::core::ptr::null());
125 };
126 ($msg:expr $(,)?) => {{
127 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#[doc(hidden)]
143#[macro_export]
144macro_rules! __halt_implementation {
145 ($ptr:expr) => {
146 unsafe {
147 ::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
159pub trait HasFlag {
163 fn has_flag(self, flag: Self) -> bool;
164}
165
166#[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
232pub use bindings::*;
234
235pub use inlines::furi_hal_gpio::*;