1use core::ops::Deref;
2
3use embedded_hal::blocking::i2c::{Read, Write, WriteRead};
4
5use crate::{
6 gpio::*,
7 rcc::Rcc,
8 time::{KiloHertz, U32Ext},
9};
10
11pub struct I2c<I2C, SCLPIN, SDAPIN> {
13 i2c: I2C,
14 pins: (SCLPIN, SDAPIN),
15}
16
17pub trait SclPin<I2C> {}
18pub trait SdaPin<I2C> {}
19
20macro_rules! i2c_pins {
21 ($($I2C:ident => {
22 scl => [$($scl:ty),+ $(,)*],
23 sda => [$($sda:ty),+ $(,)*],
24 })+) => {
25 $(
26 $(
27 impl SclPin<crate::pac::$I2C> for $scl {}
28 )+
29 $(
30 impl SdaPin<crate::pac::$I2C> for $sda {}
31 )+
32 )+
33 }
34}
35
36#[cfg(any(
37 feature = "stm32f030",
38 feature = "stm32f031",
39 feature = "stm32f038",
40 feature = "stm32f042",
41 feature = "stm32f048",
42 feature = "stm32f051",
43 feature = "stm32f058",
44 feature = "stm32f070",
45 feature = "stm32f071",
46 feature = "stm32f072",
47 feature = "stm32f078",
48 feature = "stm32f091",
49 feature = "stm32f098",
50))]
51i2c_pins! {
52 I2C1 => {
53 scl => [gpiob::PB6<Alternate<AF1>>, gpiob::PB8<Alternate<AF1>>],
54 sda => [gpiob::PB7<Alternate<AF1>>, gpiob::PB9<Alternate<AF1>>],
55 }
56}
57#[cfg(any(
58 feature = "stm32f030x4",
59 feature = "stm32f030x6",
60 feature = "stm32f030xc",
61 feature = "stm32f031",
62 feature = "stm32f038",
63 feature = "stm32f042",
64 feature = "stm32f048",
65 feature = "stm32f070x6",
66 feature = "stm32f091",
67 feature = "stm32f098",
68))]
69i2c_pins! {
70 I2C1 => {
71 scl => [gpioa::PA9<Alternate<AF4>>],
72 sda => [gpioa::PA10<Alternate<AF4>>],
73 }
74}
75#[cfg(any(feature = "stm32f042", feature = "stm32f048"))]
76i2c_pins! {
77 I2C1 => {
78 scl => [gpioa::PA11<Alternate<AF5>>],
79 sda => [gpioa::PA12<Alternate<AF5>>],
80 }
81}
82#[cfg(any(
83 feature = "stm32f030x4",
84 feature = "stm32f030x6",
85 feature = "stm32f031",
86 feature = "stm32f038",
87 feature = "stm32f042",
88 feature = "stm32f048",
89))]
90i2c_pins! {
91 I2C1 => {
92 scl => [gpiob::PB10<Alternate<AF1>>],
93 sda => [gpiob::PB11<Alternate<AF1>>],
94 }
95}
96#[cfg(any(feature = "stm32f030xc", feature = "stm32f042", feature = "stm32f048"))]
97i2c_pins! {
98 I2C1 => {
99 scl => [gpiob::PB13<Alternate<AF5>>],
100 sda => [gpiob::PB14<Alternate<AF5>>],
101 }
102}
103#[cfg(any(
104 feature = "stm32f030xc",
105 feature = "stm32f042",
106 feature = "stm32f048",
107 feature = "stm32f070x6",
108 feature = "stm32f091",
109 feature = "stm32f098",
110))]
111i2c_pins! {
112 I2C1 => {
113 scl => [gpiof::PF1<Alternate<AF1>>],
114 sda => [gpiof::PF0<Alternate<AF1>>],
115 }
116}
117
118#[cfg(any(feature = "stm32f030x8", feature = "stm32f051", feature = "stm32f058"))]
119i2c_pins! {
120 I2C2 => {
121 scl => [gpiob::PB10<Alternate<AF1>>],
122 sda => [gpiob::PB11<Alternate<AF1>>],
123 }
124}
125#[cfg(any(
126 feature = "stm32f030xc",
127 feature = "stm32f070xb",
128 feature = "stm32f071",
129 feature = "stm32f072",
130 feature = "stm32f078",
131 feature = "stm32f091",
132 feature = "stm32f098",
133))]
134i2c_pins! {
135 I2C2 => {
136 scl => [gpiob::PB10<Alternate<AF1>>, gpiob::PB13<Alternate<AF5>>],
137 sda => [gpiob::PB11<Alternate<AF1>>, gpiob::PB14<Alternate<AF5>>],
138 }
139}
140#[cfg(any(feature = "stm32f091", feature = "stm32f098"))]
141i2c_pins! {
142 I2C2 => {
143 scl => [gpioa::PA11<Alternate<AF5>>],
144 sda => [gpioa::PA12<Alternate<AF5>>],
145 }
146}
147
148#[derive(Debug)]
149pub enum Error {
150 OVERRUN,
151 NACK,
152 BUS,
153}
154
155macro_rules! i2c {
156 ($($I2C:ident: ($i2c:ident, $i2cXen:ident, $i2cXrst:ident, $apbenr:ident, $apbrstr:ident),)+) => {
157 $(
158 use crate::pac::$I2C;
159 impl<SCLPIN, SDAPIN> I2c<$I2C, SCLPIN, SDAPIN> {
160 pub fn $i2c(i2c: $I2C, pins: (SCLPIN, SDAPIN), speed: KiloHertz, rcc: &mut Rcc) -> Self
161 where
162 SCLPIN: SclPin<$I2C>,
163 SDAPIN: SdaPin<$I2C>,
164 {
165 rcc.regs.$apbenr.modify(|_, w| w.$i2cXen().set_bit());
167
168 rcc.regs.$apbrstr.modify(|_, w| w.$i2cXrst().set_bit());
170 rcc.regs.$apbrstr.modify(|_, w| w.$i2cXrst().clear_bit());
171 I2c { i2c, pins }.i2c_init(speed)
172 }
173 }
174 )+
175 }
176}
177
178i2c! {
179 I2C1: (i2c1, i2c1en, i2c1rst, apb1enr, apb1rstr),
180}
181
182#[cfg(any(
183 feature = "stm32f030x8",
184 feature = "stm32f030xc",
185 feature = "stm32f051",
186 feature = "stm32f058",
187 feature = "stm32f070xb",
188 feature = "stm32f071",
189 feature = "stm32f072",
190 feature = "stm32f078",
191 feature = "stm32f091",
192 feature = "stm32f098",
193))]
194i2c! {
195 I2C2: (i2c2, i2c2en, i2c2rst, apb1enr, apb1rstr),
196}
197
198#[allow(dead_code)]
200type I2cRegisterBlock = crate::pac::i2c1::RegisterBlock;
201
202impl<I2C, SCLPIN, SDAPIN> I2c<I2C, SCLPIN, SDAPIN>
203where
204 I2C: Deref<Target = I2cRegisterBlock>,
205{
206 fn i2c_init(self, speed: KiloHertz) -> Self {
207 use core::cmp;
208
209 self.i2c.cr1.modify(|_, w| w.pe().clear_bit());
211
212 let presc;
214 let scldel;
215 let sdadel;
216 let sclh;
217 let scll;
218
219 const FREQ: u32 = 8_000_000;
221
222 if speed <= 100_u32.khz() {
224 presc = 1;
225 scll = cmp::max((((FREQ >> presc) >> 1) / speed.0) - 1, 255) as u8;
226 sclh = scll - 4;
227 sdadel = 2;
228 scldel = 4;
229 } else {
230 presc = 0;
231 scll = cmp::max((((FREQ >> presc) >> 1) / speed.0) - 1, 255) as u8;
232 sclh = scll - 6;
233 sdadel = 1;
234 scldel = 3;
235 }
236
237 self.i2c.timingr.write(|w| {
239 w.presc()
240 .bits(presc)
241 .scldel()
242 .bits(scldel)
243 .sdadel()
244 .bits(sdadel)
245 .sclh()
246 .bits(sclh)
247 .scll()
248 .bits(scll)
249 });
250
251 self.i2c.cr1.modify(|_, w| w.pe().set_bit());
253
254 self
255 }
256
257 pub fn release(self) -> (I2C, (SCLPIN, SDAPIN)) {
258 (self.i2c, self.pins)
259 }
260
261 fn check_and_clear_error_flags(&self, isr: &crate::stm32::i2c1::isr::R) -> Result<(), Error> {
262 if isr.ovr().bit_is_set() {
264 self.i2c.icr.write(|w| w.ovrcf().set_bit());
265 return Err(Error::OVERRUN);
266 }
267
268 if isr.arlo().bit_is_set() | isr.berr().bit_is_set() {
270 self.i2c
271 .icr
272 .write(|w| w.arlocf().set_bit().berrcf().set_bit());
273 return Err(Error::BUS);
274 }
275
276 if isr.nackf().bit_is_set() {
278 self.i2c
279 .icr
280 .write(|w| w.stopcf().set_bit().nackcf().set_bit());
281 return Err(Error::NACK);
282 }
283
284 Ok(())
285 }
286
287 fn send_byte(&self, byte: u8) -> Result<(), Error> {
288 loop {
290 let isr = self.i2c.isr.read();
291 self.check_and_clear_error_flags(&isr)?;
292 if isr.txis().bit_is_set() {
293 break;
294 }
295 }
296
297 self.i2c.txdr.write(|w| unsafe { w.bits(u32::from(byte)) });
299
300 self.check_and_clear_error_flags(&self.i2c.isr.read())?;
301 Ok(())
302 }
303
304 fn recv_byte(&self) -> Result<u8, Error> {
305 loop {
306 let isr = self.i2c.isr.read();
307 self.check_and_clear_error_flags(&isr)?;
308 if isr.rxne().bit_is_set() {
309 break;
310 }
311 }
312
313 let value = self.i2c.rxdr.read().bits() as u8;
314 Ok(value)
315 }
316}
317
318impl<I2C, SCLPIN, SDAPIN> WriteRead for I2c<I2C, SCLPIN, SDAPIN>
319where
320 I2C: Deref<Target = I2cRegisterBlock>,
321{
322 type Error = Error;
323
324 fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Error> {
325 self.i2c.cr2.modify(|_, w| {
327 w.sadd()
328 .bits(u16::from(addr) << 1)
329 .nbytes()
330 .bits(bytes.len() as u8)
331 .rd_wrn()
332 .clear_bit()
333 .autoend()
334 .clear_bit()
335 });
336
337 self.i2c.cr2.modify(|_, w| w.start().set_bit());
339
340 loop {
342 let isr = self.i2c.isr.read();
343 self.check_and_clear_error_flags(&isr)?;
344 if isr.txis().bit_is_set() || isr.tc().bit_is_set() {
345 break;
346 }
347 }
348
349 for c in bytes {
351 self.send_byte(*c)?;
352 }
353
354 loop {
356 let isr = self.i2c.isr.read();
357 self.check_and_clear_error_flags(&isr)?;
358 if isr.tc().bit_is_set() {
359 break;
360 }
361 }
362
363 self.i2c.cr2.modify(|_, w| {
365 w.sadd()
366 .bits(u16::from(addr) << 1)
367 .nbytes()
368 .bits(buffer.len() as u8)
369 .rd_wrn()
370 .set_bit()
371 });
372
373 self.i2c.cr2.modify(|_, w| w.start().set_bit());
375
376 self.i2c.cr2.modify(|_, w| w.autoend().set_bit());
378
379 for c in buffer.iter_mut() {
381 *c = self.recv_byte()?;
382 }
383
384 self.check_and_clear_error_flags(&self.i2c.isr.read())?;
386
387 Ok(())
388 }
389}
390
391impl<I2C, SCLPIN, SDAPIN> Read for I2c<I2C, SCLPIN, SDAPIN>
392where
393 I2C: Deref<Target = I2cRegisterBlock>,
394{
395 type Error = Error;
396
397 fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Error> {
398 self.i2c.cr2.modify(|_, w| {
400 w.sadd()
401 .bits(u16::from(addr) << 1)
402 .nbytes()
403 .bits(buffer.len() as u8)
404 .rd_wrn()
405 .set_bit()
406 });
407
408 self.i2c.cr2.modify(|_, w| w.start().set_bit());
410
411 self.i2c.cr2.modify(|_, w| w.autoend().set_bit());
413
414 for c in buffer.iter_mut() {
416 *c = self.recv_byte()?;
417 }
418
419 self.check_and_clear_error_flags(&self.i2c.isr.read())?;
421
422 Ok(())
423 }
424}
425
426impl<I2C, SCLPIN, SDAPIN> Write for I2c<I2C, SCLPIN, SDAPIN>
427where
428 I2C: Deref<Target = I2cRegisterBlock>,
429{
430 type Error = Error;
431
432 fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error> {
433 self.i2c.cr2.modify(|_, w| {
435 w.sadd()
436 .bits(u16::from(addr) << 1)
437 .nbytes()
438 .bits(bytes.len() as u8)
439 .rd_wrn()
440 .clear_bit()
441 .autoend()
442 .set_bit()
443 });
444
445 self.i2c.cr2.modify(|_, w| w.start().set_bit());
447
448 for c in bytes {
450 self.send_byte(*c)?;
451 }
452
453 self.check_and_clear_error_flags(&self.i2c.isr.read())?;
455
456 Ok(())
457 }
458}