mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-25 08:12:30 +00:00
stm32/i2c: use new_pin! macro
This commit is contained in:
parent
ca3c15658d
commit
41711195e3
@ -9,16 +9,16 @@ use core::future::Future;
|
||||
use core::iter;
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use embassy_hal_internal::{into_ref, Peripheral};
|
||||
use embassy_hal_internal::{Peripheral, PeripheralRef};
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
#[cfg(feature = "time")]
|
||||
use embassy_time::{Duration, Instant};
|
||||
|
||||
use crate::dma::ChannelAndRequest;
|
||||
use crate::gpio::{AFType, Pull};
|
||||
use crate::gpio::{AFType, AnyPin, Pull, SealedPin as _, Speed};
|
||||
use crate::interrupt::typelevel::Interrupt;
|
||||
use crate::mode::{Async, Blocking, Mode};
|
||||
use crate::rcc::{self, RccInfo, SealedRccPeripheral};
|
||||
use crate::rcc::{RccInfo, SealedRccPeripheral};
|
||||
use crate::time::Hertz;
|
||||
use crate::{interrupt, peripherals};
|
||||
|
||||
@ -72,11 +72,29 @@ impl Default for Config {
|
||||
}
|
||||
}
|
||||
|
||||
impl Config {
|
||||
fn scl_pull_mode(&self) -> Pull {
|
||||
match self.scl_pullup {
|
||||
true => Pull::Up,
|
||||
false => Pull::Down,
|
||||
}
|
||||
}
|
||||
|
||||
fn sda_pull_mode(&self) -> Pull {
|
||||
match self.sda_pullup {
|
||||
true => Pull::Up,
|
||||
false => Pull::Down,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// I2C driver.
|
||||
pub struct I2c<'d, M: Mode> {
|
||||
info: &'static Info,
|
||||
state: &'static State,
|
||||
kernel_clock: Hertz,
|
||||
scl: Option<PeripheralRef<'d, AnyPin>>,
|
||||
sda: Option<PeripheralRef<'d, AnyPin>>,
|
||||
tx_dma: Option<ChannelAndRequest<'d>>,
|
||||
rx_dma: Option<ChannelAndRequest<'d>>,
|
||||
#[cfg(feature = "time")]
|
||||
@ -98,7 +116,15 @@ impl<'d> I2c<'d, Async> {
|
||||
freq: Hertz,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
Self::new_inner(peri, scl, sda, new_dma!(tx_dma), new_dma!(rx_dma), freq, config)
|
||||
Self::new_inner(
|
||||
peri,
|
||||
new_pin!(scl, AFType::OutputOpenDrain, Speed::Medium, config.scl_pull_mode()),
|
||||
new_pin!(sda, AFType::OutputOpenDrain, Speed::Medium, config.sda_pull_mode()),
|
||||
new_dma!(tx_dma),
|
||||
new_dma!(rx_dma),
|
||||
freq,
|
||||
config,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,7 +137,15 @@ impl<'d> I2c<'d, Blocking> {
|
||||
freq: Hertz,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
Self::new_inner(peri, scl, sda, None, None, freq, config)
|
||||
Self::new_inner(
|
||||
peri,
|
||||
new_pin!(scl, AFType::OutputOpenDrain, Speed::Medium, config.scl_pull_mode()),
|
||||
new_pin!(sda, AFType::OutputOpenDrain, Speed::Medium, config.sda_pull_mode()),
|
||||
None,
|
||||
None,
|
||||
freq,
|
||||
config,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,34 +153,13 @@ impl<'d, M: Mode> I2c<'d, M> {
|
||||
/// Create a new I2C driver.
|
||||
fn new_inner<T: Instance>(
|
||||
_peri: impl Peripheral<P = T> + 'd,
|
||||
scl: impl Peripheral<P = impl SclPin<T>> + 'd,
|
||||
sda: impl Peripheral<P = impl SdaPin<T>> + 'd,
|
||||
scl: Option<PeripheralRef<'d, AnyPin>>,
|
||||
sda: Option<PeripheralRef<'d, AnyPin>>,
|
||||
tx_dma: Option<ChannelAndRequest<'d>>,
|
||||
rx_dma: Option<ChannelAndRequest<'d>>,
|
||||
freq: Hertz,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
into_ref!(scl, sda);
|
||||
|
||||
rcc::enable_and_reset::<T>();
|
||||
|
||||
scl.set_as_af_pull(
|
||||
scl.af_num(),
|
||||
AFType::OutputOpenDrain,
|
||||
match config.scl_pullup {
|
||||
true => Pull::Up,
|
||||
false => Pull::None,
|
||||
},
|
||||
);
|
||||
sda.set_as_af_pull(
|
||||
sda.af_num(),
|
||||
AFType::OutputOpenDrain,
|
||||
match config.sda_pullup {
|
||||
true => Pull::Up,
|
||||
false => Pull::None,
|
||||
},
|
||||
);
|
||||
|
||||
unsafe { T::EventInterrupt::enable() };
|
||||
unsafe { T::ErrorInterrupt::enable() };
|
||||
|
||||
@ -154,18 +167,23 @@ impl<'d, M: Mode> I2c<'d, M> {
|
||||
info: T::info(),
|
||||
state: T::state(),
|
||||
kernel_clock: T::frequency(),
|
||||
scl,
|
||||
sda,
|
||||
tx_dma,
|
||||
rx_dma,
|
||||
#[cfg(feature = "time")]
|
||||
timeout: config.timeout,
|
||||
_phantom: PhantomData,
|
||||
};
|
||||
|
||||
this.init(freq, config);
|
||||
|
||||
this.enable_and_init(freq, config);
|
||||
this
|
||||
}
|
||||
|
||||
fn enable_and_init(&mut self, freq: Hertz, config: Config) {
|
||||
self.info.rcc.enable_and_reset();
|
||||
self.init(freq, config);
|
||||
}
|
||||
|
||||
fn timeout(&self) -> Timeout {
|
||||
Timeout {
|
||||
#[cfg(feature = "time")]
|
||||
@ -174,6 +192,15 @@ impl<'d, M: Mode> I2c<'d, M> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, M: Mode> Drop for I2c<'d, M> {
|
||||
fn drop(&mut self) {
|
||||
self.scl.as_ref().map(|x| x.set_as_disconnected());
|
||||
self.sda.as_ref().map(|x| x.set_as_disconnected());
|
||||
|
||||
self.info.rcc.disable()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
struct Timeout {
|
||||
#[cfg(feature = "time")]
|
||||
|
@ -700,12 +700,6 @@ impl<'d> I2c<'d, Async> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, M: PeriMode> Drop for I2c<'d, M> {
|
||||
fn drop(&mut self) {
|
||||
self.info.rcc.disable()
|
||||
}
|
||||
}
|
||||
|
||||
enum Mode {
|
||||
Fast,
|
||||
Standard,
|
||||
|
@ -671,12 +671,6 @@ impl<'d> I2c<'d, Async> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, M: Mode> Drop for I2c<'d, M> {
|
||||
fn drop(&mut self) {
|
||||
self.info.rcc.disable();
|
||||
}
|
||||
}
|
||||
|
||||
/// I2C Stop Configuration
|
||||
///
|
||||
/// Peripheral options for generating the STOP condition
|
||||
|
Loading…
Reference in New Issue
Block a user