zephyr/device.rs
1//! Device wrappers
2//!
3//! This module contains implementations of wrappers for various types of devices in zephyr. In
4//! general, these wrap a `*const device` from Zephyr, and provide an API that is appropriate.
5//!
6//! Most of these instances come from the device tree.
7
8// Allow for a Zephyr build that has no devices at all.
9#![allow(dead_code)]
10
11use crate::sync::atomic::{AtomicBool, Ordering};
12
13#[cfg(CONFIG_FLASH)]
14pub mod flash;
15#[cfg(CONFIG_GPIO)]
16pub mod gpio;
17#[cfg(CONFIG_I2C)]
18pub mod i2c;
19#[cfg(CONFIG_LED)]
20pub mod led;
21#[cfg(CONFIG_LED_STRIP)]
22pub mod led_strip;
23
24// Allow dead code, because it isn't required for a given build to have any devices.
25/// Device uniqueness.
26///
27/// As the zephyr devices are statically defined structures, this `Unique` value ensures that the
28/// user is only able to get a single instance of any given device.
29///
30/// Note that some devices in zephyr will require more than one instance of the actual device. For
31/// example, a [`GpioPin`] will reference a single pin, but the underlying device for the gpio
32/// driver will be shared among then. Generally, the constructor for the individual device will
33/// call `get_instance_raw()` on the underlying device.
34pub(crate) struct Unique(pub(crate) AtomicBool);
35
36impl Unique {
37 // Note that there are circumstances where these are in zero-initialized memory, so false must
38 // be used here, and the result of `once` inverted.
39 /// Construct a new unique counter.
40 pub(crate) const fn new() -> Unique {
41 Unique(AtomicBool::new(false))
42 }
43
44 /// Indicates if this particular entity can be used. This function, on a given `Unique` value
45 /// will return true exactly once.
46 pub(crate) fn once(&self) -> bool {
47 // `fetch_add` is likely to be faster than compare_exchage. This does have the limitation
48 // that `once` is not called more than `usize::MAX` times.
49 !self.0.fetch_or(true, Ordering::AcqRel)
50 }
51}
52
53/// For devices that don't need any associated static data, This NoStatic type will take no space
54/// and generate no code, and has the const constructor needed for the type.
55pub struct NoStatic;
56
57impl NoStatic {
58 pub(crate) const fn new() -> Self {
59 Self
60 }
61}