#[cfg(feature = "embassy")]
mod future;
mod hal;
pub mod master;
mod pins;
pub mod slave;
use crate::clock::peripheral::{
PeripheralClockIndex, PeripheralIdToClockIndex, PeripheralInterrupt,
};
use crate::gpio::{self, AnyPin};
use crate::macro_def::{impl_sealed_peripheral_id, pin_af_for_instance_def};
use crate::mode::Mode;
use core::marker::PhantomData;
use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
use enumset::EnumSetType;
pub use master::Master;
pub use slave::Slave;
pub trait Instance: Peripheral<P = Self> + hal::sealed::Instance + 'static + Send {}
#[derive(PartialEq)]
pub enum Id {
I2c1,
}
impl PeripheralIdToClockIndex for Id {
fn clock(&self) -> PeripheralClockIndex {
match *self {
Self::I2c1 => PeripheralClockIndex::I2C,
}
}
}
impl PeripheralInterrupt for Id {
fn interrupt(&self) -> crate::pac::interrupt {
match *self {
Self::I2c1 => crate::pac::interrupt::I2C1,
}
}
}
pub const SPEED_HZ_STAND: usize = 100_000;
pub const SPEED_HZ_FAST: usize = 400_000;
pub enum Rule {
Master,
Slave,
}
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum Error {
Busy,
PClock,
SpeedMode,
Start,
Address,
Stop,
Tx,
RX,
}
pin_af_for_instance_def!(SdaPin, Instance);
pin_af_for_instance_def!(SclPin, Instance);
impl_sealed_peripheral_id!(I2C, I2c1);
pub struct AnyI2c<'d, T: Instance, M: Mode> {
_t: PhantomData<&'d T>,
_mode: PhantomData<M>,
_sda: PeripheralRef<'d, AnyPin>,
_scl: PeripheralRef<'d, AnyPin>,
}
impl<'d, T: Instance, M: Mode> AnyI2c<'d, T, M> {
fn new_inner(config: Config) -> Result<(), Error> {
T::id().clock().open();
T::config(config)?;
Ok(())
}
pub fn as_master(self) -> Master<'d, T, M> {
Master::<'_, T, M>::new()
}
pub fn as_slave() -> Slave<'d, T, M> {
todo!()
}
pub fn new(
_i2c: impl Peripheral<P = T>,
scl: impl Peripheral<P = impl SclPin<T>> + 'd,
sda: impl Peripheral<P = impl SdaPin<T>> + 'd,
config: Config,
) -> Result<Self, Error> {
into_ref!(_i2c, scl, sda);
scl.set_instance_af(gpio::PinSpeed::VeryHigh, gpio::PinIoType::OpenDrain);
sda.set_instance_af(gpio::PinSpeed::VeryHigh, gpio::PinIoType::OpenDrain);
Self::new_inner(config)?;
Ok(Self {
_t: PhantomData,
_mode: PhantomData,
_sda: sda.map_into(),
_scl: scl.map_into(),
})
}
}
pub struct Config {
speed: usize,
}
impl Default for Config {
fn default() -> Self {
Self { speed: 100_000 }
}
}
impl Config {
pub fn speed(self, speed: usize) -> Self {
Self { speed }
}
}
#[derive(EnumSetType)]
pub enum Event {
SB,
ADD,
STOPF,
BTF,
RXNE,
TXE,
BERR,
ARLO,
AF,
OVR,
PECERR,
}