Merge #896
896: Implement I2C pullup configuration r=lulf a=chemicstry I wasn't sure if I should put frequency into config struct, so left it separate as in SPI periph. Also added Copy derives to gpio types, not sure why they weren't? Co-authored-by: chemicstry <chemicstry@gmail.com>
This commit is contained in:
commit
0e524247fa
@ -213,7 +213,7 @@ impl<'d, T: Pin> Drop for Flex<'d, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Pull setting for an input.
|
/// Pull setting for an input.
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
pub enum Pull {
|
pub enum Pull {
|
||||||
None,
|
None,
|
||||||
@ -235,7 +235,7 @@ impl From<Pull> for vals::Pupdr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Speed settings
|
/// Speed settings
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
pub enum Speed {
|
pub enum Speed {
|
||||||
Low,
|
Low,
|
||||||
@ -303,7 +303,7 @@ impl<'d, T: Pin> Input<'d, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Digital input or output level.
|
/// Digital input or output level.
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
pub enum Level {
|
pub enum Level {
|
||||||
Low,
|
Low,
|
||||||
@ -470,7 +470,7 @@ pub(crate) mod sealed {
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
/// Alternate function type settings
|
/// Alternate function type settings
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
pub enum AFType {
|
pub enum AFType {
|
||||||
Input,
|
Input,
|
||||||
|
@ -4,11 +4,28 @@ use embassy_embedded_hal::SetConfig;
|
|||||||
use embassy_hal_common::into_ref;
|
use embassy_hal_common::into_ref;
|
||||||
|
|
||||||
use crate::gpio::sealed::AFType;
|
use crate::gpio::sealed::AFType;
|
||||||
|
use crate::gpio::Pull;
|
||||||
use crate::i2c::{Error, Instance, SclPin, SdaPin};
|
use crate::i2c::{Error, Instance, SclPin, SdaPin};
|
||||||
use crate::pac::i2c;
|
use crate::pac::i2c;
|
||||||
use crate::time::Hertz;
|
use crate::time::Hertz;
|
||||||
use crate::Peripheral;
|
use crate::Peripheral;
|
||||||
|
|
||||||
|
#[non_exhaustive]
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct Config {
|
||||||
|
pub sda_pullup: bool,
|
||||||
|
pub scl_pullup: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Config {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
sda_pullup: false,
|
||||||
|
scl_pullup: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct State {}
|
pub struct State {}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
@ -27,6 +44,7 @@ impl<'d, T: Instance> I2c<'d, T> {
|
|||||||
scl: impl Peripheral<P = impl SclPin<T>> + 'd,
|
scl: impl Peripheral<P = impl SclPin<T>> + 'd,
|
||||||
sda: impl Peripheral<P = impl SdaPin<T>> + 'd,
|
sda: impl Peripheral<P = impl SdaPin<T>> + 'd,
|
||||||
freq: Hertz,
|
freq: Hertz,
|
||||||
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(scl, sda);
|
into_ref!(scl, sda);
|
||||||
|
|
||||||
@ -34,8 +52,22 @@ impl<'d, T: Instance> I2c<'d, T> {
|
|||||||
T::reset();
|
T::reset();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
scl.set_as_af(scl.af_num(), AFType::OutputOpenDrain);
|
scl.set_as_af_pull(
|
||||||
sda.set_as_af(sda.af_num(), AFType::OutputOpenDrain);
|
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 {
|
unsafe {
|
||||||
|
@ -10,12 +10,29 @@ use futures::future::poll_fn;
|
|||||||
|
|
||||||
use crate::dma::NoDma;
|
use crate::dma::NoDma;
|
||||||
use crate::gpio::sealed::AFType;
|
use crate::gpio::sealed::AFType;
|
||||||
|
use crate::gpio::Pull;
|
||||||
use crate::i2c::{Error, Instance, SclPin, SdaPin};
|
use crate::i2c::{Error, Instance, SclPin, SdaPin};
|
||||||
use crate::interrupt::InterruptExt;
|
use crate::interrupt::InterruptExt;
|
||||||
use crate::pac::i2c;
|
use crate::pac::i2c;
|
||||||
use crate::time::Hertz;
|
use crate::time::Hertz;
|
||||||
use crate::Peripheral;
|
use crate::Peripheral;
|
||||||
|
|
||||||
|
#[non_exhaustive]
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct Config {
|
||||||
|
pub sda_pullup: bool,
|
||||||
|
pub scl_pullup: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Config {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
sda_pullup: false,
|
||||||
|
scl_pullup: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct State {
|
pub struct State {
|
||||||
waker: AtomicWaker,
|
waker: AtomicWaker,
|
||||||
chunks_transferred: AtomicUsize,
|
chunks_transferred: AtomicUsize,
|
||||||
@ -46,6 +63,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
|
|||||||
tx_dma: impl Peripheral<P = TXDMA> + 'd,
|
tx_dma: impl Peripheral<P = TXDMA> + 'd,
|
||||||
rx_dma: impl Peripheral<P = RXDMA> + 'd,
|
rx_dma: impl Peripheral<P = RXDMA> + 'd,
|
||||||
freq: Hertz,
|
freq: Hertz,
|
||||||
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(peri, irq, scl, sda, tx_dma, rx_dma);
|
into_ref!(peri, irq, scl, sda, tx_dma, rx_dma);
|
||||||
|
|
||||||
@ -53,8 +71,22 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
|
|||||||
T::reset();
|
T::reset();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
scl.set_as_af(scl.af_num(), AFType::OutputOpenDrain);
|
scl.set_as_af_pull(
|
||||||
sda.set_as_af(sda.af_num(), AFType::OutputOpenDrain);
|
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 {
|
unsafe {
|
||||||
|
@ -39,7 +39,16 @@ async fn main(_spawner: Spawner, p: Peripherals) {
|
|||||||
|
|
||||||
let mut led = Output::new(p.PE3, Level::High, Speed::Low);
|
let mut led = Output::new(p.PE3, Level::High, Speed::Low);
|
||||||
let i2c_irq = interrupt::take!(I2C1_EV);
|
let i2c_irq = interrupt::take!(I2C1_EV);
|
||||||
let cam_i2c = I2c::new(p.I2C1, p.PB8, p.PB9, i2c_irq, p.DMA1_CH1, p.DMA1_CH2, khz(100));
|
let cam_i2c = I2c::new(
|
||||||
|
p.I2C1,
|
||||||
|
p.PB8,
|
||||||
|
p.PB9,
|
||||||
|
i2c_irq,
|
||||||
|
p.DMA1_CH1,
|
||||||
|
p.DMA1_CH2,
|
||||||
|
khz(100),
|
||||||
|
Default::default(),
|
||||||
|
);
|
||||||
|
|
||||||
let mut camera = Ov7725::new(cam_i2c, mco);
|
let mut camera = Ov7725::new(cam_i2c, mco);
|
||||||
|
|
||||||
|
@ -16,7 +16,16 @@ const WHOAMI: u8 = 0x0F;
|
|||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(_spawner: Spawner, p: Peripherals) -> ! {
|
async fn main(_spawner: Spawner, p: Peripherals) -> ! {
|
||||||
let irq = interrupt::take!(I2C2_EV);
|
let irq = interrupt::take!(I2C2_EV);
|
||||||
let mut i2c = I2c::new(p.I2C2, p.PB10, p.PB11, irq, NoDma, NoDma, Hertz(100_000));
|
let mut i2c = I2c::new(
|
||||||
|
p.I2C2,
|
||||||
|
p.PB10,
|
||||||
|
p.PB11,
|
||||||
|
irq,
|
||||||
|
NoDma,
|
||||||
|
NoDma,
|
||||||
|
Hertz(100_000),
|
||||||
|
Default::default(),
|
||||||
|
);
|
||||||
|
|
||||||
let mut data = [0u8; 1];
|
let mut data = [0u8; 1];
|
||||||
unwrap!(i2c.blocking_write_read(ADDRESS, &[WHOAMI], &mut data));
|
unwrap!(i2c.blocking_write_read(ADDRESS, &[WHOAMI], &mut data));
|
||||||
|
@ -18,7 +18,16 @@ const WHOAMI: u8 = 0x0F;
|
|||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(_spawner: Spawner, p: Peripherals) -> ! {
|
async fn main(_spawner: Spawner, p: Peripherals) -> ! {
|
||||||
let irq = interrupt::take!(I2C2_EV);
|
let irq = interrupt::take!(I2C2_EV);
|
||||||
let i2c = I2c::new(p.I2C2, p.PB10, p.PB11, irq, NoDma, NoDma, Hertz(100_000));
|
let i2c = I2c::new(
|
||||||
|
p.I2C2,
|
||||||
|
p.PB10,
|
||||||
|
p.PB11,
|
||||||
|
irq,
|
||||||
|
NoDma,
|
||||||
|
NoDma,
|
||||||
|
Hertz(100_000),
|
||||||
|
Default::default(),
|
||||||
|
);
|
||||||
let mut i2c = BlockingAsync::new(i2c);
|
let mut i2c = BlockingAsync::new(i2c);
|
||||||
|
|
||||||
let mut data = [0u8; 1];
|
let mut data = [0u8; 1];
|
||||||
|
@ -15,7 +15,16 @@ const WHOAMI: u8 = 0x0F;
|
|||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(_spawner: Spawner, p: Peripherals) -> ! {
|
async fn main(_spawner: Spawner, p: Peripherals) -> ! {
|
||||||
let irq = interrupt::take!(I2C2_EV);
|
let irq = interrupt::take!(I2C2_EV);
|
||||||
let mut i2c = I2c::new(p.I2C2, p.PB10, p.PB11, irq, p.DMA1_CH4, p.DMA1_CH5, Hertz(100_000));
|
let mut i2c = I2c::new(
|
||||||
|
p.I2C2,
|
||||||
|
p.PB10,
|
||||||
|
p.PB11,
|
||||||
|
irq,
|
||||||
|
p.DMA1_CH4,
|
||||||
|
p.DMA1_CH5,
|
||||||
|
Hertz(100_000),
|
||||||
|
Default::default(),
|
||||||
|
);
|
||||||
|
|
||||||
let mut data = [0u8; 1];
|
let mut data = [0u8; 1];
|
||||||
unwrap!(i2c.write_read(ADDRESS, &[WHOAMI], &mut data).await);
|
unwrap!(i2c.write_read(ADDRESS, &[WHOAMI], &mut data).await);
|
||||||
|
Loading…
Reference in New Issue
Block a user