From 06778a61f70d01a80c37b93e585896227bdda065 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20S=C3=A1nchez=20Ortega?= Date: Sun, 18 Aug 2024 04:29:46 +0200 Subject: [PATCH 1/3] Docstrings for GPIO/PinDriver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Iván Sánchez Ortega --- src/gpio.rs | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/gpio.rs b/src/gpio.rs index d5a45fd3daf..2454ebeecfd 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -1,4 +1,39 @@ //! GPIO and pin configuration +//! +//! Interface for the input/output pins. +//! +//! `Gpio1` through `Gpio39` represent the *physical* pins of the ESP chip. +//! +//! *Logical* pins (compatible with `embedded_hal::digital::InputPin`/`OutputPin`) +//! are implemented through `PinDriver`. +//! +//! 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 +//! SPI RAM and the SPI Flash. +//! +//! # 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); +//! +//! // 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(); +//! ``` use core::marker::PhantomData; From b4cf109211dfd6b45c7e9197562d237cd6e34ec3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20S=C3=A1nchez=20Ortega?= Date: Tue, 20 Aug 2024 18:15:18 +0200 Subject: [PATCH 2/3] Update GPIO docstrings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Iván Sánchez Ortega --- src/gpio.rs | 52 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/src/gpio.rs b/src/gpio.rs index 2454ebeecfd..4b55c3d35f5 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -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 +//! 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 +//! (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 @@ -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; From 2468152bc6d0fdd7cbff0e757ef976d2493a90dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20S=C3=A1nchez=20Ortega?= Date: Tue, 20 Aug 2024 20:30:48 +0200 Subject: [PATCH 3/3] Rewording docstrings for GPIO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Iván Sánchez Ortega --- src/gpio.rs | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/gpio.rs b/src/gpio.rs index 4b55c3d35f5..0484408846c 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -2,7 +2,7 @@ //! //! Interface for the input/output pins. //! -//! `Gpio1` through `GpioNN` represent the pin peripherals of the ESP chip. You +//! `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 @@ -11,16 +11,12 @@ //! //! 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 -//! (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. +//! function (i.e. GPIO, I2C, SPI, ADC, etc). //! +//! Reusing a pin for several functions is possible but should be avoided (since +//! 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 -//! SPI RAM and the SPI Flash. +//! 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. @@ -2068,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,