Skip to content

Commit a021893

Browse files
authored
Merge pull request #782 from stm32-rs/fmpi2c-common
FMPI2c clean
2 parents bd60a44 + 3695d06 commit a021893

File tree

6 files changed

+86
-84
lines changed

6 files changed

+86
-84
lines changed

examples/display-touch.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use embedded_graphics_07::{
3232
};
3333

3434
#[cfg(feature = "stm32f413")]
35-
use stm32f4xx_hal::fmpi2c::FMPI2c;
35+
use stm32f4xx_hal::fmpi2c::I2c;
3636
#[cfg(feature = "stm32f412")]
3737
use stm32f4xx_hal::i2c::I2c;
3838

@@ -153,7 +153,7 @@ fn main() -> ! {
153153
// STM32F413 uses FMPI2C1 type.
154154
// The pins are mentioned in documentation -um2135-discovery-kit-with-stm32f413zh-mcu-stmicroelectronics
155155
#[cfg(feature = "stm32f413")]
156-
let mut i2c = { FMPI2c::new(p.FMPI2C1, (gpioc.pc6, gpioc.pc7), 400.kHz()) };
156+
let mut i2c = { I2c::new(p.FMPI2C1, (gpioc.pc6, gpioc.pc7), 400.kHz()) };
157157

158158
#[cfg(feature = "stm32f412")]
159159
let ts_int = gpiog.pg5.into_pull_down_input();

src/fmpi2c.rs

Lines changed: 69 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,54 +2,67 @@ use core::ops::Deref;
22

33
use crate::gpio;
44
use crate::i2c::{Error, NoAcknowledgeSource};
5-
use crate::pac::{fmpi2c1, FMPI2C1, RCC};
6-
use crate::rcc::{Enable, Reset};
5+
use crate::pac::fmpi2c1 as i2c1;
6+
use crate::pac::{self, RCC};
7+
use crate::rcc::{BusClock, Enable, Reset};
78
use fugit::{HertzU32 as Hertz, RateExtU32};
89

10+
// Old names
11+
pub use I2c as FmpI2c;
12+
pub use Mode as FmpMode;
13+
914
mod hal_02;
1015
mod hal_1;
1116

1217
pub trait Instance:
1318
crate::Sealed
14-
+ crate::Ptr<RB = fmpi2c1::RegisterBlock>
19+
+ crate::Ptr<RB = i2c1::RegisterBlock>
1520
+ Deref<Target = Self::RB>
1621
+ Enable
1722
+ Reset
23+
+ BusClock
1824
+ gpio::alt::I2cCommon
1925
{
2026
fn clock_hsi(rcc: &crate::pac::rcc::RegisterBlock);
2127
}
2228

23-
impl Instance for FMPI2C1 {
24-
fn clock_hsi(rcc: &crate::pac::rcc::RegisterBlock) {
25-
rcc.dckcfgr2().modify(|_, w| w.fmpi2c1sel().hsi());
26-
}
27-
}
29+
macro_rules! i2c {
30+
($I2C:ty, $i2csel:ident, $I2Calias:ident) => {
31+
pub type $I2Calias = I2c<$I2C>;
2832

29-
impl crate::Ptr for FMPI2C1 {
30-
type RB = fmpi2c1::RegisterBlock;
31-
#[inline(always)]
32-
fn ptr() -> *const Self::RB {
33-
Self::ptr()
34-
}
33+
impl Instance for $I2C {
34+
fn clock_hsi(rcc: &crate::pac::rcc::RegisterBlock) {
35+
rcc.dckcfgr2().modify(|_, w| w.$i2csel().hsi());
36+
}
37+
}
38+
39+
impl crate::Ptr for $I2C {
40+
type RB = i2c1::RegisterBlock;
41+
#[inline(always)]
42+
fn ptr() -> *const Self::RB {
43+
Self::ptr()
44+
}
45+
}
46+
};
3547
}
3648

49+
#[cfg(feature = "fmpi2c1")]
50+
i2c!(pac::FMPI2C1, fmpi2c1sel, FMPI2c1);
51+
3752
/// I2C FastMode+ abstraction
38-
pub struct FMPI2c<I2C: Instance> {
53+
pub struct I2c<I2C: Instance> {
3954
i2c: I2C,
4055
pins: (I2C::Scl, I2C::Sda),
4156
}
4257

43-
pub type FMPI2c1 = FMPI2c<FMPI2C1>;
44-
45-
#[derive(Debug, PartialEq)]
46-
pub enum FmpMode {
58+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
59+
pub enum Mode {
4760
Standard { frequency: Hertz },
4861
Fast { frequency: Hertz },
4962
FastPlus { frequency: Hertz },
5063
}
5164

52-
impl FmpMode {
65+
impl Mode {
5366
pub fn standard(frequency: Hertz) -> Self {
5467
Self::Standard { frequency }
5568
}
@@ -71,7 +84,7 @@ impl FmpMode {
7184
}
7285
}
7386

74-
impl From<Hertz> for FmpMode {
87+
impl From<Hertz> for Mode {
7588
fn from(frequency: Hertz) -> Self {
7689
let k100: Hertz = 100.kHz();
7790
let k400: Hertz = 400.kHz();
@@ -85,26 +98,39 @@ impl From<Hertz> for FmpMode {
8598
}
8699
}
87100

88-
impl<I2C: Instance> FMPI2c<I2C> {
101+
pub trait I2cExt: Sized + Instance {
102+
fn i2c<'a>(
103+
self,
104+
pins: (impl Into<Self::Scl>, impl Into<Self::Sda>),
105+
mode: impl Into<Mode>,
106+
) -> I2c<Self>;
107+
}
108+
109+
impl<I2C: Instance> I2cExt for I2C {
110+
fn i2c<'a>(
111+
self,
112+
pins: (impl Into<Self::Scl>, impl Into<Self::Sda>),
113+
mode: impl Into<Mode>,
114+
) -> I2c<Self> {
115+
I2c::new(self, pins, mode)
116+
}
117+
}
118+
119+
impl<I2C: Instance> I2c<I2C> {
89120
pub fn new(
90121
i2c: I2C,
91122
pins: (impl Into<I2C::Scl>, impl Into<I2C::Sda>),
92-
mode: impl Into<FmpMode>,
123+
mode: impl Into<Mode>,
93124
) -> Self {
94125
unsafe {
95-
// NOTE(unsafe) this reference will only be used for atomic writes with no side effects.
96-
let rcc = &(*RCC::ptr());
97-
98126
// Enable and reset clock.
99-
I2C::enable(rcc);
100-
I2C::reset(rcc);
101-
102-
I2C::clock_hsi(rcc);
127+
I2C::enable_unchecked();
128+
I2C::reset_unchecked();
103129
}
104130

105131
let pins = (pins.0.into(), pins.1.into());
106132

107-
let i2c = FMPI2c { i2c, pins };
133+
let i2c = I2c { i2c, pins };
108134
i2c.i2c_init(mode);
109135
i2c
110136
}
@@ -114,14 +140,18 @@ impl<I2C: Instance> FMPI2c<I2C> {
114140
}
115141
}
116142

117-
impl<I2C: Instance> FMPI2c<I2C> {
118-
fn i2c_init<M: Into<FmpMode>>(&self, mode: M) {
143+
impl<I2C: Instance> I2c<I2C> {
144+
fn i2c_init(&self, mode: impl Into<Mode>) {
119145
let mode = mode.into();
120146
use core::cmp;
121147

122148
// Make sure the I2C unit is disabled so we can configure it
123149
self.i2c.cr1().modify(|_, w| w.pe().clear_bit());
124150

151+
// NOTE(unsafe) this reference will only be used for atomic writes with no side effects.
152+
let rcc = unsafe { &(*RCC::ptr()) };
153+
I2C::clock_hsi(rcc);
154+
125155
// Calculate settings for I2C speed modes
126156
let presc;
127157
let scldel;
@@ -135,21 +165,21 @@ impl<I2C: Instance> FMPI2c<I2C> {
135165
// Normal I2C speeds use a different scaling than fast mode below and fast mode+ even more
136166
// below
137167
match mode {
138-
FmpMode::Standard { frequency } => {
168+
Mode::Standard { frequency } => {
139169
presc = 3;
140170
scll = cmp::max((((FREQ >> presc) >> 1) / frequency.raw()) - 1, 255) as u8;
141171
sclh = scll - 4;
142172
sdadel = 2;
143173
scldel = 4;
144174
}
145-
FmpMode::Fast { frequency } => {
175+
Mode::Fast { frequency } => {
146176
presc = 1;
147177
scll = cmp::max((((FREQ >> presc) >> 1) / frequency.raw()) - 1, 255) as u8;
148178
sclh = scll - 6;
149179
sdadel = 2;
150180
scldel = 3;
151181
}
152-
FmpMode::FastPlus { frequency } => {
182+
Mode::FastPlus { frequency } => {
153183
presc = 0;
154184
scll = cmp::max((((FREQ >> presc) >> 1) / frequency.raw()) - 4, 255) as u8;
155185
sclh = scll - 2;
@@ -171,7 +201,8 @@ impl<I2C: Instance> FMPI2c<I2C> {
171201
self.i2c.cr1().modify(|_, w| w.pe().set_bit());
172202
}
173203

174-
fn check_and_clear_error_flags(&self, isr: &fmpi2c1::isr::R) -> Result<(), Error> {
204+
#[inline(always)]
205+
fn check_and_clear_error_flags(&self, isr: &i2c1::isr::R) -> Result<(), Error> {
175206
// If we received a NACK, then this is an error
176207
if isr.nackf().bit_is_set() {
177208
self.i2c
@@ -183,6 +214,7 @@ impl<I2C: Instance> FMPI2c<I2C> {
183214
Ok(())
184215
}
185216

217+
#[inline(always)]
186218
fn end_transaction(&self) -> Result<(), Error> {
187219
// Check and clear flags if they somehow ended up set
188220
self.check_and_clear_error_flags(&self.i2c.isr().read())

src/fmpi2c/hal_02.rs

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,24 @@
11
mod blocking {
2-
use super::super::{fmpi2c1, Error, FMPI2c, Instance};
3-
use core::ops::Deref;
2+
use super::super::{Error, I2c, Instance};
43
use embedded_hal_02::blocking::i2c::{Read, Write, WriteRead};
54

6-
impl<I2C: Instance> WriteRead for FMPI2c<I2C>
7-
where
8-
I2C: Deref<Target = fmpi2c1::RegisterBlock>,
9-
{
5+
impl<I2C: Instance> WriteRead for I2c<I2C> {
106
type Error = Error;
117

128
fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Error> {
139
self.write_read(addr, bytes, buffer)
1410
}
1511
}
1612

17-
impl<I2C: Instance> Read for FMPI2c<I2C>
18-
where
19-
I2C: Deref<Target = fmpi2c1::RegisterBlock>,
20-
{
13+
impl<I2C: Instance> Read for I2c<I2C> {
2114
type Error = Error;
2215

2316
fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Error> {
2417
self.read(addr, buffer)
2518
}
2619
}
2720

28-
impl<I2C: Instance> Write for FMPI2c<I2C>
29-
where
30-
I2C: Deref<Target = fmpi2c1::RegisterBlock>,
31-
{
21+
impl<I2C: Instance> Write for I2c<I2C> {
3222
type Error = Error;
3323

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

src/fmpi2c/hal_1.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,15 @@ use embedded_hal::i2c::ErrorType;
22

33
use super::Instance;
44

5-
impl<I2C: Instance> ErrorType for super::FMPI2c<I2C> {
5+
impl<I2C: Instance> ErrorType for super::I2c<I2C> {
66
type Error = super::Error;
77
}
88

99
mod blocking {
10-
use super::super::{fmpi2c1, FMPI2c, Instance};
11-
use core::ops::Deref;
10+
use super::super::{I2c, Instance};
1211
use embedded_hal::i2c::Operation;
1312

14-
impl<I2C: Instance> embedded_hal::i2c::I2c for FMPI2c<I2C>
15-
where
16-
I2C: Deref<Target = fmpi2c1::RegisterBlock>,
17-
{
13+
impl<I2C: Instance> embedded_hal::i2c::I2c for I2c<I2C> {
1814
fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
1915
self.read(addr, buffer)
2016
}

src/i2c/hal_02.rs

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ mod blocking {
44
Operation, Read, Transactional, Write, WriteIter, WriteIterRead, WriteRead,
55
};
66

7-
impl<I2C> WriteRead for I2c<I2C>
8-
where
9-
I2C: Instance,
10-
{
7+
impl<I2C: Instance> WriteRead for I2c<I2C> {
118
type Error = Error;
129

1310
fn write_read(
@@ -20,10 +17,7 @@ mod blocking {
2017
}
2118
}
2219

23-
impl<I2C> WriteIterRead for I2c<I2C>
24-
where
25-
I2C: Instance,
26-
{
20+
impl<I2C: Instance> WriteIterRead for I2c<I2C> {
2721
type Error = Error;
2822

2923
fn write_iter_read<B>(
@@ -39,21 +33,15 @@ mod blocking {
3933
}
4034
}
4135

42-
impl<I2C> Write for I2c<I2C>
43-
where
44-
I2C: Instance,
45-
{
36+
impl<I2C: Instance> Write for I2c<I2C> {
4637
type Error = Error;
4738

4839
fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> {
4940
self.write(addr, bytes)
5041
}
5142
}
5243

53-
impl<I2C> WriteIter for I2c<I2C>
54-
where
55-
I2C: Instance,
56-
{
44+
impl<I2C: Instance> WriteIter for I2c<I2C> {
5745
type Error = Error;
5846

5947
fn write<B>(&mut self, addr: u8, bytes: B) -> Result<(), Self::Error>
@@ -64,21 +52,15 @@ mod blocking {
6452
}
6553
}
6654

67-
impl<I2C> Read for I2c<I2C>
68-
where
69-
I2C: Instance,
70-
{
55+
impl<I2C: Instance> Read for I2c<I2C> {
7156
type Error = Error;
7257

7358
fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
7459
self.read(addr, buffer)
7560
}
7661
}
7762

78-
impl<I2C> Transactional for I2c<I2C>
79-
where
80-
I2C: Instance,
81-
{
63+
impl<I2C: Instance> Transactional for I2c<I2C> {
8264
type Error = Error;
8365

8466
fn exec(

src/prelude.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ pub use crate::dma::traits::DmaEventExt as _;
5555
pub use crate::dma::traits::DmaFlagExt as _;
5656
pub use crate::dma::traits::Stream as _;
5757
pub use crate::dma::traits::StreamISR as _;
58+
#[cfg(feature = "fmpi2c1")]
59+
pub use crate::fmpi2c::I2cExt as _;
5860
pub use crate::gpio::outport::OutPort as _;
5961
pub use crate::gpio::ExtiPin as _stm32f4xx_hal_gpio_ExtiPin;
6062
pub use crate::gpio::GpioExt as _stm32f4xx_hal_gpio_GpioExt;

0 commit comments

Comments
 (0)