wasefire_board_api/
lib.rs1#![no_std]
21#![feature(doc_auto_cfg)]
22#![feature(never_type)]
23
24extern crate alloc;
25
26use core::marker::PhantomData;
27use core::ops::Deref;
28
29use derive_where::derive_where;
30use wasefire_error::Code;
31pub use wasefire_error::Error;
32
33pub mod applet;
34#[cfg(feature = "api-button")]
35pub mod button;
36#[cfg(feature = "internal-api-crypto")]
37pub mod crypto;
38pub mod debug;
39#[cfg(feature = "api-gpio")]
40pub mod gpio;
41#[cfg(feature = "api-led")]
42pub mod led;
43pub mod platform;
44#[cfg(feature = "internal-api-radio")]
45pub mod radio;
46#[cfg(feature = "api-rng")]
47pub mod rng;
48#[cfg(feature = "api-timer")]
49pub mod timer;
50#[cfg(feature = "api-uart")]
51pub mod uart;
52#[cfg(feature = "internal-api-usb")]
53pub mod usb;
54
55pub trait Api: Send + 'static {
61 fn try_event() -> Option<Event<Self>>;
65
66 fn wait_event() -> Event<Self>;
71
72 fn syscall(_x1: u32, _x2: u32, _x3: u32, _x4: u32) -> Option<Result<u32, Error>> {
78 None
79 }
80
81 type Applet: applet::Api;
83
84 #[cfg(feature = "api-button")]
86 type Button: button::Api;
87
88 #[cfg(feature = "internal-api-crypto")]
90 type Crypto: crypto::Api;
91
92 type Debug: debug::Api;
94
95 #[cfg(feature = "api-gpio")]
97 type Gpio: gpio::Api;
98
99 #[cfg(feature = "api-led")]
101 type Led: led::Api;
102
103 type Platform: platform::Api;
105
106 #[cfg(feature = "internal-api-radio")]
108 type Radio: radio::Api;
109
110 #[cfg(feature = "api-rng")]
112 type Rng: rng::Api;
113
114 #[cfg(feature = "api-storage")]
116 type Storage: Singleton + wasefire_store::Storage + Send;
117
118 #[cfg(feature = "api-timer")]
120 type Timer: timer::Api;
121
122 #[cfg(feature = "api-uart")]
124 type Uart: uart::Api;
125
126 #[cfg(feature = "internal-api-usb")]
128 type Usb: usb::Api;
129}
130
131pub trait Support<Value> {
136 const SUPPORT: Value;
138}
139
140pub trait Supported {}
142
143pub trait Singleton: Sized {
145 fn take() -> Option<Self>;
149}
150
151#[cfg_attr(feature = "defmt", derive(defmt::Format))]
156#[derive_where(Debug, PartialEq, Eq)]
157pub enum Event<B: Api + ?Sized> {
158 #[cfg(feature = "api-button")]
160 Button(button::Event<B>),
161
162 Platform(platform::Event),
164
165 #[cfg(feature = "internal-api-radio")]
167 Radio(radio::Event),
168
169 #[cfg(feature = "api-timer")]
171 Timer(timer::Event<B>),
172
173 #[cfg(feature = "api-uart")]
175 Uart(uart::Event<B>),
176
177 #[cfg(feature = "internal-api-usb")]
179 Usb(usb::Event),
180
181 Impossible(Impossible<B>),
183}
184
185#[derive_where(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
190pub struct Impossible<B: Api + ?Sized>(!, PhantomData<B>);
191
192#[cfg(feature = "defmt")]
193impl<B: Api + ?Sized> defmt::Format for Impossible<B> {
194 fn format(&self, fmt: defmt::Formatter) {
195 defmt::write!(fmt, "Impossible");
196 }
197}
198
199impl<B: Api + ?Sized> Impossible<B> {
200 pub fn unreachable(&self) -> ! {
202 match self.0 {}
203 }
204}
205
206pub type Applet<B> = <B as Api>::Applet;
208
209#[cfg(feature = "api-button")]
211pub type Button<B> = <B as Api>::Button;
212
213#[cfg(feature = "internal-api-crypto")]
215pub type Crypto<B> = <B as Api>::Crypto;
216
217pub type Debug<B> = <B as Api>::Debug;
219
220#[cfg(feature = "api-gpio")]
222pub type Gpio<B> = <B as Api>::Gpio;
223
224#[cfg(feature = "api-led")]
226pub type Led<B> = <B as Api>::Led;
227
228pub type Platform<B> = <B as Api>::Platform;
230
231#[cfg(feature = "internal-api-radio")]
233pub type Radio<B> = <B as Api>::Radio;
234
235#[cfg(feature = "api-rng")]
237pub type Rng<B> = <B as Api>::Rng;
238
239#[cfg(feature = "api-storage")]
241pub type Storage<B> = <B as Api>::Storage;
242
243#[cfg(feature = "api-timer")]
245pub type Timer<B> = <B as Api>::Timer;
246
247#[cfg(feature = "api-uart")]
249pub type Uart<B> = <B as Api>::Uart;
250
251#[cfg(feature = "internal-api-usb")]
253pub type Usb<B> = <B as Api>::Usb;
254
255#[derive_where(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
257pub struct Id<T: Support<usize> + ?Sized> {
258 value: usize,
260 count: PhantomData<T>,
261}
262
263#[cfg(feature = "defmt")]
264impl<T: Support<usize> + ?Sized> defmt::Format for Id<T> {
265 fn format(&self, fmt: defmt::Formatter) {
266 self.value.format(fmt)
267 }
268}
269
270impl<T: Support<usize>> Id<T> {
271 pub fn new(value: usize) -> Result<Self, Error> {
273 match value < T::SUPPORT {
274 true => Ok(Self { value, count: PhantomData }),
275 false => Err(Error::user(Code::OutOfBounds)),
276 }
277 }
278}
279
280impl<T: Support<usize>> Deref for Id<T> {
281 type Target = usize;
282
283 fn deref(&self) -> &Self::Target {
284 &self.value
285 }
286}
287
288impl<T: Supported> Support<bool> for T {
289 const SUPPORT: bool = true;
290}