Skip to content

Commit 5d5ce6f

Browse files
committed
Move i2c to module based in an attemp to get rid of feature-gated use statements,
and to clear up which pins are present on which lines Fix incorrect I2C2 on PC0 and PC1 for stm32l4x3 Add missing I2C1 SDA pin for stm32l4x3
1 parent 46bf2a8 commit 5d5ce6f

File tree

1 file changed

+91
-79
lines changed

1 file changed

+91
-79
lines changed

src/i2c.rs

Lines changed: 91 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
//! [stm32h7xx-hal](https://github.com/stm32-rs/stm32h7xx-hal) implementation,
33
//! as of 2021-02-25.
44
5-
use crate::gpio::{Alternate, OpenDrain, Output, AF4};
65
use crate::hal::blocking::i2c::{Read, Write, WriteRead};
76
use crate::pac::{i2c1, I2C1, I2C2};
87
use crate::rcc::{Clocks, APB1R1};
@@ -31,7 +30,7 @@ pub enum Error {
3130
}
3231

3332
#[doc(hidden)]
34-
mod private {
33+
pub(self) mod private {
3534
pub trait Sealed {}
3635
}
3736

@@ -44,12 +43,12 @@ pub trait SdaPin<I2C>: private::Sealed {}
4443
macro_rules! pins {
4544
($spi:ident, $af:ident, SCL: [$($scl:ident),*], SDA: [$($sda:ident),*]) => {
4645
$(
47-
impl private::Sealed for $scl<Alternate<$af, Output<OpenDrain>>> {}
48-
impl SclPin<$spi> for $scl<Alternate<$af, Output<OpenDrain>>> {}
46+
impl super::private::Sealed for $scl<Alternate<$af, Output<OpenDrain>>> {}
47+
impl super::SclPin<$spi> for $scl<Alternate<$af, Output<OpenDrain>>> {}
4948
)*
5049
$(
51-
impl private::Sealed for $sda<Alternate<$af, Output<OpenDrain>>> {}
52-
impl SdaPin<$spi> for $sda<Alternate<$af, Output<OpenDrain>>> {}
50+
impl super::private::Sealed for $sda<Alternate<$af, Output<OpenDrain>>> {}
51+
impl super::SdaPin<$spi> for $sda<Alternate<$af, Output<OpenDrain>>> {}
5352
)*
5453
}
5554
}
@@ -60,6 +59,8 @@ pub struct I2c<I2C, PINS> {
6059
pins: PINS,
6160
}
6261

62+
// TODO review why StartCondition and State structs exists. Last
63+
// update to them was november 2020
6364
/// Start conditions that govern repeated sequential transfer
6465
#[derive(Debug, Clone)]
6566
enum StartCondition {
@@ -119,48 +120,35 @@ impl State {
119120
}
120121
}
121122

122-
impl<SCL, SDA> I2c<I2C1, (SCL, SDA)> {
123-
pub fn i2c1<F>(i2c: I2C1, pins: (SCL, SDA), freq: F, clocks: Clocks, apb1: &mut APB1R1) -> Self
124-
where
125-
F: Into<Hertz>,
126-
SCL: SclPin<I2C1>,
127-
SDA: SdaPin<I2C1>,
128-
{
129-
apb1.enr().modify(|_, w| w.i2c1en().set_bit());
130-
apb1.rstr().modify(|_, w| w.i2c1rst().set_bit());
131-
apb1.rstr().modify(|_, w| w.i2c1rst().clear_bit());
132-
Self::new(i2c, pins, freq, clocks)
133-
}
123+
macro_rules! hal {
124+
($i2c_type: ident, $i2cX: ident, $i2cXen: ident, $i2cXrst: ident) => {
125+
impl<SCL, SDA> I2c<$i2c_type, (SCL, SDA)> {
126+
pub fn $i2cX<F>(
127+
i2c: $i2c_type,
128+
pins: (SCL, SDA),
129+
freq: F,
130+
clocks: Clocks,
131+
apb1: &mut APB1R1,
132+
) -> Self
133+
where
134+
F: Into<Hertz>,
135+
SCL: SclPin<$i2c_type>,
136+
SDA: SdaPin<$i2c_type>,
137+
{
138+
apb1.enr().modify(|_, w| w.$i2cXen().set_bit());
139+
apb1.rstr().modify(|_, w| w.$i2cXrst().set_bit());
140+
apb1.rstr().modify(|_, w| w.$i2cXrst().clear_bit());
141+
Self::new(i2c, pins, freq, clocks)
142+
}
143+
}
144+
};
134145
}
135146

136-
impl<SCL, SDA> I2c<I2C2, (SCL, SDA)> {
137-
pub fn i2c2<F>(i2c: I2C2, pins: (SCL, SDA), freq: F, clocks: Clocks, apb1: &mut APB1R1) -> Self
138-
where
139-
F: Into<Hertz>,
140-
SCL: SclPin<I2C2>,
141-
SDA: SdaPin<I2C2>,
142-
{
143-
apb1.enr().modify(|_, w| w.i2c2en().set_bit());
144-
apb1.rstr().modify(|_, w| w.i2c2rst().set_bit());
145-
apb1.rstr().modify(|_, w| w.i2c2rst().clear_bit());
146-
Self::new(i2c, pins, freq, clocks)
147-
}
148-
}
147+
hal!(I2C1, i2c1, i2c1en, i2c1rst);
148+
hal!(I2C2, i2c2, i2c2en, i2c2rst);
149149

150150
#[cfg(any(feature = "stm32l4x5", feature = "stm32l4x6"))]
151-
impl<SCL, SDA> I2c<I2C3, (SCL, SDA)> {
152-
pub fn i2c3<F>(i2c: I2C3, pins: (SCL, SDA), freq: F, clocks: Clocks, apb1: &mut APB1R1) -> Self
153-
where
154-
F: Into<Hertz>,
155-
SCL: SclPin<I2C3>,
156-
SDA: SdaPin<I2C3>,
157-
{
158-
apb1.enr().modify(|_, w| w.i2c3en().set_bit());
159-
apb1.rstr().modify(|_, w| w.i2c3rst().set_bit());
160-
apb1.rstr().modify(|_, w| w.i2c3rst().clear_bit());
161-
Self::new(i2c, pins, freq, clocks)
162-
}
163-
}
151+
hal!(I2C3, i2c3, i2c3en, i2c3rst);
164152

165153
impl<SCL, SDA, I2C> I2c<I2C, (SCL, SDA)>
166154
where
@@ -225,14 +213,26 @@ where
225213
(presc, scll, sclh, sdadel, scldel)
226214
};
227215

228-
let presc = u8(presc).unwrap();
216+
macro_rules! u8_or_panic {
217+
($value: expr, $message: literal) => {
218+
match u8($value) {
219+
Ok(value) => value,
220+
Err(_) => panic!($message),
221+
}
222+
};
223+
}
224+
225+
let presc = u8_or_panic!(presc, "I2C pres");
229226
assert!(presc < 16);
230-
let scldel = u8(scldel).unwrap();
227+
228+
let scldel = u8_or_panic!(scldel, "I2C scldel");
231229
assert!(scldel < 16);
232-
let sdadel = u8(sdadel).unwrap();
230+
231+
let sdadel = u8_or_panic!(sdadel, "I2C sdadel");
233232
assert!(sdadel < 16);
234-
let sclh = u8(sclh).unwrap();
235-
let scll = u8(scll).unwrap();
233+
234+
let sclh = u8_or_panic!(sclh, "I2C sclh");
235+
let scll = u8_or_panic!(scll, "I2C scll");
236236

237237
// Configure for "fast mode" (400 KHz)
238238
i2c.timingr.write(|w| {
@@ -472,43 +472,55 @@ where
472472
}
473473
}
474474

475-
use crate::gpio::gpioa::{PA10, PA9};
476-
use crate::gpio::gpiob::{PB10, PB11, PB6, PB7};
477-
478-
#[cfg(any(feature = "stm32l4x3", feature = "stm32l4x5", feature = "stm32l4x6"))]
479-
use crate::gpio::gpioc::{PC0, PC1};
480-
481-
#[cfg(any(
482-
feature = "stm32l4x1",
483-
feature = "stm32l4x2",
484-
feature = "stm32l4x3",
485-
feature = "stm32l4x6",
486-
))]
487-
use crate::gpio::gpiob::PB8;
488-
489-
#[cfg(feature = "stm32l4x2")]
490-
use crate::gpio::gpiob::PB9;
475+
// All parts have I2C1 on alternate function 4 of
476+
// pins PA9/PB6 as SCL and PA10/PB7 as SDA, etc.
477+
mod i2c_pins_default {
478+
use super::{I2C1, I2C2};
479+
use crate::gpio::gpioa::{PA10, PA9};
480+
use crate::gpio::gpiob::{PB10, PB11, PB6, PB7};
481+
use crate::gpio::{Alternate, OpenDrain, Output, AF4};
491482

492-
#[cfg(any(feature = "stm32l4x1", feature = "stm32l4x6"))]
493-
use crate::gpio::gpiob::{PB13, PB14, PB9};
483+
pins!(I2C1, AF4,
484+
SCL: [PA9, PB6],
485+
SDA: [PA10, PB7]);
494486

495-
pins!(I2C1, AF4,
496-
SCL: [PA9, PB6],
497-
SDA: [PA10, PB7]);
498-
499-
pins!(I2C2, AF4, SCL: [PB10], SDA: [PB11]);
487+
pins!(I2C2, AF4, SCL: [PB10], SDA: [PB11]);
488+
}
500489

