embedded_platform/
lib.rs

1//! # Embedded platform
2//!
3//! This crate defines a rich platform on top of which embedded device drivers and applications can
4//! be written.
5//!
6//! The idea is to add device and peripheral support to complement [`embedded-hal`]-based crates.
7//! This makes it possible to plug-and-play and mix-and-match different crates that adhere to common
8//! specs.  For example, if you have a `nrf52840`-based MCU as well as a `ili9341`-based device, and
9//! both adhere to the [Adafruit Feather spec] (pin layout, voltage levels, ...), you can connect
10//! them up and all the wiring will be done for you.
11//!
12//! The ambition is that `embedded-platform` should be to `embedded-hal` what `tokio` is to `mio`.
13//!
14//! ## Design
15//!
16//! Some design trade-offs that have been made:
17//!
18//!   * `#![forbid(unsafe_code)]`; that belongs in `-pac` or `-hal` crates.
19//!   * Don't require `alloc`.
20//!   * Do some compatibility checks at runtime during startup instead of at compile time, for
21//!     example to check that a pin is used only once.  It turns out to be super tricky to do
22//!     granular ownership mapping of device registers at compile time (this has been done in
23//!     [`drone-os`](https://www.drone-os.com/)), and instead we opt to do some checks at runtime
24//!     (e.g. `Option::take`).  This wastes a dozen or so instructions at startup, which is a
25//!     one-time cost.
26//!   * All APIs are async-first, so that code won't have to block and we can be power efficient.
27//!     This does require an executor, and one can be made that doesn't require `alloc`, yet to be
28//!     written.
29//!   * The crate uses its own HAL-like traits for e.g. `OutputPin` or `I2cRead` to enable async
30//!     APIs as well as smooth over any incompatibilities between `embedded_hal::gpio::v1` and
31//!     `embedded_hal::gpio::v2` etc.
32//!   * All platform crates should be maintained in this repository so that changes like the last
33//!     bullet point can be made in lock-step.
34//!   * Don't expose interrupts to the user.  `mypin.changes()` should return an async
35//!     `futures::Stream` when the pin changes.  In the background, we stash away a `Waker` that
36//!      gets called from the interrupt handler.
37//!
38//! ## Stack
39//! You can think about the intended stack like this:
40//!
41//! ```text
42//! ┌─────────────────────────────────────────┐
43//! │         Peripheral Access Crate         │
44//! │            e.g. nrf52840-pac            │
45//! ├─────────────────────────────────────────┤
46//! │        Hardware Abstraction Layer       │
47//! │            e.g. nrf52840-hal            │
48//! ├─────────────────────────────────────────┤
49//! │         Platform Implementation         │
50//! │          e.g. nrf52840-platform         │
51//! │ ┌─────────────────────────────────────┐ │
52//! │ │          Specific Product           │ │
53//! │ │         e.g. Particle Argon         │ │
54//! │ ├─────────────────────────────────────┤ │
55//! │ │            Common Spec              │ │
56//! │ │        e.g. Adafruit Feather        │ │
57//! │ │          or Arduino Shield          │ │
58//! │ ├─────────────────────────────────────┤ │
59//! │ │              Adapter                │ │
60//! │ │        e.g. "Main SPI bus" on       │ │
61//! │ │        specific Feather pins        │ │
62//! │ └─────────────────────────────────────┘ │
63//! ├─────────────────────────────────────────┤
64//! │              Device Driver              │
65//! │              e.g. ili9341               │
66//! └─────────────────────────────────────────┘
67//! ```
68//!
69//! [`embedded-hal`]: https://crates.io/crates/embedded-hal
70//! [Adafruit Feather spec]: https://learn.adafruit.com/adafruit-feather/feather-specification
71#![no_std]
72#![deny(
73    // missing_docs,
74    missing_debug_implementations,
75    missing_copy_implementations,
76    trivial_casts,
77    trivial_numeric_casts,
78    unstable_features,
79    unused_import_braces,
80    unused_qualifications,
81    clippy::all
82)]
83#![forbid(unsafe_code)]
84
85pub mod gpio;
86pub mod i2c;
87pub mod io;
88pub mod platform;
89pub mod specs;
90pub mod spi;
91pub mod time;
92
93pub use platform::Platform;