diff options
| author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-08-10 10:08:27 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-08-10 10:08:27 +0000 |
| commit | 0e524247fa4adc524c546b0d073e7061ad6c1b83 (patch) | |
| tree | b929b2f1d676790deee4d8c4fe3ec58ae5d6643e | |
| parent | de22cb906567b1262f91398c82b6ed90803852fc (diff) | |
| parent | 936473b68adb3a526846ff30233936dc3c52de25 (diff) | |
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 <[email protected]>
| -rw-r--r-- | embassy-stm32/src/gpio.rs | 8 | ||||
| -rw-r--r-- | embassy-stm32/src/i2c/v1.rs | 36 | ||||
| -rw-r--r-- | embassy-stm32/src/i2c/v2.rs | 36 | ||||
| -rw-r--r-- | examples/stm32h7/src/bin/camera.rs | 11 | ||||
| -rw-r--r-- | examples/stm32l4/src/bin/i2c.rs | 11 | ||||
| -rw-r--r-- | examples/stm32l4/src/bin/i2c_blocking_async.rs | 11 | ||||
| -rw-r--r-- | examples/stm32l4/src/bin/i2c_dma.rs | 11 |
7 files changed, 112 insertions, 12 deletions
diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs index 3c4cdb887..d794e3989 100644 --- a/embassy-stm32/src/gpio.rs +++ b/embassy-stm32/src/gpio.rs | |||
| @@ -213,7 +213,7 @@ impl<'d, T: Pin> Drop for Flex<'d, T> { | |||
| 213 | } | 213 | } |
| 214 | 214 | ||
| 215 | /// Pull setting for an input. | 215 | /// Pull setting for an input. |
| 216 | #[derive(Debug, Eq, PartialEq)] | 216 | #[derive(Debug, Eq, PartialEq, Copy, Clone)] |
| 217 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 217 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 218 | pub enum Pull { | 218 | pub enum Pull { |
| 219 | None, | 219 | None, |
| @@ -235,7 +235,7 @@ impl From<Pull> for vals::Pupdr { | |||
| 235 | } | 235 | } |
| 236 | 236 | ||
| 237 | /// Speed settings | 237 | /// Speed settings |
| 238 | #[derive(Debug)] | 238 | #[derive(Debug, Copy, Clone)] |
| 239 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 239 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 240 | pub enum Speed { | 240 | pub enum Speed { |
| 241 | Low, | 241 | Low, |
| @@ -303,7 +303,7 @@ impl<'d, T: Pin> Input<'d, T> { | |||
| 303 | } | 303 | } |
| 304 | 304 | ||
| 305 | /// Digital input or output level. | 305 | /// Digital input or output level. |
| 306 | #[derive(Debug, Eq, PartialEq)] | 306 | #[derive(Debug, Eq, PartialEq, Copy, Clone)] |
| 307 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 307 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 308 | pub enum Level { | 308 | pub enum Level { |
| 309 | Low, | 309 | Low, |
| @@ -470,7 +470,7 @@ pub(crate) mod sealed { | |||
| 470 | use super::*; | 470 | use super::*; |
| 471 | 471 | ||
| 472 | /// Alternate function type settings | 472 | /// Alternate function type settings |
| 473 | #[derive(Debug)] | 473 | #[derive(Debug, Copy, Clone)] |
| 474 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 474 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 475 | pub enum AFType { | 475 | pub enum AFType { |
| 476 | Input, | 476 | Input, |
diff --git a/embassy-stm32/src/i2c/v1.rs b/embassy-stm32/src/i2c/v1.rs index 613815a9c..9dc75789a 100644 --- a/embassy-stm32/src/i2c/v1.rs +++ b/embassy-stm32/src/i2c/v1.rs | |||
| @@ -4,11 +4,28 @@ use embassy_embedded_hal::SetConfig; | |||
| 4 | use embassy_hal_common::into_ref; | 4 | use embassy_hal_common::into_ref; |
| 5 | 5 | ||
| 6 | use crate::gpio::sealed::AFType; | 6 | use crate::gpio::sealed::AFType; |
| 7 | use crate::gpio::Pull; | ||
| 7 | use crate::i2c::{Error, Instance, SclPin, SdaPin}; | 8 | use crate::i2c::{Error, Instance, SclPin, SdaPin}; |
| 8 | use crate::pac::i2c; | 9 | use crate::pac::i2c; |
| 9 | use crate::time::Hertz; | 10 | use crate::time::Hertz; |
| 10 | use crate::Peripheral; | 11 | use crate::Peripheral; |
| 11 | 12 | ||
| 13 | #[non_exhaustive] | ||
| 14 | #[derive(Copy, Clone)] | ||
| 15 | pub struct Config { | ||
| 16 | pub sda_pullup: bool, | ||
| 17 | pub scl_pullup: bool, | ||
| 18 | } | ||
| 19 | |||
| 20 | impl Default for Config { | ||
| 21 | fn default() -> Self { | ||
| 22 | Self { | ||
| 23 | sda_pullup: false, | ||
| 24 | scl_pullup: false, | ||
| 25 | } | ||
| 26 | } | ||
| 27 | } | ||
| 28 | |||
| 12 | pub struct State {} | 29 | pub struct State {} |
| 13 | 30 | ||
| 14 | impl State { | 31 | impl State { |
| @@ -27,6 +44,7 @@ impl<'d, T: Instance> I2c<'d, T> { | |||
| 27 | scl: impl Peripheral<P = impl SclPin<T>> + 'd, | 44 | scl: impl Peripheral<P = impl SclPin<T>> + 'd, |
| 28 | sda: impl Peripheral<P = impl SdaPin<T>> + 'd, | 45 | sda: impl Peripheral<P = impl SdaPin<T>> + 'd, |
| 29 | freq: Hertz, | 46 | freq: Hertz, |
| 47 | config: Config, | ||
| 30 | ) -> Self { | 48 | ) -> Self { |
| 31 | into_ref!(scl, sda); | 49 | into_ref!(scl, sda); |
| 32 | 50 | ||
| @@ -34,8 +52,22 @@ impl<'d, T: Instance> I2c<'d, T> { | |||
| 34 | T::reset(); | 52 | T::reset(); |
| 35 | 53 | ||
| 36 | unsafe { | 54 | unsafe { |
| 37 | scl.set_as_af(scl.af_num(), AFType::OutputOpenDrain); | 55 | scl.set_as_af_pull( |
| 38 | sda.set_as_af(sda.af_num(), AFType::OutputOpenDrain); | 56 | scl.af_num(), |
| 57 | AFType::OutputOpenDrain, | ||
| 58 | match config.scl_pullup { | ||
| 59 | true => Pull::Up, | ||
| 60 | false => Pull::None, | ||
| 61 | }, | ||
| 62 | ); | ||
| 63 | sda.set_as_af_pull( | ||
| 64 | sda.af_num(), | ||
| 65 | AFType::OutputOpenDrain, | ||
| 66 | match config.sda_pullup { | ||
| 67 | true => Pull::Up, | ||
| 68 | false => Pull::None, | ||
| 69 | }, | ||
| 70 | ); | ||
| 39 | } | 71 | } |
| 40 | 72 | ||
| 41 | unsafe { | 73 | unsafe { |
diff --git a/embassy-stm32/src/i2c/v2.rs b/embassy-stm32/src/i2c/v2.rs index f8067e8b3..b4303d3d4 100644 --- a/embassy-stm32/src/i2c/v2.rs +++ b/embassy-stm32/src/i2c/v2.rs | |||
| @@ -10,12 +10,29 @@ use futures::future::poll_fn; | |||
| 10 | 10 | ||
| 11 | use crate::dma::NoDma; | 11 | use crate::dma::NoDma; |
| 12 | use crate::gpio::sealed::AFType; | 12 | use crate::gpio::sealed::AFType; |
| 13 | use crate::gpio::Pull; | ||
| 13 | use crate::i2c::{Error, Instance, SclPin, SdaPin}; | 14 | use crate::i2c::{Error, Instance, SclPin, SdaPin}; |
| 14 | use crate::interrupt::InterruptExt; | 15 | use crate::interrupt::InterruptExt; |
| 15 | use crate::pac::i2c; | 16 | use crate::pac::i2c; |
| 16 | use crate::time::Hertz; | 17 | use crate::time::Hertz; |
| 17 | use crate::Peripheral; | 18 | use crate::Peripheral; |
| 18 | 19 | ||
| 20 | #[non_exhaustive] | ||
| 21 | #[derive(Copy, Clone)] | ||
| 22 | pub struct Config { | ||
| 23 | pub sda_pullup: bool, | ||
| 24 | pub scl_pullup: bool, | ||
| 25 | } | ||
| 26 | |||
| 27 | impl Default for Config { | ||
| 28 | fn default() -> Self { | ||
| 29 | Self { | ||
| 30 | sda_pullup: false, | ||
| 31 | scl_pullup: false, | ||
| 32 | } | ||
| 33 | } | ||
| 34 | } | ||
| 35 | |||
| 19 | pub struct State { | 36 | pub struct State { |
| 20 | waker: AtomicWaker, | 37 | waker: AtomicWaker, |
| 21 | chunks_transferred: AtomicUsize, | 38 | chunks_transferred: AtomicUsize, |
| @@ -46,6 +63,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { | |||
| 46 | tx_dma: impl Peripheral<P = TXDMA> + 'd, | 63 | tx_dma: impl Peripheral<P = TXDMA> + 'd, |
| 47 | rx_dma: impl Peripheral<P = RXDMA> + 'd, | 64 | rx_dma: impl Peripheral<P = RXDMA> + 'd, |
| 48 | freq: Hertz, | 65 | freq: Hertz, |
| 66 | config: Config, | ||
| 49 | ) -> Self { | 67 | ) -> Self { |
| 50 | into_ref!(peri, irq, scl, sda, tx_dma, rx_dma); | 68 | into_ref!(peri, irq, scl, sda, tx_dma, rx_dma); |
| 51 | 69 | ||
| @@ -53,8 +71,22 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> { | |||
| 53 | T::reset(); | 71 | T::reset(); |
| 54 | 72 | ||
| 55 | unsafe { | 73 | unsafe { |
| 56 | scl.set_as_af(scl.af_num(), AFType::OutputOpenDrain); | 74 | scl.set_as_af_pull( |
| 57 | sda.set_as_af(sda.af_num(), AFType::OutputOpenDrain); | 75 | scl.af_num(), |
| 76 | AFType::OutputOpenDrain, | ||
| 77 | match config.scl_pullup { | ||
| 78 | true => Pull::Up, | ||
| 79 | false => Pull::None, | ||
| 80 | }, | ||
| 81 | ); | ||
| 82 | sda.set_as_af_pull( | ||
| 83 | sda.af_num(), | ||
| 84 | AFType::OutputOpenDrain, | ||
| 85 | match config.sda_pullup { | ||
| 86 | true => Pull::Up, | ||
| 87 | false => Pull::None, | ||
| 88 | }, | ||
| 89 | ); | ||
| 58 | } | 90 | } |
| 59 | 91 | ||
| 60 | unsafe { | 92 | unsafe { |
diff --git a/examples/stm32h7/src/bin/camera.rs b/examples/stm32h7/src/bin/camera.rs index 69187182f..a3bb2d5e2 100644 --- a/examples/stm32h7/src/bin/camera.rs +++ b/examples/stm32h7/src/bin/camera.rs | |||
| @@ -39,7 +39,16 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 39 | 39 | ||
| 40 | let mut led = Output::new(p.PE3, Level::High, Speed::Low); | 40 | let mut led = Output::new(p.PE3, Level::High, Speed::Low); |
| 41 | let i2c_irq = interrupt::take!(I2C1_EV); | 41 | let i2c_irq = interrupt::take!(I2C1_EV); |
| 42 | let cam_i2c = I2c::new(p.I2C1, p.PB8, p.PB9, i2c_irq, p.DMA1_CH1, p.DMA1_CH2, khz(100)); | 42 | let cam_i2c = I2c::new( |
| 43 | p.I2C1, | ||
| 44 | p.PB8, | ||
| 45 | p.PB9, | ||
| 46 | i2c_irq, | ||
| 47 | p.DMA1_CH1, | ||
| 48 | p.DMA1_CH2, | ||
| 49 | khz(100), | ||
| 50 | Default::default(), | ||
| 51 | ); | ||
| 43 | 52 | ||
| 44 | let mut camera = Ov7725::new(cam_i2c, mco); | 53 | let mut camera = Ov7725::new(cam_i2c, mco); |
| 45 | 54 | ||
diff --git a/examples/stm32l4/src/bin/i2c.rs b/examples/stm32l4/src/bin/i2c.rs index 058529ecf..5bfa560dc 100644 --- a/examples/stm32l4/src/bin/i2c.rs +++ b/examples/stm32l4/src/bin/i2c.rs | |||
| @@ -16,7 +16,16 @@ const WHOAMI: u8 = 0x0F; | |||
| 16 | #[embassy_executor::main] | 16 | #[embassy_executor::main] |
| 17 | async fn main(_spawner: Spawner, p: Peripherals) -> ! { | 17 | async fn main(_spawner: Spawner, p: Peripherals) -> ! { |
| 18 | let irq = interrupt::take!(I2C2_EV); | 18 | let irq = interrupt::take!(I2C2_EV); |
| 19 | let mut i2c = I2c::new(p.I2C2, p.PB10, p.PB11, irq, NoDma, NoDma, Hertz(100_000)); | 19 | let mut i2c = I2c::new( |
| 20 | p.I2C2, | ||
| 21 | p.PB10, | ||
| 22 | p.PB11, | ||
| 23 | irq, | ||
| 24 | NoDma, | ||
| 25 | NoDma, | ||
| 26 | Hertz(100_000), | ||
| 27 | Default::default(), | ||
| 28 | ); | ||
| 20 | 29 | ||
| 21 | let mut data = [0u8; 1]; | 30 | let mut data = [0u8; 1]; |
| 22 | unwrap!(i2c.blocking_write_read(ADDRESS, &[WHOAMI], &mut data)); | 31 | unwrap!(i2c.blocking_write_read(ADDRESS, &[WHOAMI], &mut data)); |
diff --git a/examples/stm32l4/src/bin/i2c_blocking_async.rs b/examples/stm32l4/src/bin/i2c_blocking_async.rs index 2dae9c2d5..c924bc9c5 100644 --- a/examples/stm32l4/src/bin/i2c_blocking_async.rs +++ b/examples/stm32l4/src/bin/i2c_blocking_async.rs | |||
| @@ -18,7 +18,16 @@ const WHOAMI: u8 = 0x0F; | |||
| 18 | #[embassy_executor::main] | 18 | #[embassy_executor::main] |
| 19 | async fn main(_spawner: Spawner, p: Peripherals) -> ! { | 19 | async fn main(_spawner: Spawner, p: Peripherals) -> ! { |
| 20 | let irq = interrupt::take!(I2C2_EV); | 20 | let irq = interrupt::take!(I2C2_EV); |
| 21 | let i2c = I2c::new(p.I2C2, p.PB10, p.PB11, irq, NoDma, NoDma, Hertz(100_000)); | 21 | let i2c = I2c::new( |
| 22 | p.I2C2, | ||
| 23 | p.PB10, | ||
| 24 | p.PB11, | ||
| 25 | irq, | ||
| 26 | NoDma, | ||
| 27 | NoDma, | ||
| 28 | Hertz(100_000), | ||
| 29 | Default::default(), | ||
| 30 | ); | ||
| 22 | let mut i2c = BlockingAsync::new(i2c); | 31 | let mut i2c = BlockingAsync::new(i2c); |
| 23 | 32 | ||
| 24 | let mut data = [0u8; 1]; | 33 | let mut data = [0u8; 1]; |
diff --git a/examples/stm32l4/src/bin/i2c_dma.rs b/examples/stm32l4/src/bin/i2c_dma.rs index 9e71d404b..2b338427b 100644 --- a/examples/stm32l4/src/bin/i2c_dma.rs +++ b/examples/stm32l4/src/bin/i2c_dma.rs | |||
| @@ -15,7 +15,16 @@ const WHOAMI: u8 = 0x0F; | |||
| 15 | #[embassy_executor::main] | 15 | #[embassy_executor::main] |
| 16 | async fn main(_spawner: Spawner, p: Peripherals) -> ! { | 16 | async fn main(_spawner: Spawner, p: Peripherals) -> ! { |
| 17 | let irq = interrupt::take!(I2C2_EV); | 17 | let irq = interrupt::take!(I2C2_EV); |
| 18 | let mut i2c = I2c::new(p.I2C2, p.PB10, p.PB11, irq, p.DMA1_CH4, p.DMA1_CH5, Hertz(100_000)); | 18 | let mut i2c = I2c::new( |
| 19 | p.I2C2, | ||
| 20 | p.PB10, | ||
| 21 | p.PB11, | ||
| 22 | irq, | ||
| 23 | p.DMA1_CH4, | ||
| 24 | p.DMA1_CH5, | ||
| 25 | Hertz(100_000), | ||
| 26 | Default::default(), | ||
| 27 | ); | ||
| 19 | 28 | ||
| 20 | let mut data = [0u8; 1]; | 29 | let mut data = [0u8; 1]; |
| 21 | unwrap!(i2c.write_read(ADDRESS, &[WHOAMI], &mut data).await); | 30 | unwrap!(i2c.write_read(ADDRESS, &[WHOAMI], &mut data).await); |
