Skip to content

Commit 2aa1d1b

Browse files
Generalize i2c and port to i2c2
1 parent a51bb0e commit 2aa1d1b

File tree

1 file changed

+68
-26
lines changed

1 file changed

+68
-26
lines changed

src/i2c.rs

+68-26
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
#[cfg(any(feature = "stm32f042", feature = "stm32f030"))]
2-
use crate::stm32::{I2C1, RCC};
1+
use core::ops::Deref;
32

43
use crate::stm32;
54
use embedded_hal::blocking::i2c::{Write, WriteRead};
@@ -65,32 +64,71 @@ i2c_pins! {
6564
sda => [gpiob::PB14<Alternate<AF5>>, gpiof::PF0<Alternate<AF1>>],
6665
}
6766
}
67+
#[cfg(any(feature = "stm32f030x8", feature = "stm32f030xc"))]
68+
i2c_pins! {
69+
I2C2 => {
70+
scl => [gpiob::PB10<Alternate<AF1>>],
71+
sda => [gpiob::PB11<Alternate<AF1>>],
72+
}
73+
}
74+
#[cfg(feature = "stm32f030xc")]
75+
i2c_pins! {
76+
I2C2 => {
77+
scl => [gpiob::PB13<Alternate<AF5>>],
78+
sda => [gpiob::PB14<Alternate<AF5>>],
79+
}
80+
}
6881

6982
#[derive(Debug)]
7083
pub enum Error {
7184
OVERRUN,
7285
NACK,
7386
}
7487

88+
macro_rules! i2c {
89+
($($I2C:ident: ($i2c:ident, $i2cXen:ident, $i2cXrst:ident, $apbenr:ident, $apbrstr:ident),)+) => {
90+
$(
91+
use crate::stm32::$I2C;
92+
impl<SCLPIN, SDAPIN> I2c<$I2C, SCLPIN, SDAPIN> {
93+
pub fn $i2c(i2c: $I2C, pins: (SCLPIN, SDAPIN), speed: KiloHertz) -> Self
94+
where
95+
SCLPIN: SclPin<$I2C>,
96+
SDAPIN: SdaPin<$I2C>,
97+
{
98+
// NOTE(unsafe) This executes only during initialisation
99+
let rcc = unsafe { &(*stm32::RCC::ptr()) };
100+
101+
/* Enable clock for I2C */
102+
rcc.$apbenr.modify(|_, w| w.$i2cXen().set_bit());
103+
104+
/* Reset I2C */
105+
rcc.$apbrstr.modify(|_, w| w.$i2cXrst().set_bit());
106+
rcc.$apbrstr.modify(|_, w| w.$i2cXrst().clear_bit());
107+
I2c { i2c, pins }.i2c_init(speed)
108+
}
109+
}
110+
)+
111+
}
112+
}
75113
#[cfg(any(feature = "stm32f042", feature = "stm32f030"))]
76-
impl<SCLPIN, SDAPIN> I2c<I2C1, SCLPIN, SDAPIN> {
77-
pub fn i2c1(i2c: I2C1, pins: (SCLPIN, SDAPIN), speed: KiloHertz) -> Self
78-
where
79-
SCLPIN: SclPin<I2C1>,
80-
SDAPIN: SdaPin<I2C1>,
81-
{
82-
// NOTE(unsafe) This executes only during initialisation
83-
let rcc = unsafe { &(*RCC::ptr()) };
84-
85-
/* Enable clock for I2C1 */
86-
rcc.apb1enr.modify(|_, w| w.i2c1en().set_bit());
87-
88-
/* Reset I2C1 */
89-
rcc.apb1rstr.modify(|_, w| w.i2c1rst().set_bit());
90-
rcc.apb1rstr.modify(|_, w| w.i2c1rst().clear_bit());
114+
i2c! {
115+
I2C1: (i2c1, i2c1en, i2c1rst, apb1enr, apb1rstr),
116+
}
117+
#[cfg(any(feature = "stm32f030xc", feature = "stm32f030xc"))]
118+
i2c! {
119+
I2C2: (i2c2, i2c2en, i2c2rst, apb1enr, apb1rstr),
120+
}
91121

122+
// It's s needed for the impls, but rustc doesn't recognize that
123+
#[allow(dead_code)]
124+
type I2cRegisterBlock = stm32::i2c1::RegisterBlock;
125+
impl<I2C, SCLPIN, SDAPIN> I2c<I2C, SCLPIN, SDAPIN>
126+
where
127+
I2C: Deref<Target = I2cRegisterBlock>,
128+
{
129+
fn i2c_init(self: Self, speed: KiloHertz) -> Self {
92130
/* Make sure the I2C unit is disabled so we can configure it */
93-
i2c.cr1.modify(|_, w| w.pe().clear_bit());
131+
self.i2c.cr1.modify(|_, w| w.pe().clear_bit());
94132

95133
// Calculate settings for I2C speed modes
96134
let presc;
@@ -118,7 +156,7 @@ impl<SCLPIN, SDAPIN> I2c<I2C1, SCLPIN, SDAPIN> {
118156
}
119157

120158
/* Enable I2C signal generator, and configure I2C for 400KHz full speed */
121-
i2c.timingr.write(|w| {
159+
self.i2c.timingr.write(|w| {
122160
w.presc()
123161
.bits(presc)
124162
.scldel()
@@ -132,12 +170,12 @@ impl<SCLPIN, SDAPIN> I2c<I2C1, SCLPIN, SDAPIN> {
132170
});
133171

134172
/* Enable the I2C processing */
135-
i2c.cr1.modify(|_, w| w.pe().set_bit());
173+
self.i2c.cr1.modify(|_, w| w.pe().set_bit());
136174

137-
I2c { i2c, pins }
175+
self
138176
}
139177

140-
pub fn release(self) -> (I2C1, (SCLPIN, SDAPIN)) {
178+
pub fn release(self) -> (I2C, (SCLPIN, SDAPIN)) {
141179
(self.i2c, self.pins)
142180
}
143181

@@ -166,8 +204,10 @@ impl<SCLPIN, SDAPIN> I2c<I2C1, SCLPIN, SDAPIN> {
166204
}
167205
}
168206

169-
#[cfg(any(feature = "stm32f042", feature = "stm32f030"))]
170-
impl<SCLPIN, SDAPIN> WriteRead for I2c<I2C1, SCLPIN, SDAPIN> {
207+
impl<I2C, SCLPIN, SDAPIN> WriteRead for I2c<I2C, SCLPIN, SDAPIN>
208+
where
209+
I2C: Deref<Target = I2cRegisterBlock>,
210+
{
171211
type Error = Error;
172212

173213
fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Error> {
@@ -244,8 +284,10 @@ impl<SCLPIN, SDAPIN> WriteRead for I2c<I2C1, SCLPIN, SDAPIN> {
244284
}
245285
}
246286

247-
#[cfg(any(feature = "stm32f042", feature = "stm32f030"))]
248-
impl<SCLPIN, SDAPIN> Write for I2c<I2C1, SCLPIN, SDAPIN> {
287+
impl<I2C, SCLPIN, SDAPIN> Write for I2c<I2C, SCLPIN, SDAPIN>
288+
where
289+
I2C: Deref<Target = I2cRegisterBlock>,
290+
{
249291
type Error = Error;
250292

251293
fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error> {

0 commit comments

Comments
 (0)