From bbc3e49c585a2bf58091add9aeac3628d9044297 Mon Sep 17 00:00:00 2001 From: erwin Date: Mon, 18 Aug 2025 12:16:30 +0200 Subject: Add configurable internal pullups for rp i2c - Example updated to demonstrate enabling internal pullups - Add `sda_pullup` and `scl_pullup` fields to I2C Config --- embassy-rp/src/i2c.rs | 26 +++++++++++++++++++------- embassy-rp/src/i2c_slave.rs | 16 ++++++++++++++-- examples/rp/src/bin/i2c_blocking.rs | 6 +++++- 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/embassy-rp/src/i2c.rs b/embassy-rp/src/i2c.rs index 172193a07..089c2d080 100644 --- a/embassy-rp/src/i2c.rs +++ b/embassy-rp/src/i2c.rs @@ -64,14 +64,26 @@ pub enum ConfigError { pub struct Config { /// Frequency. pub frequency: u32, + /// Enable internal pullup on SDA. + /// + /// Using external pullup resistors is recommended for I2C. If you do + /// have external pullups you should not enable this. + pub sda_pullup: bool, + /// Enable internal pullup on SCL. + /// + /// Using external pullup resistors is recommended for I2C. If you do + /// have external pullups you should not enable this. + pub scl_pullup: bool, } - impl Default for Config { fn default() -> Self { - Self { frequency: 100_000 } + Self { + frequency: 100_000, + sda_pullup: false, + scl_pullup: false, + } } } - /// Size of I2C FIFO. pub const FIFO_SIZE: u8 = 16; @@ -359,7 +371,7 @@ impl interrupt::typelevel::Handler for InterruptHandl } } -pub(crate) fn set_up_i2c_pin(pin: &P) +pub(crate) fn set_up_i2c_pin(pin: &P, pullup: bool) where P: core::ops::Deref, T: crate::gpio::Pin, @@ -372,7 +384,7 @@ where w.set_slewfast(false); w.set_ie(true); w.set_od(false); - w.set_pue(true); + w.set_pue(pullup); w.set_pde(false); }); } @@ -384,8 +396,8 @@ impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> { crate::reset::unreset_wait(reset); // Configure SCL & SDA pins - set_up_i2c_pin(&scl); - set_up_i2c_pin(&sda); + set_up_i2c_pin(&scl, config.scl_pullup); + set_up_i2c_pin(&sda, config.sda_pullup); let mut me = Self { phantom: PhantomData }; diff --git a/embassy-rp/src/i2c_slave.rs b/embassy-rp/src/i2c_slave.rs index 7bc14511d..bfee0c45b 100644 --- a/embassy-rp/src/i2c_slave.rs +++ b/embassy-rp/src/i2c_slave.rs @@ -65,6 +65,16 @@ pub struct Config { pub addr: u16, /// Control if the peripheral should ack to and report general calls. pub general_call: bool, + /// Enable internal pullup on SDA. + /// + /// Using external pullup resistors is recommended for I2C. If you do + /// have external pullups you should not enable this. + pub sda_pullup: bool, + /// Enable internal pullup on SCL. + /// + /// Using external pullup resistors is recommended for I2C. If you do + /// have external pullups you should not enable this. + pub scl_pullup: bool, } impl Default for Config { @@ -72,6 +82,8 @@ impl Default for Config { Self { addr: 0x55, general_call: true, + sda_pullup: false, + scl_pullup: false, } } } @@ -95,8 +107,8 @@ impl<'d, T: Instance> I2cSlave<'d, T> { assert!(config.addr != 0); // Configure SCL & SDA pins - set_up_i2c_pin(&scl); - set_up_i2c_pin(&sda); + set_up_i2c_pin(&scl, config.scl_pullup); + set_up_i2c_pin(&sda, config.sda_pullup); let mut ret = Self { phantom: PhantomData, diff --git a/examples/rp/src/bin/i2c_blocking.rs b/examples/rp/src/bin/i2c_blocking.rs index c9c8a2760..6a57ded20 100644 --- a/examples/rp/src/bin/i2c_blocking.rs +++ b/examples/rp/src/bin/i2c_blocking.rs @@ -49,7 +49,11 @@ async fn main(_spawner: Spawner) { let scl = p.PIN_15; info!("set up i2c "); - let mut i2c = i2c::I2c::new_blocking(p.I2C1, scl, sda, Config::default()); + let mut config = Config::default(); + // by default internal pullup resitors are disabled + config.sda_pullup = true; + config.scl_pullup = true; + let mut i2c = i2c::I2c::new_blocking(p.I2C1, scl, sda, config); use mcp23017::*; -- cgit From e2794a270679bae2b070b034b286aa20cbab263a Mon Sep 17 00:00:00 2001 From: erwin Date: Mon, 18 Aug 2025 14:47:46 +0200 Subject: add entry to the changelog --- embassy-rp/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/embassy-rp/CHANGELOG.md b/embassy-rp/CHANGELOG.md index c5bc55941..5482f277f 100644 --- a/embassy-rp/CHANGELOG.md +++ b/embassy-rp/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased - ReleaseDate +- add `i2c` internal pullup options ([#4564](https://github.com/embassy-rs/embassy/pull/4564)) ## 0.7.0 - 2025-08-04 -- cgit From badcdcc24c223954b3fd828ecd925e225e850d29 Mon Sep 17 00:00:00 2001 From: erwin Date: Tue, 19 Aug 2025 12:14:48 +0200 Subject: change default internal pullup state to be active to make this change nonbreaking --- embassy-rp/src/i2c.rs | 4 ++-- embassy-rp/src/i2c_slave.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/embassy-rp/src/i2c.rs b/embassy-rp/src/i2c.rs index 089c2d080..ffbef63be 100644 --- a/embassy-rp/src/i2c.rs +++ b/embassy-rp/src/i2c.rs @@ -79,8 +79,8 @@ impl Default for Config { fn default() -> Self { Self { frequency: 100_000, - sda_pullup: false, - scl_pullup: false, + sda_pullup: true, + scl_pullup: true, } } } diff --git a/embassy-rp/src/i2c_slave.rs b/embassy-rp/src/i2c_slave.rs index bfee0c45b..c263047ad 100644 --- a/embassy-rp/src/i2c_slave.rs +++ b/embassy-rp/src/i2c_slave.rs @@ -82,8 +82,8 @@ impl Default for Config { Self { addr: 0x55, general_call: true, - sda_pullup: false, - scl_pullup: false, + sda_pullup: true, + scl_pullup: true, } } } -- cgit