arduino_hal/
lib.rs

1#![no_std]
2#![feature(doc_cfg)]
3
4//! `arduino-hal`
5//! =============
6//! Common HAL (hardware abstraction layer) for Arduino boards.
7//!
8//! **Note**: This version of the documentation was built for
9#![cfg_attr(feature = "arduino-diecimila", doc = "**Arduino Diecimila**.")]
10#![cfg_attr(feature = "arduino-leonardo", doc = "**Arduino Leonardo**.")]
11#![cfg_attr(feature = "arduino-mega2560", doc = "**Arduino Mega 2560**.")]
12#![cfg_attr(feature = "arduino-mega1280", doc = "**Arduino Mega 1280**.")]
13#![cfg_attr(feature = "arduino-micro", doc = "**Arduino Micro**.")]
14#![cfg_attr(feature = "arduino-nano", doc = "**Arduino Nano**.")]
15#![cfg_attr(feature = "arduino-uno", doc = "**Arduino Uno**.")]
16#![cfg_attr(feature = "sparkfun-promicro", doc = "**SparkFun ProMicro**.")]
17#![cfg_attr(
18    feature = "sparkfun-promini-3v3",
19    doc = "**SparkFun ProMini 3.3V (8MHz)**."
20)]
21#![cfg_attr(
22    feature = "sparkfun-promini-5v",
23    doc = "**SparkFun ProMini 5V (16MHz)**."
24)]
25#![cfg_attr(feature = "trinket-pro", doc = "**Trinket Pro**.")]
26#![cfg_attr(feature = "trinket", doc = "**Trinket**.")]
27#![cfg_attr(feature = "nano168", doc = "**Nano clone (ATmega168)**.")]
28//! This means that only items which are available for this board are visible.  If you are using a
29//! different board, try building the documentation locally with
30//!
31//! ```text
32//! cargo doc --open
33//! ```
34//!
35//! in your project (where `arduino-hal` is included with the feature-flag for your board).
36//!
37//! ## Usage
38//! For setting up a new project, the [`avr-hal-template`](https://github.com/Rahix/avr-hal-template)
39//! is the recommended baseline.  Applications should be built ontop of the following skeleton:
40//!
41//! ```no_run
42//! #![no_std]
43//! #![no_main]
44//!
45//! use panic_halt as _;
46//!
47//! #[arduino_hal::entry]
48//! fn main() -> ! {
49//!     let dp = arduino_hal::Peripherals::take().unwrap();
50//!     let pins = arduino_hal::pins!(dp);
51//!
52//!     loop { }
53//! }
54//! ```
55//!
56//! For examples, please check the `avr-hal` examples: <https://github.com/Rahix/avr-hal/tree/main/examples>
57
58#[cfg(not(feature = "board-selected"))]
59compile_error!(
60    "This crate requires you to specify your target Arduino board as a feature.
61
62    Please select one of the following
63
64    * arduino-diecimila
65    * arduino-leonardo
66    * arduino-mega2560
67    * arduino-mega1280
68    * arduino-micro
69    * arduino-nano
70    * arduino-uno
71    * sparkfun-promicro
72    * sparkfun-promini-3v3
73    * sparkfun-promini-5v
74    * trinket-pro
75    * trinket
76    * nano168
77    "
78);
79
80/// Attribute to declare the entry point of the program
81///
82/// Exactly one entry point must be declared in the entire dependency tree.
83///
84/// ```
85/// #[arduino_hal::entry]
86/// fn main() -> ! {
87///     // ...
88/// }
89/// ```
90///
91/// The entry function must have a signature of `[unsafe] fn() -> !`.
92///
93/// This macro is a reexport of [`avr_device::entry`].  It is only available when the `rt`
94/// (runtime) feature is selected (it is by default).
95#[cfg(any(feature = "rt", doc))]
96#[doc(cfg(feature = "rt"))]
97pub use avr_device::entry;
98
99#[doc(no_inline)]
100#[cfg(feature = "mcu-atmega")]
101pub use atmega_hal as hal;
102#[doc(no_inline)]
103#[cfg(feature = "mcu-atmega")]
104pub use atmega_hal::pac;
105
106#[doc(no_inline)]
107#[cfg(feature = "mcu-attiny")]
108pub use attiny_hal as hal;
109#[doc(no_inline)]
110#[cfg(feature = "mcu-attiny")]
111pub use attiny_hal::pac;
112
113#[doc(no_inline)]
114#[cfg(feature = "board-selected")]
115pub use hal::Peripherals;
116
117#[cfg(feature = "board-selected")]
118pub mod clock;
119#[cfg(feature = "board-selected")]
120pub use clock::default::DefaultClock;
121
122#[cfg(feature = "board-selected")]
123mod delay;
124#[cfg(feature = "board-selected")]
125pub use delay::{delay_ms, delay_ns, delay_us, Delay};
126
127#[cfg(feature = "board-selected")]
128pub mod port;
129
130#[doc(no_inline)]
131#[cfg(feature = "board-selected")]
132pub use port::Pins;
133
134/// Analog to Digital converter.
135#[cfg(feature = "mcu-atmega")]
136pub mod adc {
137    pub use crate::hal::adc::{
138        channel, AdcChannel, AdcOps, AdcSettings, Channel, ClockDivider, ReferenceVoltage,
139    };
140
141    /// Check the [`avr_hal_generic::adc::Adc`] documentation.
142    pub type Adc = crate::hal::Adc<crate::DefaultClock>;
143}
144#[doc(no_inline)]
145#[cfg(feature = "mcu-atmega")]
146pub use adc::Adc;
147
148/// I2C bus controller.
149#[cfg(feature = "mcu-atmega")]
150pub mod i2c {
151    pub use crate::hal::i2c::*;
152
153    pub type I2c = crate::hal::i2c::I2c<crate::DefaultClock>;
154}
155#[doc(no_inline)]
156#[cfg(feature = "mcu-atmega")]
157pub use i2c::I2c;
158
159/// SPI controller.
160#[cfg(feature = "mcu-atmega")]
161pub mod spi {
162    pub use crate::hal::spi::*;
163
164    pub type Spi = crate::hal::spi::Spi;
165}
166#[doc(no_inline)]
167#[cfg(feature = "mcu-atmega")]
168pub use spi::Spi;
169
170#[cfg(feature = "mcu-atmega")]
171pub mod usart {
172    pub use crate::hal::usart::{Baudrate, UsartOps};
173
174    pub type Usart<USART, RX, TX> = crate::hal::usart::Usart<USART, RX, TX, crate::DefaultClock>;
175    pub type UsartWriter<USART, RX, TX> =
176        crate::hal::usart::UsartWriter<USART, RX, TX, crate::DefaultClock>;
177    pub type UsartReader<USART, RX, TX> =
178        crate::hal::usart::UsartReader<USART, RX, TX, crate::DefaultClock>;
179}
180
181#[doc(no_inline)]
182#[cfg(feature = "mcu-atmega")]
183pub use usart::Usart;
184
185#[cfg(feature = "board-selected")]
186pub mod eeprom {
187    pub use crate::hal::eeprom::{Eeprom, EepromOps, OutOfBoundsError};
188}
189#[doc(no_inline)]
190#[cfg(feature = "board-selected")]
191pub use eeprom::Eeprom;
192
193#[cfg(feature = "board-selected")]
194pub mod simple_pwm {
195    #[cfg(feature = "mcu-atmega")]
196    pub use atmega_hal::simple_pwm::*;
197
198    #[cfg(feature = "mcu-attiny")]
199    pub use attiny_hal::simple_pwm::*;
200}
201
202#[cfg(feature = "mcu-atmega")]
203pub mod prelude {
204    pub use crate::hal::prelude::*;
205
206    cfg_if::cfg_if! {
207        if #[cfg(any(
208            feature = "arduino-diecimila",
209            feature = "arduino-mega2560",
210            feature = "arduino-mega1280",
211            feature = "arduino-uno"
212        ))] {
213            pub use crate::hal::usart::BaudrateArduinoExt as _;
214        } else {
215            pub use crate::hal::usart::BaudrateExt as _;
216        }
217    }
218}
219
220/// Convenience macro to instantiate the [`Pins`] struct for this board.
221///
222/// # Example
223/// ```no_run
224/// let dp = arduino_hal::Peripherals::take().unwrap();
225/// let pins = arduino_hal::pins!(dp);
226/// ```
227#[cfg(feature = "board-selected")]
228#[macro_export]
229macro_rules! pins {
230    ($p:expr) => {
231        $crate::Pins::with_mcu_pins($crate::hal::pins!($p))
232    };
233}
234
235/// Convenience macro to instantiate the [`Usart`] driver for this board.
236///
237/// # Example
238/// ```no_run
239/// let dp = arduino_hal::Peripherals::take().unwrap();
240/// let pins = arduino_hal::pins!(dp);
241/// let serial = arduino_hal::default_serial!(dp, pins, 57600);
242/// ```
243#[cfg(any(feature = "arduino-leonardo", feature = "arduino-micro"))]
244#[macro_export]
245macro_rules! default_serial {
246    ($p:expr, $pins:expr, $baud:expr) => {
247        $crate::Usart::new(
248            $p.USART1,
249            $pins.d0,
250            $pins.d1.into_output(),
251            $crate::hal::usart::BaudrateExt::into_baudrate($baud),
252        )
253    };
254}
255
256/// Convenience macro to instantiate the [`Usart`] driver for this board.
257///
258/// # Example
259/// ```no_run
260/// let dp = arduino_hal::Peripherals::take().unwrap();
261/// let pins = arduino_hal::pins!(dp);
262/// let serial = arduino_hal::default_serial!(dp, pins, 57600);
263/// ```
264#[cfg(any(feature = "sparkfun-promicro"))]
265#[macro_export]
266macro_rules! default_serial {
267    ($p:expr, $pins:expr, $baud:expr) => {
268        $crate::Usart::new(
269            $p.USART1,
270            $pins.rx,
271            $pins.tx.into_output(),
272            $crate::hal::usart::BaudrateExt::into_baudrate($baud),
273        )
274    };
275}
276
277/// Convenience macro to instantiate the [`Usart`] driver for this board.
278///
279/// # Example
280/// ```no_run
281/// let dp = arduino_hal::Peripherals::take().unwrap();
282/// let pins = arduino_hal::pins!(dp);
283/// let serial = arduino_hal::default_serial!(dp, pins, 57600);
284/// ```
285///
286/// This is equivalent to manually configuring the driver:
287///
288/// ```no_run
289/// let dp = arduino_hal::Peripherals::take().unwrap();
290/// let pins = arduino_hal::pins!(dp);
291/// let serial = arduino_hal::Usart::new(
292///     dp.USART1,
293///     pins.d0,
294///     pins.d1.into_output(),
295///     // See src/usart.rs for why some boards use the BaudrateArduinoExt trait
296///     // instead of BaudrateExt.
297///     arduino_hal::hal::usart::BaudrateArduinoExt::into_baudrate(57600),
298/// );
299/// ```
300#[cfg(any(
301    feature = "arduino-diecimila",
302    feature = "arduino-mega2560",
303    feature = "arduino-mega1280",
304    feature = "arduino-uno"
305))]
306#[macro_export]
307macro_rules! default_serial {
308    ($p:expr, $pins:expr, $baud:expr) => {
309        $crate::Usart::new(
310            $p.USART0,
311            $pins.d0,
312            $pins.d1.into_output(),
313            // See comment in avr-hal-generic/src/usart.rs for why these boards use the
314            // BaudrateArduinoExt trait instead of BaudrateExt
315            $crate::hal::usart::BaudrateArduinoExt::into_baudrate($baud),
316        )
317    };
318}
319
320/// Convenience macro to instantiate the [`Usart`] driver for this board.
321///
322/// # Example
323/// ```no_run
324/// let dp = arduino_hal::Peripherals::take().unwrap();
325/// let pins = arduino_hal::pins!(dp);
326/// let serial = arduino_hal::default_serial!(dp, pins, 57600);
327/// ```
328#[cfg(any(
329    feature = "arduino-nano",
330    feature = "nano168",
331    feature = "sparkfun-promini-3v3",
332    feature = "sparkfun-promini-5v",
333))]
334#[macro_export]
335macro_rules! default_serial {
336    ($p:expr, $pins:expr, $baud:expr) => {
337        $crate::Usart::new(
338            $p.USART0,
339            $pins.d0,
340            $pins.d1.into_output(),
341            $crate::hal::usart::BaudrateExt::into_baudrate($baud),
342        )
343    };
344}