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.
This commit is contained in:
Jonathan Dickinson 2023-10-10 20:14:09 -04:00
parent 233aa1b53a
commit 3ec4e6320a
No known key found for this signature in database
2 changed files with 23 additions and 36 deletions

View File

@ -6,7 +6,6 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use pac::i2c; use pac::i2c;
use crate::gpio::sealed::Pin;
use crate::gpio::AnyPin; use crate::gpio::AnyPin;
use crate::interrupt::typelevel::{Binding, Interrupt}; use crate::interrupt::typelevel::{Binding, Interrupt};
use crate::{interrupt, pac, peripherals, Peripheral}; use crate::{interrupt, pac, peripherals, Peripheral};
@ -318,6 +317,22 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
} }
} }
pub(crate) fn set_up_i2c_pin<'d, P, T>(pin: &P)
where
P: core::ops::Deref<Target = T>,
T: crate::gpio::Pin,
{
pin.gpio().ctrl().write(|w| w.set_funcsel(3));
pin.pad_ctrl().write(|w| {
w.set_schmitt(true);
w.set_slewfast(false);
w.set_ie(true);
w.set_od(false);
w.set_pue(true);
w.set_pde(false);
});
}
impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> { impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> {
fn new_inner( fn new_inner(
_peri: impl Peripheral<P = T> + 'd, _peri: impl Peripheral<P = T> + 'd,
@ -355,23 +370,8 @@ impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> {
p.ic_rx_tl().write(|w| w.set_rx_tl(0)); p.ic_rx_tl().write(|w| w.set_rx_tl(0));
// Configure SCL & SDA pins // Configure SCL & SDA pins
scl.gpio().ctrl().write(|w| w.set_funcsel(3)); set_up_i2c_pin(&scl);
sda.gpio().ctrl().write(|w| w.set_funcsel(3)); set_up_i2c_pin(&sda);
scl.pad_ctrl().write(|w| {
w.set_schmitt(true);
w.set_ie(true);
w.set_od(false);
w.set_pue(true);
w.set_pde(false);
});
sda.pad_ctrl().write(|w| {
w.set_schmitt(true);
w.set_ie(true);
w.set_od(false);
w.set_pue(true);
w.set_pde(false);
});
// Configure baudrate // Configure baudrate

View File

@ -5,7 +5,9 @@ use core::task::Poll;
use embassy_hal_internal::into_ref; use embassy_hal_internal::into_ref;
use pac::i2c; use pac::i2c;
use crate::i2c::{i2c_reserved_addr, AbortReason, Instance, InterruptHandler, SclPin, SdaPin, FIFO_SIZE}; use crate::i2c::{
i2c_reserved_addr, set_up_i2c_pin, AbortReason, Instance, InterruptHandler, SclPin, SdaPin, FIFO_SIZE,
};
use crate::interrupt::typelevel::{Binding, Interrupt}; use crate::interrupt::typelevel::{Binding, Interrupt};
use crate::{pac, Peripheral}; use crate::{pac, Peripheral};
@ -100,23 +102,8 @@ impl<'d, T: Instance> I2cSlave<'d, T> {
p.ic_rx_tl().write(|w| w.set_rx_tl(0)); p.ic_rx_tl().write(|w| w.set_rx_tl(0));
// Configure SCL & SDA pins // Configure SCL & SDA pins
scl.gpio().ctrl().write(|w| w.set_funcsel(3)); set_up_i2c_pin(&scl);
sda.gpio().ctrl().write(|w| w.set_funcsel(3)); set_up_i2c_pin(&sda);
scl.pad_ctrl().write(|w| {
w.set_schmitt(true);
w.set_ie(true);
w.set_od(false);
w.set_pue(true);
w.set_pde(false);
});
sda.pad_ctrl().write(|w| {
w.set_schmitt(true);
w.set_ie(true);
w.set_od(false);
w.set_pue(true);
w.set_pde(false);
});
// Clear interrupts // Clear interrupts
p.ic_clr_intr().read(); p.ic_clr_intr().read();