aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-08-10 10:08:27 +0000
committerGitHub <[email protected]>2022-08-10 10:08:27 +0000
commit0e524247fa4adc524c546b0d073e7061ad6c1b83 (patch)
treeb929b2f1d676790deee4d8c4fe3ec58ae5d6643e
parentde22cb906567b1262f91398c82b6ed90803852fc (diff)
parent936473b68adb3a526846ff30233936dc3c52de25 (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.rs8
-rw-r--r--embassy-stm32/src/i2c/v1.rs36
-rw-r--r--embassy-stm32/src/i2c/v2.rs36
-rw-r--r--examples/stm32h7/src/bin/camera.rs11
-rw-r--r--examples/stm32l4/src/bin/i2c.rs11
-rw-r--r--examples/stm32l4/src/bin/i2c_blocking_async.rs11
-rw-r--r--examples/stm32l4/src/bin/i2c_dma.rs11
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))]
218pub enum Pull { 218pub 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))]
240pub enum Speed { 240pub 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))]
308pub enum Level { 308pub 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;
4use embassy_hal_common::into_ref; 4use embassy_hal_common::into_ref;
5 5
6use crate::gpio::sealed::AFType; 6use crate::gpio::sealed::AFType;
7use crate::gpio::Pull;
7use crate::i2c::{Error, Instance, SclPin, SdaPin}; 8use crate::i2c::{Error, Instance, SclPin, SdaPin};
8use crate::pac::i2c; 9use crate::pac::i2c;
9use crate::time::Hertz; 10use crate::time::Hertz;
10use crate::Peripheral; 11use crate::Peripheral;
11 12
13#[non_exhaustive]
14#[derive(Copy, Clone)]
15pub struct Config {
16 pub sda_pullup: bool,
17 pub scl_pullup: bool,
18}
19
20impl Default for Config {
21 fn default() -> Self {
22 Self {
23 sda_pullup: false,
24 scl_pullup: false,
25 }
26 }
27}
28
12pub struct State {} 29pub struct State {}
13 30
14impl State { 31impl 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
11use crate::dma::NoDma; 11use crate::dma::NoDma;
12use crate::gpio::sealed::AFType; 12use crate::gpio::sealed::AFType;
13use crate::gpio::Pull;
13use crate::i2c::{Error, Instance, SclPin, SdaPin}; 14use crate::i2c::{Error, Instance, SclPin, SdaPin};
14use crate::interrupt::InterruptExt; 15use crate::interrupt::InterruptExt;
15use crate::pac::i2c; 16use crate::pac::i2c;
16use crate::time::Hertz; 17use crate::time::Hertz;
17use crate::Peripheral; 18use crate::Peripheral;
18 19
20#[non_exhaustive]
21#[derive(Copy, Clone)]
22pub struct Config {
23 pub sda_pullup: bool,
24 pub scl_pullup: bool,
25}
26
27impl Default for Config {
28 fn default() -> Self {
29 Self {
30 sda_pullup: false,
31 scl_pullup: false,
32 }
33 }
34}
35
19pub struct State { 36pub 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]
17async fn main(_spawner: Spawner, p: Peripherals) -> ! { 17async 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]
19async fn main(_spawner: Spawner, p: Peripherals) -> ! { 19async 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]
16async fn main(_spawner: Spawner, p: Peripherals) -> ! { 16async 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);