Skip to content

Commit 6433d7b

Browse files
authored
Merge pull request #4564 from erwin-ps/feature/rp-i2c-add-pullup-config
Add configurable internal pullups for rp i2c
2 parents 61dbd89 + badcdcc commit 6433d7b

File tree

4 files changed

+39
-10
lines changed

4 files changed

+39
-10
lines changed

embassy-rp/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
<!-- next-header -->
99
## Unreleased - ReleaseDate
10+
- add `i2c` internal pullup options ([#4564](https://github.com/embassy-rs/embassy/pull/4564))
1011

1112
## 0.7.0 - 2025-08-04
1213

embassy-rp/src/i2c.rs

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,26 @@ pub enum ConfigError {
6464
pub struct Config {
6565
/// Frequency.
6666
pub frequency: u32,
67+
/// Enable internal pullup on SDA.
68+
///
69+
/// Using external pullup resistors is recommended for I2C. If you do
70+
/// have external pullups you should not enable this.
71+
pub sda_pullup: bool,
72+
/// Enable internal pullup on SCL.
73+
///
74+
/// Using external pullup resistors is recommended for I2C. If you do
75+
/// have external pullups you should not enable this.
76+
pub scl_pullup: bool,
6777
}
68-
6978
impl Default for Config {
7079
fn default() -> Self {
71-
Self { frequency: 100_000 }
80+
Self {
81+
frequency: 100_000,
82+
sda_pullup: true,
83+
scl_pullup: true,
84+
}
7285
}
7386
}
74-
7587
/// Size of I2C FIFO.
7688
pub const FIFO_SIZE: u8 = 16;
7789

@@ -359,7 +371,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
359371
}
360372
}
361373

362-
pub(crate) fn set_up_i2c_pin<P, T>(pin: &P)
374+
pub(crate) fn set_up_i2c_pin<P, T>(pin: &P, pullup: bool)
363375
where
364376
P: core::ops::Deref<Target = T>,
365377
T: crate::gpio::Pin,
@@ -372,7 +384,7 @@ where
372384
w.set_slewfast(false);
373385
w.set_ie(true);
374386
w.set_od(false);
375-
w.set_pue(true);
387+
w.set_pue(pullup);
376388
w.set_pde(false);
377389
});
378390
}
@@ -384,8 +396,8 @@ impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> {
384396
crate::reset::unreset_wait(reset);
385397

386398
// Configure SCL & SDA pins
387-
set_up_i2c_pin(&scl);
388-
set_up_i2c_pin(&sda);
399+
set_up_i2c_pin(&scl, config.scl_pullup);
400+
set_up_i2c_pin(&sda, config.sda_pullup);
389401

390402
let mut me = Self { phantom: PhantomData };
391403

embassy-rp/src/i2c_slave.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,25 @@ pub struct Config {
6565
pub addr: u16,
6666
/// Control if the peripheral should ack to and report general calls.
6767
pub general_call: bool,
68+
/// Enable internal pullup on SDA.
69+
///
70+
/// Using external pullup resistors is recommended for I2C. If you do
71+
/// have external pullups you should not enable this.
72+
pub sda_pullup: bool,
73+
/// Enable internal pullup on SCL.
74+
///
75+
/// Using external pullup resistors is recommended for I2C. If you do
76+
/// have external pullups you should not enable this.
77+
pub scl_pullup: bool,
6878
}
6979

7080
impl Default for Config {
7181
fn default() -> Self {
7282
Self {
7383
addr: 0x55,
7484
general_call: true,
85+
sda_pullup: true,
86+
scl_pullup: true,
7587
}
7688
}
7789
}
@@ -95,8 +107,8 @@ impl<'d, T: Instance> I2cSlave<'d, T> {
95107
assert!(config.addr != 0);
96108

97109
// Configure SCL & SDA pins
98-
set_up_i2c_pin(&scl);
99-
set_up_i2c_pin(&sda);
110+
set_up_i2c_pin(&scl, config.scl_pullup);
111+
set_up_i2c_pin(&sda, config.sda_pullup);
100112

101113
let mut ret = Self {
102114
phantom: PhantomData,

examples/rp/src/bin/i2c_blocking.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,11 @@ async fn main(_spawner: Spawner) {
4949
let scl = p.PIN_15;
5050

5151
info!("set up i2c ");
52-
let mut i2c = i2c::I2c::new_blocking(p.I2C1, scl, sda, Config::default());
52+
let mut config = Config::default();
53+
// by default internal pullup resitors are disabled
54+
config.sda_pullup = true;
55+
config.scl_pullup = true;
56+
let mut i2c = i2c::I2c::new_blocking(p.I2C1, scl, sda, config);
5357

5458
use mcp23017::*;
5559

0 commit comments

Comments
 (0)