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 1 commit
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
52 changes: 41 additions & 11 deletions src/gpio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,29 @@
//!
//! Interface for the input/output pins.
//!
//! `Gpio1` through `Gpio39` represent the *physical* pins of the ESP chip.
//! `Gpio1` through `GpioNN` represent the pin peripherals of the ESP chip. You
Copy link
Collaborator

@Vollbrecht Vollbrecht Aug 20, 2024

Choose a reason for hiding this comment

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

Nitpick: gpio's start at gpio0

//! may think of pin peripherals as *physical* pins.
//!
//! *Logical* pins (compatible with `embedded_hal::digital::InputPin`/`OutputPin`)
//! are implemented through `PinDriver`.
//! 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, which means that (almost) any
//! physical pin can be used for any logical function (i.e. GPIO, I2C, SPI, ADC, etc).
//! Even though it's possible to use a pin for several functions at once, this
//! should be avoided. This is particularly important with the pins used for the
//! 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). Even though it's possible to
//! use a pin for several functions at once, this should be avoided. In
//! practice, `esp-idf-hal` should prevent most instances of pin reuse.
//!
//! If you *really* need to mux I/O pins, you might need to drop any function
Copy link
Collaborator

@Vollbrecht Vollbrecht Aug 20, 2024

Choose a reason for hiding this comment

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

I think this part would be confusing for people as it doesn't cleary describe what you mean here.

For example most of our logical drivers accept also pin references. E.g you can give a PinDriver a &mut gpio0 and if you drop the PinDriver you still have access to gpio0 instance. No need for fancy Mutex etc.

    let mut foo = per.pins.gpio0;

   let driver = PinDriver::input(&mut foo);
   drop(driver);
   let driver2 = PinDriver::input(&mut foo);

//! (GPIO, I2C, etc) that's using a pin before using it for any other purpose,
//! and use appropriate measures (e.g. `std::sync::Mutex`) to avoid conflicts.
//!
//! Avoiding pin reuse is particularly important with the pins used for the
//! 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
Expand All @@ -28,11 +40,29 @@
//!
//! // 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);
//!
//! // The logical pin implements some embedded_hal traits, so it can
//! // be used in crates that rely on those traits, e.g.:
//! use one_wire_bus::OneWire;
//! let bus = OneWire::new(logical_pin_2).unwrap();
//! let display = TM1637::builder(clk, dio, delay_provider).build();
//! ```

use core::marker::PhantomData;
Expand Down
Loading