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 2 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
65 changes: 65 additions & 0 deletions src/gpio.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,69 @@
//! GPIO and pin configuration
//!
//! Interface for the input/output pins.
//!
//! `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.
//!
//! 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). 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
//! ```
//! 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
Loading