This commit is contained in:
jrmoulton 2024-06-25 14:12:19 -06:00
parent c7b4a076cc
commit d1f5a4c5c7
No known key found for this signature in database
3 changed files with 41 additions and 85 deletions

View File

@ -1,4 +1,6 @@
#[cfg(gpio_v2)]
use crate::gpio::Pull; use crate::gpio::Pull;
use crate::gpio::{AfType, OutputType, Speed};
#[repr(u8)] #[repr(u8)]
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
@ -111,11 +113,13 @@ pub struct Config {
/// ///
/// Using external pullup resistors is recommended for I2C. If you do /// Using external pullup resistors is recommended for I2C. If you do
/// have external pullups you should not enable this. /// have external pullups you should not enable this.
#[cfg(gpio_v2)]
pub sda_pullup: bool, pub sda_pullup: bool,
/// Enable internal pullup on SCL. /// Enable internal pullup on SCL.
/// ///
/// Using external pullup resistors is recommended for I2C. If you do /// Using external pullup resistors is recommended for I2C. If you do
/// have external pullups you should not enable this. /// have external pullups you should not enable this.
#[cfg(gpio_v2)]
pub scl_pullup: bool, pub scl_pullup: bool,
/// Timeout. /// Timeout.
#[cfg(feature = "time")] #[cfg(feature = "time")]
@ -125,7 +129,9 @@ pub struct Config {
impl Default for Config { impl Default for Config {
fn default() -> Self { fn default() -> Self {
Self { Self {
#[cfg(gpio_v2)]
sda_pullup: false, sda_pullup: false,
#[cfg(gpio_v2)]
scl_pullup: false, scl_pullup: false,
#[cfg(feature = "time")] #[cfg(feature = "time")]
timeout: embassy_time::Duration::from_millis(1000), timeout: embassy_time::Duration::from_millis(1000),
@ -134,17 +140,31 @@ impl Default for Config {
} }
impl Config { impl Config {
pub(super) fn scl_pull_mode(&self) -> Pull { pub(super) fn scl_af(&self) -> AfType {
#[cfg(gpio_v1)]
return AfType::output(OutputType::OpenDrain, Speed::Medium);
#[cfg(gpio_v2)]
return AfType::output_pull(
OutputType::OpenDrain,
Speed::Medium,
match self.scl_pullup { match self.scl_pullup {
true => Pull::Up, true => Pull::Up,
false => Pull::Down, false => Pull::Down,
} },
);
} }
pub(super) fn sda_pull_mode(&self) -> Pull { pub(super) fn sda_af(&self) -> AfType {
#[cfg(gpio_v1)]
return AfType::output(OutputType::OpenDrain, Speed::Medium);
#[cfg(gpio_v2)]
return AfType::output_pull(
OutputType::OpenDrain,
Speed::Medium,
match self.sda_pullup { match self.sda_pullup {
true => Pull::Up, true => Pull::Up,
false => Pull::Down, false => Pull::Down,
} },
);
} }
} }

View File

@ -19,9 +19,7 @@ use embassy_time::{Duration, Instant};
use mode::{Master, MasterMode}; use mode::{Master, MasterMode};
use crate::dma::ChannelAndRequest; use crate::dma::ChannelAndRequest;
#[cfg(gpio_v2)] use crate::gpio::{AnyPin, SealedPin as _};
use crate::gpio::Pull;
use crate::gpio::{AfType, AnyPin, OutputType, SealedPin as _, Speed};
use crate::interrupt::typelevel::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::mode::{Async, Blocking, Mode}; use crate::mode::{Async, Blocking, Mode};
use crate::rcc::{RccInfo, SealedRccPeripheral}; use crate::rcc::{RccInfo, SealedRccPeripheral};
@ -48,70 +46,6 @@ pub enum Error {
ZeroLengthTransfer, ZeroLengthTransfer,
} }
/// I2C config
#[non_exhaustive]
#[derive(Copy, Clone)]
pub struct Config {
/// Enable internal pullup on SDA.
///
/// Using external pullup resistors is recommended for I2C. If you do
/// have external pullups you should not enable this.
#[cfg(gpio_v2)]
pub sda_pullup: bool,
/// Enable internal pullup on SCL.
///
/// Using external pullup resistors is recommended for I2C. If you do
/// have external pullups you should not enable this.
#[cfg(gpio_v2)]
pub scl_pullup: bool,
/// Timeout.
#[cfg(feature = "time")]
pub timeout: embassy_time::Duration,
}
impl Default for Config {
fn default() -> Self {
Self {
#[cfg(gpio_v2)]
sda_pullup: false,
#[cfg(gpio_v2)]
scl_pullup: false,
#[cfg(feature = "time")]
timeout: embassy_time::Duration::from_millis(1000),
}
}
}
impl Config {
fn scl_af(&self) -> AfType {
#[cfg(gpio_v1)]
return AfType::output(OutputType::OpenDrain, Speed::Medium);
#[cfg(gpio_v2)]
return AfType::output_pull(
OutputType::OpenDrain,
Speed::Medium,
match self.scl_pullup {
true => Pull::Up,
false => Pull::Down,
},
);
}
fn sda_af(&self) -> AfType {
#[cfg(gpio_v1)]
return AfType::output(OutputType::OpenDrain, Speed::Medium);
#[cfg(gpio_v2)]
return AfType::output_pull(
OutputType::OpenDrain,
Speed::Medium,
match self.sda_pullup {
true => Pull::Up,
false => Pull::Down,
},
);
}
}
/// I2C modes /// I2C modes
pub mod mode { pub mod mode {
trait SealedMode {} trait SealedMode {}
@ -169,8 +103,12 @@ struct I2CDropGuard<'d> {
} }
impl<'d> Drop for I2CDropGuard<'d> { impl<'d> Drop for I2CDropGuard<'d> {
fn drop(&mut self) { fn drop(&mut self) {
self.scl.as_ref().map(|x| x.set_as_disconnected()); if let Some(x) = self.scl.as_ref() {
self.sda.as_ref().map(|x| x.set_as_disconnected()); x.set_as_disconnected()
}
if let Some(x) = self.sda.as_ref() {
x.set_as_disconnected()
}
self.info.rcc.disable(); self.info.rcc.disable();
} }
@ -187,7 +125,7 @@ pub struct I2c<'d, M: Mode, IM: MasterMode> {
timeout: Duration, timeout: Duration,
_phantom: PhantomData<M>, _phantom: PhantomData<M>,
_phantom2: PhantomData<IM>, _phantom2: PhantomData<IM>,
drop_guard: I2CDropGuard<'d>, _drop_guard: I2CDropGuard<'d>,
} }
impl<'d> I2c<'d, Async, Master> { impl<'d> I2c<'d, Async, Master> {
@ -261,7 +199,7 @@ impl<'d, M: Mode> I2c<'d, M, Master> {
timeout: config.timeout, timeout: config.timeout,
_phantom: PhantomData, _phantom: PhantomData,
_phantom2: PhantomData, _phantom2: PhantomData,
drop_guard: I2CDropGuard { _drop_guard: I2CDropGuard {
info: T::info(), info: T::info(),
scl, scl,
sda, sda,
@ -509,9 +447,7 @@ fn operation_frames<'a, 'b: 'a>(
let mut next_first_frame = true; let mut next_first_frame = true;
Ok(iter::from_fn(move || { Ok(iter::from_fn(move || {
let Some(op) = operations.next() else { let op = operations.next()?;
return None;
};
// Is `op` first frame of its type? // Is `op` first frame of its type?
let first_frame = next_first_frame; let first_frame = next_first_frame;

View File

@ -733,7 +733,7 @@ impl<'d, M: Mode> I2c<'d, M, Master> {
timeout: self.timeout, timeout: self.timeout,
_phantom: PhantomData, _phantom: PhantomData,
_phantom2: PhantomData, _phantom2: PhantomData,
drop_guard: self.drop_guard, _drop_guard: self._drop_guard,
}; };
slave.init_slave(slave_addr_config); slave.init_slave(slave_addr_config);
slave slave