501490
#[cfg(any(feature = "stm32l4x1", feature = "stm32l4x2", feature = "stm32l4x6"))]
502-
pins!(I2C1, AF4, SCL: [PB8], SDA: [PB9]);
491+
mod i2c_pins_pb8_pb9 {
492+
use super::I2C1;
493+
use crate::gpio::gpiob::{PB8, PB9};
494+
use crate::gpio::{Alternate, OpenDrain, Output, AF4};
495+
496+
pins!(I2C1, AF4, SCL: [PB8], SDA: [PB9]);
497+
}
503498

504499
#[cfg(any(feature = "stm32l4x1", feature = "stm32l4x6"))]
505-
pins!(I2C2, AF4, SCL: [PB13], SDA: [PB14]);
500+
mod i2c_pins_pb13_pb14 {
501+
use super::I2C2;
502+
use crate::gpio::gpiob::{PB13, PB14};
503+
use crate::gpio::{Alternate, OpenDrain, Output, AF4};
506504

507-
#[cfg(any(feature = "stm32l4x5", feature = "stm32l4x6"))]
508-
pins!(I2C3, AF4, SCL: [PC0], SDA: [PC1]);
505+
pins!(I2C2, AF4, SCL: [PB13], SDA: [PB14]);
506+
}
509507

510-
#[cfg(feature = "stm32l4x3")]
511-
pins!(I2C1, AF4, SCL: [PB8], SDA: []);
508+
#[cfg(any(feature = "stm32l4x3", feature = "stm32l4x5", feature = "stm32l4x6"))]
509+
mod i2c_pins_pbc0_pc1 {
510+
use super::I2C3;
511+
use crate::gpio::gpioc::{PC0, PC1};
512+
use crate::gpio::{Alternate, OpenDrain, Output, AF4};
513+
514+
pins!(I2C3, AF4, SCL: [PC0], SDA: [PC1]);
515+
}
512516

513517
#[cfg(feature = "stm32l4x3")]
514-
pins!(I2C2, AF4, SCL: [PC0], SDA: [PC1]);
518+
mod i2c_pins_pa7_pb4 {
519+
use super::I2C3;
520+
use crate::gpio::gpioa::PA7;
521+
use crate::gpio::gpiob::PB4;
522+
use crate::gpio::{Alternate, OpenDrain, Output, AF4};
523+
524+
// These pins aren't as nicely consistent
525+
pins!(I2C3, AF4, SCL: [PA7], SDA: [PB4]);
526+
}

0 commit comments

Comments
 (0)