stm32g0xx_hal/i2c/
blocking.rs

1//! I2C
2use crate::gpio::*;
3use crate::i2c::config::Config;
4use crate::i2c::{self, Error, I2c, I2cDirection, I2cExt, SCLPin, SDAPin};
5use crate::rcc::*;
6use crate::stm32::{I2C1, I2C2};
7use hal::blocking::i2c::{Read, Write, WriteRead};
8
9pub trait I2cSlave {
10    /// Enable/Disable Slave Byte Control. Default SBC is switched on.
11    /// For master write/read the transaction should start with sbc disabled.
12    /// So ACK will be send on the last received byte.
13    /// Before the send phase SBC should be enabled again.
14    fn slave_sbc(&mut self, sbc_enabled: bool);
15
16    /// An optional tuple is returned with the address as sent by the master. The address is for 7 bit in range of 0..127
17    fn slave_addressed(&mut self) -> Result<Option<(u16, I2cDirection)>, Error>;
18
19    /// Wait until this slave is addressed by the master.
20    /// A tuple is returned with the address as sent by the master. The address is for 7 bit in range of 0..127
21    fn slave_wait_addressed(&mut self) -> Result<(u16, I2cDirection), Error>;
22
23    /// Start reading the bytes, send by the master . If OK returned, all bytes are transferred
24    /// If the master want to send more bytes than the slave can recieve the slave will NACK the n+1 byte
25    /// In this case the function will return IncorrectFrameSize(bytes.len() + 1)
26    /// If the master did send a STOP before all bytes are recieve, the slave will return IncorrectFrameSize(actual nr of bytes send)
27    fn slave_read(&mut self, bytes: &mut [u8]) -> Result<(), Error>;
28
29    /// Start writing the bytes, the master want to receive. If OK returned, all bytes are transferred
30    /// If the master wants more data than bytes.len()  the master will run into a timeout, This function will return Ok(())
31    /// If the master wants less data than bytes.len(), the function will return  IncorrectFrameSize(bytes.len() + 1)
32    fn slave_write(&mut self, bytes: &[u8]) -> Result<(), Error>;
33}
34
35/// Sequence to flush the TXDR register. This resets the TXIS and TXE flags
36macro_rules! flush_txdr {
37    ($i2c:expr) => {
38        // If a pending TXIS flag is set, write dummy data to TXDR
39        if $i2c.isr.read().txis().bit_is_set() {
40            $i2c.txdr.write(|w| unsafe { w.txdata().bits(0) });
41        }
42
43        // If TXDR is not flagged as empty, write 1 to flush it
44        if $i2c.isr.read().txe().bit_is_set() {
45            $i2c.isr.write(|w| w.txe().set_bit());
46        }
47    };
48}
49/// Sequence to flush the RXDR register. This resets the TXIS and TXE flags
50macro_rules! flush_rxdr {
51    ($i2c:expr) => {
52        if $i2c.isr.read().rxne().bit_is_set() {
53            // flush
54            let _ = $i2c.rxdr.read().rxdata().bits();
55        };
56    };
57}
58
59/// Check the isr flags, with 2 types of exit
60/// In case of hard errors the error will be returned, also forcing the caller of this function to return
61/// In all other case the macro will return without a result
62macro_rules! busy_wait {
63    ($i2c:expr, $flag:ident, $variant:ident, $idx:ident, $buflen:ident) => {
64        loop {
65            let isr = $i2c.isr.read();
66
67            if isr.$flag().$variant() {
68                break
69            } else  if isr.berr().bit_is_set() {
70                $i2c.icr.write(|w| w.berrcf().set_bit());
71                return Err(Error::BusError);
72            } else if isr.arlo().bit_is_set() {
73                $i2c.icr.write(|w| w.arlocf().set_bit());
74                return Err(Error::ArbitrationLost);
75            } else if isr.nackf().bit_is_set() {
76                $i2c.icr.write(|w| w.nackcf().set_bit());
77                // Make one extra loop to wait on the stop condition
78            } else if isr.tcr().bit_is_set() {
79                // This condition Will only happen when reload == 1 and sbr == 1 (slave) and nbytes was written.
80                // Send a NACK, set nbytes to clear tcr flag
81                $i2c.cr2.modify(|_, w| unsafe {
82                    w.nack().set_bit().nbytes().bits(1 as u8)
83                });
84                // Make one extra loop here to wait on the stop condition
85            } else if isr.addr().bit_is_set() {
86                // in case of a master write_read operation, this flag is the only exit for the function.
87                // Leave the bit set, so it can be detected in the wait_addressed function
88                if $idx == $buflen {
89                    return Ok( () )
90                } else {
91                  return Err(Error::IncorrectFrameSize($idx))
92                }
93            } else if isr.stopf().bit_is_set() {
94                flush_txdr!($i2c);
95                // Clear the stop condition flag
96                $i2c.icr.write(|w| w.stopcf().set_bit());
97                if $idx == $buflen {
98                    return Ok( () )
99                } else
100                if $idx == 0 {
101                    return Err(Error::Nack)
102                } else
103                {
104                  return Err(Error::IncorrectFrameSize($idx))
105                }
106            } else  {
107                // try again
108            }
109        }
110    };
111}
112
113macro_rules! i2c {
114    ($I2CX:ident, $i2cx:ident,
115        sda: [ $($PSDA:ty,)+ ],
116        scl: [ $($PSCL:ty,)+ ],
117    ) => {
118        $(
119            impl SDAPin<$I2CX> for $PSDA {
120                fn setup(&self) {
121                    self.set_alt_mode(AltFunction::AF6)
122                }
123
124                fn release(self) -> Self {
125                    self.into_open_drain_output()
126                }
127            }
128        )+
129
130        $(
131            impl SCLPin<$I2CX> for $PSCL {
132                fn setup(&self) {
133                    self.set_alt_mode(AltFunction::AF6)
134                }
135
136                fn release(self) -> Self {
137                    self.into_open_drain_output()
138                }
139            }
140        )+
141
142        impl I2cExt<$I2CX> for $I2CX {
143            fn i2c<SDA, SCL>(
144                self,
145                sda: SDA,
146                scl: SCL,
147                config: impl Into<Config>,
148                rcc: &mut Rcc,
149            ) -> I2c<$I2CX, SDA, SCL>
150            where
151                SDA: SDAPin<$I2CX>,
152                SCL: SCLPin<$I2CX>,
153            {
154                I2c::$i2cx(self, sda, scl, config, rcc)
155            }
156        }
157
158        impl<SDA, SCL> I2c<$I2CX, SDA, SCL> where
159            SDA: SDAPin<$I2CX>,
160            SCL: SCLPin<$I2CX>
161        {
162            pub fn $i2cx(i2c: $I2CX, sda: SDA, scl: SCL, config: impl Into<Config>, rcc: &mut Rcc) -> Self
163            where
164                SDA: SDAPin<$I2CX>,
165                SCL: SCLPin<$I2CX>,
166            {
167                let config = config.into();
168                $I2CX::enable(rcc);
169                $I2CX::reset(rcc);
170
171                // Make sure the I2C unit is disabled so we can configure it
172                i2c.cr1.modify(|_, w| w.pe().clear_bit());
173
174                // Setup protocol timings
175                let timing_bits = config.timing_bits(rcc.clocks.apb_clk);
176                i2c.timingr.write(|w| unsafe { w.bits(timing_bits) });
177
178                // Enable the I2C processing
179                i2c.cr1.modify(|_, w| unsafe {
180                    w.pe()
181                        .set_bit()
182                        .dnf()
183                        .bits(config.digital_filter)
184                        .anfoff()
185                        .bit(!config.analog_filter)
186                });
187
188                if config.slave_address_1 > 0 {
189                    i2c.oar1.write(|w| unsafe {
190                        w.oa1_7_1().bits(config.slave_address_1 as u8)
191                        .oa1mode().bit(config.address_11bits)
192                        .oa1en().set_bit()
193                    });
194                    // Enable acknowlidge control
195                    i2c.cr1.modify(|_, w|  w.sbc().set_bit() );
196                }
197
198                if config.slave_address_2 > 0 {
199                    i2c.oar2.write( |w| unsafe {
200                        w.oa2msk().bits(  config.slave_address_mask as u8)
201                        .oa2().bits(config.slave_address_2)
202                        .oa2en().set_bit()
203                    });
204                    // Enable acknowlidge control
205                    i2c.cr1.modify(|_, w| w.sbc().set_bit() );
206                }
207
208                // Enable pins
209                sda.setup();
210                scl.setup();
211
212                I2c { i2c, sda, scl }
213            }
214
215            pub fn listen(&mut self, ev: i2c::Event) {
216                match ev {
217                    i2c::Event::AddressMatch => self.i2c.cr1.modify(|_, w| w.addrie().set_bit()),
218                    i2c::Event::Rxne => self.i2c.cr1.modify(|_, w| w.rxie().set_bit()),
219                }
220            }
221
222            pub fn unlisten(&mut self, ev: i2c::Event) {
223                match ev {
224                    i2c::Event::AddressMatch => self.i2c.cr1.modify(|_, w| w.addrie().clear_bit()),
225                    i2c::Event::Rxne => self.i2c.cr1.modify(|_, w| w.rxie().clear_bit()),
226                }
227            }
228
229            pub fn clear_irq(&mut self, ev: i2c::Event) {
230                match ev {
231                    i2c::Event::AddressMatch => self.i2c.icr.write(|w| w.addrcf().set_bit()),
232                    _ => {},
233                }
234            }
235
236            pub fn release(self) -> ($I2CX, SDA, SCL) {
237                (self.i2c, self.sda.release(), self.scl.release())
238            }
239        }
240
241        impl<SDA, SCL> WriteRead for I2c<$I2CX, SDA, SCL> {
242            type Error = Error;
243
244            fn write_read(
245                &mut self,
246                addr: u8,
247                snd_buffer: &[u8],
248                rcv_buffer: &mut [u8],
249            ) -> Result<(), Self::Error> {
250                // TODO support transfers of more than 255 bytes
251                let sndlen = snd_buffer.len();
252                let rcvlen = rcv_buffer.len();
253                assert!(sndlen < 256 && sndlen > 0);
254                assert!(rcvlen < 256 && rcvlen > 0);
255
256                // Wait for any previous address sequence to end automatically.
257                // This could be up to 50% of a bus cycle (ie. up to 0.5/freq)
258                while self.i2c.cr2.read().start().bit_is_set() {};
259
260                // flush i2c tx register
261                self.i2c.isr.write(|w| w.txe().set_bit());
262
263                // Set START and prepare to send `bytes`.
264                // The START bit can be set even if the bus is BUSY or
265                // I2C is in slave mode.
266                self.i2c.cr2.write(|w| unsafe {
267                    w
268                        // Set number of bytes to transfer
269                        .nbytes().bits(sndlen as u8)
270                        // Set address to transfer to/from
271                        .sadd().bits((addr << 1) as u16)
272                        // 7-bit addressing mode
273                        .add10().clear_bit()
274                        // Set transfer direction to write
275                        .rd_wrn().clear_bit()
276                        // Software end mode
277                        .autoend().clear_bit()
278                        .reload().clear_bit()
279                        // Start transfer
280                        .start().set_bit()
281                });
282                let mut idx = 0;
283                // Wait until we are allowed to send data
284                // (START has been ACKed or last byte went through)
285                // macro will return false when the tc bit is set
286                for byte in snd_buffer {
287                    busy_wait!(self.i2c, txis, bit_is_set, idx, sndlen);
288                    // Put byte on the wire
289                    self.i2c.txdr.write(|w| unsafe { w.txdata().bits(*byte) });
290                    idx += 1;
291                }
292                // Wait until the write finishes before beginning to read.
293                let dummy  = 0xFE;
294                busy_wait!(self.i2c, tc, bit_is_set, idx, dummy );
295
296                // reSTART and prepare to receive bytes into `rcv_buffer`
297                self.i2c.cr2.write(|w| unsafe {
298                    w
299                        // Set number of bytes to transfer
300                        .nbytes().bits(rcvlen as u8)
301                        // Set address to transfer to/from
302                        .sadd().bits((addr << 1) as u16)
303                        // 7-bit addressing mode
304                        .add10().clear_bit()
305                        // Set transfer direction to read
306                        .rd_wrn().set_bit()
307                        // Automatic end mode
308                        .autoend().set_bit()
309                        .reload().clear_bit()
310                        // Start transfer
311                        .start().set_bit()
312                });
313
314                idx = 0;
315                loop {
316                    // Wait until we have received something. Handle all state in busy_wait macro
317                    busy_wait!(self.i2c, rxne, bit_is_set, idx, rcvlen);
318                    if idx < rcvlen {
319                        rcv_buffer[idx] = self.i2c.rxdr.read().rxdata().bits();
320                        idx +=1;
321                    }
322                }
323            }
324        }
325
326        impl<SDA, SCL> Write for I2c<$I2CX, SDA, SCL> {
327            type Error = Error;
328
329            fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> {
330                let buflen = bytes.len();
331                assert!(buflen < 256 && buflen > 0);
332
333                // Wait for any previous address sequence to end automatically.
334                // This could be up to 50% of a bus cycle (ie. up to 0.5/freq)
335                while self.i2c.cr2.read().start().bit_is_set() {};
336
337                self.i2c.cr2.modify(|_, w| unsafe {
338                    w
339                        // Start transfer
340                        .start().set_bit()
341                        // Set number of bytes to transfer
342                        .nbytes().bits(buflen as u8)
343                        // Set address to transfer to/from
344                        .sadd().bits((addr << 1) as u16)
345                        // Set transfer direction to write
346                        .rd_wrn().clear_bit()
347                        // Automatic end mode
348                        .autoend().set_bit()
349                        .reload().clear_bit()
350                });
351
352                let mut idx = 0;
353                loop {
354                    // Wait until we are allowed to send data, handle all state in busy_wait macro
355                    busy_wait!(self.i2c, txis, bit_is_set, idx, buflen);
356
357                    // Put byte on the wire
358                    if idx < buflen {
359                        self.i2c.txdr.write(|w| unsafe { w.txdata().bits(bytes[idx]) });
360                        idx += 1;
361                    }
362                }
363            }
364        }
365
366        impl<SDA, SCL> Read for I2c<$I2CX, SDA, SCL> {
367            type Error = Error;
368
369            fn read(&mut self, addr: u8, bytes: &mut [u8]) -> Result<(), Self::Error> {
370                let buflen = bytes.len();
371                // TODO support transfers of more than 255 bytes
372                assert!(buflen < 256 && buflen > 0);
373
374                // Wait for any previous address sequence to end automatically.
375                // This could be up to 50% of a bus cycle (ie. up to 0.5/freq)
376                while self.i2c.cr2.read().start().bit_is_set() {};
377                // Flush rxdr register
378                let _ = self.i2c.rxdr.read().rxdata().bits();
379
380                // Set START and prepare to receive bytes into `buffer`.
381                // The START bit can be set even if the bus
382                // is BUSY or I2C is in slave mode.
383                self.i2c.cr2.modify(|_, w| unsafe {
384                    w
385                        // Start transfer
386                        .start().set_bit()
387                        // Set number of bytes to transfer
388                        .nbytes().bits(buflen as u8)
389                        // Set address to transfer to/from
390                        .sadd().bits((addr << 1) as u16)
391                        // Set transfer direction to read
392                        .rd_wrn().set_bit()
393                        // automatic end mode
394                        .autoend().set_bit()
395                        .reload().clear_bit()
396                    });
397                let mut idx = 0;
398                loop {
399                    // Wait until we have received something
400                    busy_wait!(self.i2c, rxne, bit_is_set, idx, buflen);
401                    if idx < buflen {
402                        bytes[idx] = self.i2c.rxdr.read().rxdata().bits();
403                        idx +=1;
404                    }
405                }
406            }
407        }
408
409        impl<SDA, SCL> I2cSlave for I2c<$I2CX, SDA, SCL> {
410
411            fn slave_sbc(&mut self, sbc_enabled: bool)  {
412                // Enable Slave byte control
413                self.i2c.cr1.modify(|_, w|  w.sbc().bit(sbc_enabled) );
414            }
415
416            fn slave_addressed(&mut self) -> Result<Option<(u16, I2cDirection)>, Error> {
417                if self.i2c.isr.read().addr().bit_is_set() {
418                    let isr = self.i2c.isr.read();
419                    let current_address = isr.addcode().bits() as u16;
420
421                    // if the dir bit is set it is a master write slave read operation
422                    let direction = if isr.dir().bit_is_set() {
423                        I2cDirection::MasterReadSlaveWrite
424                    }  else  {
425                        I2cDirection::MasterWriteSlaveRead
426                    };
427                    // do not yet release the clock stretching here.
428                    // In the slave read function the nbytes is send, for this the addr bit must be set
429                    Ok(Some((current_address, direction)))
430
431                } else {
432                    Ok(None)
433                }
434            }
435
436            fn slave_wait_addressed(&mut self) -> Result<(u16, I2cDirection), Error> {
437                loop {
438                    if let Some(res) = self.slave_addressed()? {
439                        return Ok(res)
440                    }
441                }
442            }
443
444            fn slave_write(&mut self, bytes: &[u8]) -> Result<(), Error> {
445                let buflen = bytes.len();
446                // TODO support transfers of more than 255 bytes
447                assert!(buflen < 256 && buflen > 0);
448
449                // Set the nbytes and prepare to send bytes into `buffer`.
450                self.i2c.cr2.modify(|_, w| unsafe {
451                    w.nbytes().bits( buflen as u8)
452                    .reload().clear_bit()
453                });
454                // flush i2c tx register
455                self.i2c.isr.write(|w| w.txe().set_bit());
456                // end address phase, release clock stretching
457                self.i2c.icr.write(|w| w.addrcf().set_bit() );
458
459                let mut idx = 0;
460                loop {
461                    // wait until we are allowed to send the byte. Handle all state in macro
462                    busy_wait!(self.i2c, txis, bit_is_set, idx, buflen);
463
464                    // Put byte on the wire
465                    if idx < buflen {
466                        self.i2c.txdr.write(|w| unsafe { w.txdata().bits(bytes[idx]) });
467                        idx += 1;
468                    } else {
469                        // we will never reach here. In case the master wants to read more than buflen
470                        // the hardware will send 0xFF
471                        // Also means that on slave side we cannot detect this error case
472                        self.i2c.txdr.write(|w| unsafe { w.txdata().bits(0x21) });
473                    }
474                }
475            }
476
477            fn slave_read(&mut self, bytes: &mut [u8]) -> Result<(), Error> {
478                let buflen = bytes.len();
479                // TODO support transfers of more than 255 bytes
480                assert!(buflen < 256 && buflen > 0);
481
482                // Set the nbytes START and prepare to receive bytes into `buffer`.
483                self.i2c.cr2.modify(|_, w| unsafe {
484                    w
485                        // Set number of bytes to transfer: maximum as all incoming bytes will be ACK'ed
486                        .nbytes().bits(buflen as u8)
487                        // during sending nbytes automatically send a ACK, stretch clock after last byte
488                        .reload().set_bit()
489                });
490                // end address phase, release clock stretching
491                self.i2c.icr.write(|w|
492                    w.addrcf().set_bit()
493                );
494                flush_rxdr!(self.i2c);
495
496                let mut idx = 0;
497                loop  {
498                    // Wait until we have received something.
499                    busy_wait!(self.i2c, rxne, bit_is_set, idx, buflen);
500
501                    // read byte from wire
502                    if idx < buflen {
503                        bytes[idx] = self.i2c.rxdr.read().rxdata().bits();
504                        idx += 1;
505                    }
506                }
507            }
508        }
509    }
510}
511
512i2c!(
513    I2C1,
514    i2c1,
515    sda: [
516        PA10<Output<OpenDrain>>,
517        PB7<Output<OpenDrain>>,
518        PB9<Output<OpenDrain>>,
519    ],
520    scl: [
521        PA9<Output<OpenDrain>>,
522        PB6<Output<OpenDrain>>,
523        PB8<Output<OpenDrain>>,
524    ],
525);
526
527i2c!(
528    I2C2,
529    i2c2,
530    sda: [
531        PA12<Output<OpenDrain>>,
532        PB11<Output<OpenDrain>>,
533        PB14<Output<OpenDrain>>,
534    ],
535    scl: [
536        PA11<Output<OpenDrain>>,
537        PB10<Output<OpenDrain>>,
538        PB13<Output<OpenDrain>>,
539    ],
540);