aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Munns <[email protected]>2025-08-19 15:04:26 +0000
committerGitHub <[email protected]>2025-08-19 15:04:26 +0000
commit6433d7bf397b8cb28941c5ba3d07ac097852b565 (patch)
tree0eb9b2eb39940f38986d0798034b2f0f2744b6bf
parent61dbd89bd4648cc6b16017bbbf4db8f5fdcb109a (diff)
parentbadcdcc24c223954b3fd828ecd925e225e850d29 (diff)
Merge pull request #4564 from erwin-ps/feature/rp-i2c-add-pullup-config
Add configurable internal pullups for rp i2c
-rw-r--r--embassy-rp/CHANGELOG.md1
-rw-r--r--embassy-rp/src/i2c.rs26
-rw-r--r--embassy-rp/src/i2c_slave.rs16
-rw-r--r--examples/rp/src/bin/i2c_blocking.rs6
4 files changed, 39 insertions, 10 deletions
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
7 7
8<!-- next-header --> 8<!-- next-header -->
9## Unreleased - ReleaseDate 9## Unreleased - ReleaseDate
10- add `i2c` internal pullup options ([#4564](https://github.com/embassy-rs/embassy/pull/4564))
10 11
11## 0.7.0 - 2025-08-04 12## 0.7.0 - 2025-08-04
12 13
diff --git a/embassy-rp/src/i2c.rs b/embassy-rp/src/i2c.rs
index 172193a07..ffbef63be 100644
--- a/embassy-rp/src/i2c.rs
+++ b/embassy-rp/src/i2c.rs
@@ -64,14 +64,26 @@ pub enum ConfigError {
64pub struct Config { 64pub struct Config {
65 /// Frequency. 65 /// Frequency.
66 pub frequency: u32, 66 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,
67} 77}
68
69impl Default for Config { 78impl Default for Config {
70 fn default() -> Self { 79 fn default() -> Self {
71 Self { frequency: 100_000 } 80 Self {
81 frequency: 100_000,
82 sda_pullup: true,
83 scl_pullup: true,
84 }
72 } 85 }
73} 86}
74
75/// Size of I2C FIFO. 87/// Size of I2C FIFO.
76pub const FIFO_SIZE: u8 = 16; 88pub const FIFO_SIZE: u8 = 16;
77 89
@@ -359,7 +371,7 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
359 } 371 }
360} 372}
361 373
362pub(crate) fn set_up_i2c_pin<P, T>(pin: &P) 374pub(crate) fn set_up_i2c_pin<P, T>(pin: &P, pullup: bool)
363where 375where
364 P: core::ops::Deref<Target = T>, 376 P: core::ops::Deref<Target = T>,
365 T: crate::gpio::Pin, 377 T: crate::gpio::Pin,
@@ -372,7 +384,7 @@ where
372 w.set_slewfast(false); 384 w.set_slewfast(false);
373 w.set_ie(true); 385 w.set_ie(true);
374 w.set_od(false); 386 w.set_od(false);
375 w.set_pue(true); 387 w.set_pue(pullup);
376 w.set_pde(false); 388 w.set_pde(false);
377 }); 389 });
378} 390}
@@ -384,8 +396,8 @@ impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> {
384 crate::reset::unreset_wait(reset); 396 crate::reset::unreset_wait(reset);
385 397
386 // Configure SCL & SDA pins 398 // Configure SCL & SDA pins
387 set_up_i2c_pin(&scl); 399 set_up_i2c_pin(&scl, config.scl_pullup);
388 set_up_i2c_pin(&sda); 400 set_up_i2c_pin(&sda, config.sda_pullup);
389 401
390 let mut me = Self { phantom: PhantomData }; 402 let mut me = Self { phantom: PhantomData };
391 403
diff --git a/embassy-rp/src/i2c_slave.rs b/embassy-rp/src/i2c_slave.rs
index 7bc14511d..c263047ad 100644
--- a/embassy-rp/src/i2c_slave.rs
+++ b/embassy-rp/src/i2c_slave.rs
@@ -65,6 +65,16 @@ pub struct Config {
65 pub addr: u16, 65 pub addr: u16,
66 /// Control if the peripheral should ack to and report general calls. 66 /// Control if the peripheral should ack to and report general calls.
67 pub general_call: bool, 67 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,
68} 78}
69 79
70impl Default for Config { 80impl Default for Config {
@@ -72,6 +82,8 @@ impl Default for Config {
72 Self { 82 Self {
73 addr: 0x55, 83 addr: 0x55,
74 general_call: true, 84 general_call: true,
85 sda_pullup: true,
86 scl_pullup: true,
75 } 87 }
76 } 88 }
77} 89}
@@ -95,8 +107,8 @@ impl<'d, T: Instance> I2cSlave<'d, T> {
95 assert!(config.addr != 0); 107 assert!(config.addr != 0);
96 108
97 // Configure SCL & SDA pins 109 // Configure SCL & SDA pins
98 set_up_i2c_pin(&scl); 110 set_up_i2c_pin(&scl, config.scl_pullup);
99 set_up_i2c_pin(&sda); 111 set_up_i2c_pin(&sda, config.sda_pullup);
100 112
101 let mut ret = Self { 113 let mut ret = Self {
102 phantom: PhantomData, 114 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) {
49 let scl = p.PIN_15; 49 let scl = p.PIN_15;
50 50
51 info!("set up i2c "); 51 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);
53 57
54 use mcp23017::*; 58 use mcp23017::*;
55 59