Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docstrings for GPIO/PinDriver #473

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions src/gpio.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,65 @@
//! GPIO and pin configuration
//!
//! Interface for the input/output pins.
//!
//! `Gpio0` through `GpioNN` represent the pin peripherals of the ESP chip. You
//! may think of pin peripherals as *physical* pins.
//!
//! Pin drivers are implemented through `PinDriver`. You may think of pin drivers as
//! *logical* I/O pins. They implement the [`embedded_hal::digital::InputPin`](https://docs.rs/embedded-hal/latest/embedded_hal/digital/trait.InputPin.html)/[`OutputPin`](https://docs.rs/embedded-hal/latest/embedded_hal/digital/trait.OutputPin.html)
//! traits, as well as their [`embedded_hal_async`](https://docs.rs/embedded-hal-async/latest/embedded_hal_async/) counterparts.
//!
//! The ESP architecture has a [I/O multiplexer](https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf#iomuxgpio),
//! which means that (almost) any physical pin can be used for any logical
//! function (i.e. GPIO, I2C, SPI, ADC, etc).
//!
//! Reusing a pin for several functions is possible but should be avoided (since
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this paragraph is not a correct statement. The type system makes sure that if you for example are giving out `&mut gpio0) than it will check it for you. So in that sense we do this complete shenanigans (compared to the underlying C api where you just give for example an arbitrary int number) so the user don't need to be careful here at all and nothing of that sort is discouraged . The compiler has you here!

And sorry for the delay i think otherwise everything is fine and we should merge it then.

//! reusing a pin requires the programmer to be more careful about its usage).
//! Avoiding pin reuse is particularly important with the pins used for the
//! integrated SPI RAM and the SPI Flash.
//!
//! Each physical architecture (ESP32, ESP32C3, ESP32H2, etc) has a different set
//! of pins; check the documentation for your model.
//!
//! # Examples
//!
//! Create a logical input/output pin on physical pin 2
//! ```
//! use esp_idf_hal::peripherals::Peripherals;
//! use esp_idf_hal::gpio:PinDriver;
//! use esp_idf_hal::gpio:Level;
//!
//! let physical_pin_2 = Peripherals::take().unwrap().pins.gpio2;
//!
//! // Set pin to input/output and open drain
//! let logical_pin_2 = PinDriver::input_output_od().unwrap();
//!
//! // Set pin to high
//! logical_pin_2.set_level(Level::High);
//! ```
//!
//! Using (physical) pins for I2C does not require creating (logical) pin drivers:
//! ```
//! let peripherals = esp_idf_hal::peripherals::Peripherals::take()?;
//! let i2c = peripherals.i2c0;
//! let sda = peripherals.pins.gpio5;
//! let scl = peripherals.pins.gpio6;
//!
//! let mut i2c = esp_idf_hal::i2c::I2cDriver::new(i2c, sda, scl, &esp_idf_hal_::i2c::I2cConfig::new())?;
//! ```
//!
//! Since pin drivers implement `embedded_hal` traits, they can be used in
//! crates that use those traits:
//! ```
//! use tm1637_embedded_hal::blocking::TM1637;
//! let peripherals = esp_idf_hal::peripherals::Peripherals::take()?;
//! let delay_provider = esp_idf_hal::delay::Delay::new(50);
//!
//! let dio = PinDriver::input_output_od(peripherals.pins.gpio16);
//! let clk = PinDriver::output(peripherals.pins.gpio17);
//!
//! let display = TM1637::builder(clk, dio, delay_provider).build();
//! ```

use core::marker::PhantomData;

Expand Down Expand Up @@ -2003,6 +2064,19 @@ mod chip {
pin!(Gpio20:20, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0);
pin!(Gpio21:21, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0);

/// The pins in this structure vary depending on your specific physical
/// architecture; for example, an ESP32C2 has pins 0 through 20, whereas
/// an ESP32S3 has pins 0 through 21 and 26 through 48.
///
/// Each pin has different capabilities, and therefore each `gpioN` has a
/// specific type which implements different [traits](https://doc.rust-lang.org/book/ch10-02-traits.html).
/// For example, pin `gpio15` on a ESP32C2 is a `Gpio15` which implements
/// the `AnyInputPin`, `AnyOutputPin` and `AnyIOPin` traits. The same pin
/// `gpio15` on a ESP32S3 is also a `Gpio15`, but it implements the `AnyInputPin`,
/// `AnyOutputPin`, `AnyIOPin`, `ADCPin` and `RTCPin` traits.
///
/// Note that pins here do **not** implement the `embedded_hal` pin traits.
/// Instead, check `esp-idf-hal::gpio`.
pub struct Pins {
pub gpio0: Gpio0,
pub gpio1: Gpio1,
Expand Down
Loading