diff options
| author | Jonathan Dickinson <[email protected]> | 2023-10-10 20:14:09 -0400 |
|---|---|---|
| committer | Jonathan Dickinson <[email protected]> | 2023-10-10 20:14:09 -0400 |
| commit | 3ec4e6320a3e9f7723a91e727004a35c3c903765 (patch) | |
| tree | d094a6caf1b5ac8becbcc067efe4deb52394c4df | |
| parent | 233aa1b53a91ea0696d879ca86d72026c029c691 (diff) | |
fix (rp i2c): set i2c slew rate to spec value
The RP2040 datasheet indicates that I2C pins should have a limited
slew rate (Page 440 - 4.3.1.3.). This configures that for both
`I2c` and `I2cSlave`.
In addition, the pin configuration has been centralized to a single
fn.
| -rw-r--r-- | embassy-rp/src/i2c.rs | 36 | ||||
| -rw-r--r-- | embassy-rp/src/i2c_slave.rs | 23 |
2 files changed, 23 insertions, 36 deletions
diff --git a/embassy-rp/src/i2c.rs b/embassy-rp/src/i2c.rs index 77777ad30..b4036f207 100644 --- a/embassy-rp/src/i2c.rs +++ b/embassy-rp/src/i2c.rs | |||
| @@ -6,7 +6,6 @@ use embassy_hal_internal::{into_ref, PeripheralRef}; | |||
| 6 | use embassy_sync::waitqueue::AtomicWaker; | 6 | use embassy_sync::waitqueue::AtomicWaker; |
| 7 | use pac::i2c; | 7 | use pac::i2c; |
| 8 | 8 | ||
| 9 | use crate::gpio::sealed::Pin; | ||
| 10 | use crate::gpio::AnyPin; | 9 | use crate::gpio::AnyPin; |
| 11 | use crate::interrupt::typelevel::{Binding, Interrupt}; | 10 | use crate::interrupt::typelevel::{Binding, Interrupt}; |
| 12 | use crate::{interrupt, pac, peripherals, Peripheral}; | 11 | use crate::{interrupt, pac, peripherals, Peripheral}; |
| @@ -318,6 +317,22 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 318 | } | 317 | } |
| 319 | } | 318 | } |
| 320 | 319 | ||
| 320 | pub(crate) fn set_up_i2c_pin<'d, P, T>(pin: &P) | ||
| 321 | where | ||
| 322 | P: core::ops::Deref<Target = T>, | ||
| 323 | T: crate::gpio::Pin, | ||
| 324 | { | ||
| 325 | pin.gpio().ctrl().write(|w| w.set_funcsel(3)); | ||
| 326 | pin.pad_ctrl().write(|w| { | ||
| 327 | w.set_schmitt(true); | ||
| 328 | w.set_slewfast(false); | ||
| 329 | w.set_ie(true); | ||
| 330 | w.set_od(false); | ||
| 331 | w.set_pue(true); | ||
| 332 | w.set_pde(false); | ||
| 333 | }); | ||
| 334 | } | ||
| 335 | |||
| 321 | impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> { | 336 | impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> { |
| 322 | fn new_inner( | 337 | fn new_inner( |
| 323 | _peri: impl Peripheral<P = T> + 'd, | 338 | _peri: impl Peripheral<P = T> + 'd, |
| @@ -355,23 +370,8 @@ impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> { | |||
| 355 | p.ic_rx_tl().write(|w| w.set_rx_tl(0)); | 370 | p.ic_rx_tl().write(|w| w.set_rx_tl(0)); |
| 356 | 371 | ||
| 357 | // Configure SCL & SDA pins | 372 | // Configure SCL & SDA pins |
| 358 | scl.gpio().ctrl().write(|w| w.set_funcsel(3)); | 373 | set_up_i2c_pin(&scl); |
| 359 | sda.gpio().ctrl().write(|w| w.set_funcsel(3)); | 374 | set_up_i2c_pin(&sda); |
| 360 | |||
| 361 | scl.pad_ctrl().write(|w| { | ||
| 362 | w.set_schmitt(true); | ||
| 363 | w.set_ie(true); | ||
| 364 | w.set_od(false); | ||
| 365 | w.set_pue(true); | ||
| 366 | w.set_pde(false); | ||
| 367 | }); | ||
| 368 | sda.pad_ctrl().write(|w| { | ||
| 369 | w.set_schmitt(true); | ||
| 370 | w.set_ie(true); | ||
| 371 | w.set_od(false); | ||
| 372 | w.set_pue(true); | ||
| 373 | w.set_pde(false); | ||
| 374 | }); | ||
| 375 | 375 | ||
| 376 | // Configure baudrate | 376 | // Configure baudrate |
| 377 | 377 | ||
diff --git a/embassy-rp/src/i2c_slave.rs b/embassy-rp/src/i2c_slave.rs index 30e789259..9271ede3a 100644 --- a/embassy-rp/src/i2c_slave.rs +++ b/embassy-rp/src/i2c_slave.rs | |||
| @@ -5,7 +5,9 @@ use core::task::Poll; | |||
| 5 | use embassy_hal_internal::into_ref; | 5 | use embassy_hal_internal::into_ref; |
| 6 | use pac::i2c; | 6 | use pac::i2c; |
| 7 | 7 | ||
| 8 | use crate::i2c::{i2c_reserved_addr, AbortReason, Instance, InterruptHandler, SclPin, SdaPin, FIFO_SIZE}; | 8 | use crate::i2c::{ |
| 9 | i2c_reserved_addr, set_up_i2c_pin, AbortReason, Instance, InterruptHandler, SclPin, SdaPin, FIFO_SIZE, | ||
| 10 | }; | ||
| 9 | use crate::interrupt::typelevel::{Binding, Interrupt}; | 11 | use crate::interrupt::typelevel::{Binding, Interrupt}; |
| 10 | use crate::{pac, Peripheral}; | 12 | use crate::{pac, Peripheral}; |
| 11 | 13 | ||
| @@ -100,23 +102,8 @@ impl<'d, T: Instance> I2cSlave<'d, T> { | |||
| 100 | p.ic_rx_tl().write(|w| w.set_rx_tl(0)); | 102 | p.ic_rx_tl().write(|w| w.set_rx_tl(0)); |
| 101 | 103 | ||
| 102 | // Configure SCL & SDA pins | 104 | // Configure SCL & SDA pins |
| 103 | scl.gpio().ctrl().write(|w| w.set_funcsel(3)); | 105 | set_up_i2c_pin(&scl); |
| 104 | sda.gpio().ctrl().write(|w| w.set_funcsel(3)); | 106 | set_up_i2c_pin(&sda); |
| 105 | |||
| 106 | scl.pad_ctrl().write(|w| { | ||
| 107 | w.set_schmitt(true); | ||
| 108 | w.set_ie(true); | ||
| 109 | w.set_od(false); | ||
| 110 | w.set_pue(true); | ||
| 111 | w.set_pde(false); | ||
| 112 | }); | ||
| 113 | sda.pad_ctrl().write(|w| { | ||
| 114 | w.set_schmitt(true); | ||
| 115 | w.set_ie(true); | ||
| 116 | w.set_od(false); | ||
| 117 | w.set_pue(true); | ||
| 118 | w.set_pde(false); | ||
| 119 | }); | ||
| 120 | 107 | ||
| 121 | // Clear interrupts | 108 | // Clear interrupts |
| 122 | p.ic_clr_intr().read(); | 109 | p.ic_clr_intr().read(); |
