#![cfg_attr(docsrs, procmacros::doc_replace(
"sda" => {
cfg(lp_i2c_master_version = "rtc_i2c") => gpio_for_signal!(SAR_I2C_SDA_0),
_ => gpio_for_signal!(LP_I2C_SDA, "GPIO6")
},
"scl" => {
cfg(lp_i2c_master_version = "rtc_i2c") => gpio_for_signal!(SAR_I2C_SCL_1),
_ => gpio_for_signal!(LP_I2C_SCL, "GPIO7")
}
))]
use crate::{
gpio::{InputPin, LpPin, OutputPin},
peripherals::LP_I2C0,
};
#[cfg_attr(lp_i2c_master_version = "lp_i2c", path = "lp_i2c.rs")]
#[cfg_attr(lp_i2c_master_version = "rtc_i2c", path = "rtc_i2c.rs")]
mod driver;
pub use driver::*;
pub trait Sda: LpPin + OutputPin + InputPin {
#[doc(hidden)]
fn connect_sda(&self);
}
pub trait Scl: LpPin + OutputPin + InputPin {
#[doc(hidden)]
fn connect_scl(&self);
}
#[cfg(lp_io_has_gpio_matrix)]
for_each_lp_function! {
(($_signal:ident, LP_GPIOn, $_pin:literal), $gpio:ident, $_af:ident, $_lp_in:tt $_lp_out:tt) => {
impl Sda for crate::peripherals::$gpio<'_> {
fn connect_sda(&self) {
crate::gpio::lp_io::connect_open_drain_signals(
self,
crate::gpio::lp_io::LpInputSignal::LP_I2C_SDA,
crate::gpio::lp_io::LpOutputSignal::LP_I2C_SDA,
);
}
}
impl Scl for crate::peripherals::$gpio<'_> {
fn connect_scl(&self) {
crate::gpio::lp_io::connect_open_drain_signals(
self,
crate::gpio::lp_io::LpInputSignal::LP_I2C_SCL,
crate::gpio::lp_io::LpOutputSignal::LP_I2C_SCL,
);
}
}
};
}
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Error {
TransactionSizeLimitExceeded,
AckCheckFailed,
TimeOut,
ArbitrationLost,
}
#[procmacros::doc_replace(
"sda" => {
cfg(lp_i2c_master_version = "rtc_i2c") => gpio_for_signal!(SAR_I2C_SDA_0),
_ => gpio_for_signal!(LP_I2C_SDA, "GPIO6")
},
"scl" => {
cfg(lp_i2c_master_version = "rtc_i2c") => gpio_for_signal!(SAR_I2C_SCL_1),
_ => gpio_for_signal!(LP_I2C_SCL, "GPIO7")
}
)]
pub struct LpI2c<'d> {
i2c: LP_I2C0<'d>,
sda: u8,
scl: u8,
}
impl<'d> LpI2c<'d> {
#[procmacros::doc_replace(
"sda" => {
cfg(lp_i2c_master_version = "rtc_i2c") => gpio_for_signal!(SAR_I2C_SDA_0),
_ => gpio_for_signal!(LP_I2C_SDA, "GPIO6")
},
"scl" => {
cfg(lp_i2c_master_version = "rtc_i2c") => gpio_for_signal!(SAR_I2C_SCL_1),
_ => gpio_for_signal!(LP_I2C_SCL, "GPIO7")
}
)]
pub fn new(
i2c: LP_I2C0<'d>,
config: Config,
sda: impl Sda + 'd,
scl: impl Scl + 'd,
) -> Result<Self, ConfigError> {
let mut me = Self {
i2c,
sda: sda.lp_number(),
scl: scl.lp_number(),
};
me.init();
scl.connect_scl();
sda.connect_sda();
me.apply_config(&config)?;
Ok(me)
}
#[procmacros::doc_replace(
"sda" => {
cfg(lp_i2c_master_version = "rtc_i2c") => gpio_for_signal!(SAR_I2C_SDA_0),
_ => gpio_for_signal!(LP_I2C_SDA, "GPIO6")
},
"scl" => {
cfg(lp_i2c_master_version = "rtc_i2c") => gpio_for_signal!(SAR_I2C_SCL_1),
_ => gpio_for_signal!(LP_I2C_SCL, "GPIO7")
}
)]
pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
self.configure(config)
}
#[procmacros::doc_replace(
"sda" => {
cfg(lp_i2c_master_version = "rtc_i2c") => gpio_for_signal!(SAR_I2C_SDA_0),
_ => gpio_for_signal!(LP_I2C_SDA, "GPIO6")
},
"scl" => {
cfg(lp_i2c_master_version = "rtc_i2c") => gpio_for_signal!(SAR_I2C_SCL_1),
_ => gpio_for_signal!(LP_I2C_SCL, "GPIO7")
}
)]
pub fn write(&mut self, address: u8, register: u8, data: &[u8]) -> Result<(), Error> {
self.write_bytes(address, register, data)
}
#[procmacros::doc_replace(
"sda" => {
cfg(lp_i2c_master_version = "rtc_i2c") => gpio_for_signal!(SAR_I2C_SDA_0),
_ => gpio_for_signal!(LP_I2C_SDA, "GPIO6")
},
"scl" => {
cfg(lp_i2c_master_version = "rtc_i2c") => gpio_for_signal!(SAR_I2C_SCL_1),
_ => gpio_for_signal!(LP_I2C_SCL, "GPIO7")
}
)]
pub fn read(&mut self, address: u8, register: u8, data: &mut [u8]) -> Result<(), Error> {
self.read_bytes(address, register, data)
}
}
impl Drop for LpI2c<'_> {
fn drop(&mut self) {
self.disable();
crate::gpio::lp_io::reset_pin(self.sda);
crate::gpio::lp_io::reset_pin(self.scl);
}
}