Skip to content

Commit c61beeb

Browse files
authored
Merge pull request #169 from stm32-rs/stop-after-i2c-write
Move I2C write implementation into write_bytes function
2 parents 6ec8632 + 4c93814 commit c61beeb

File tree

2 files changed

+43
-27
lines changed

2 files changed

+43
-27
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased]
99

10+
### Fixed
11+
12+
- Make sure that I2C writes are concluded with a STOP condition
13+
1014
## [v0.8.2] - 2020-05-29
1115

1216
### Added

src/i2c.rs

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,8 @@ where
695695
}
696696

697697
trait I2cCommon {
698+
fn write_bytes(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error>;
699+
698700
fn send_byte(&self, byte: u8) -> Result<(), Error>;
699701

700702
fn recv_byte(&self) -> Result<u8, Error>;
@@ -704,6 +706,39 @@ impl<I2C, PINS> I2cCommon for I2c<I2C, PINS>
704706
where
705707
I2C: Deref<Target = i2c1::RegisterBlock>,
706708
{
709+
fn write_bytes(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error> {
710+
// Send a START condition
711+
self.i2c.cr1.modify(|_, w| w.start().set_bit());
712+
713+
// Wait until START condition was generated
714+
while self.i2c.sr1.read().sb().bit_is_clear() {}
715+
716+
// Also wait until signalled we're master and everything is waiting for us
717+
while {
718+
let sr2 = self.i2c.sr2.read();
719+
sr2.msl().bit_is_clear() && sr2.busy().bit_is_clear()
720+
} {}
721+
722+
// Set up current address, we're trying to talk to
723+
self.i2c
724+
.dr
725+
.write(|w| unsafe { w.bits(u32::from(addr) << 1) });
726+
727+
// Wait until address was sent
728+
while self.i2c.sr1.read().addr().bit_is_clear() {}
729+
730+
// Clear condition by reading SR2
731+
self.i2c.sr2.read();
732+
733+
// Send bytes
734+
for c in bytes {
735+
self.send_byte(*c)?;
736+
}
737+
738+
// Fallthrough is success
739+
Ok(())
740+
}
741+
707742
fn send_byte(&self, byte: u8) -> Result<(), Error> {
708743
// Wait until we're ready for sending
709744
while self.i2c.sr1.read().tx_e().bit_is_clear() {}
@@ -740,7 +775,7 @@ where
740775
type Error = Error;
741776

742777
fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Self::Error> {
743-
self.write(addr, bytes)?;
778+
self.write_bytes(addr, bytes)?;
744779
self.read(addr, buffer)?;
745780

746781
Ok(())
@@ -754,33 +789,10 @@ where
754789
type Error = Error;
755790

756791
fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Self::Error> {
757-
// Send a START condition
758-
self.i2c.cr1.modify(|_, w| w.start().set_bit());
759-
760-
// Wait until START condition was generated
761-
while self.i2c.sr1.read().sb().bit_is_clear() {}
792+
self.write_bytes(addr, bytes)?;
762793

763-
// Also wait until signalled we're master and everything is waiting for us
764-
while {
765-
let sr2 = self.i2c.sr2.read();
766-
sr2.msl().bit_is_clear() && sr2.busy().bit_is_clear()
767-
} {}
768-
769-
// Set up current address, we're trying to talk to
770-
self.i2c
771-
.dr
772-
.write(|w| unsafe { w.bits(u32::from(addr) << 1) });
773-
774-
// Wait until address was sent
775-
while self.i2c.sr1.read().addr().bit_is_clear() {}
776-
777-
// Clear condition by reading SR2
778-
self.i2c.sr2.read();
779-
780-
// Send bytes
781-
for c in bytes {
782-
self.send_byte(*c)?;
783-
}
794+
// Send a STOP condition
795+
self.i2c.cr1.modify(|_, w| w.stop().set_bit());
784796

785797
// Fallthrough is success
786798
Ok(())

0 commit comments

Comments
 (0)