Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

various i2c fixes #282

Merged
merged 5 commits into from
Nov 6, 2020
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 21 additions & 7 deletions src/i2c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,12 +436,17 @@ where
last_ret
}

fn write_without_stop(&mut self, addr: u8, bytes: &[u8]) -> NbResult<(), Error> {
self.send_start_and_wait()?;
fn send_addr_and_wait(&mut self, addr: u8, read: bool) -> NbResult<(), Error> {
self.nb.i2c.sr1.read();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not directly related to the PR, but I'm now becomming unsure about what this is doing here. My best guess is that it tries to clear the status registers, but clearly that's not done since the first commit in the PR is needed...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm; looking at the datasheet i'm not entirely sure if it's needed here either; Fwiw the relevant parts are:

Then the master waits for a read of the SR1 register followed by a write in the DR register
with the Slave address (see Figure 273 and Figure 274 Transfer sequencing EV5).

with EV5 being EV5: SB=1, cleared by reading SR1 register followed by writing DR register with Address.

But ofcourse the send_start_and_wait is already reading SR1 while polling for the flag; So it's probably not needed here.

Overall it seems some bits of sr1 are persistents (the error bits in particular) while others gets cleared on read

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. I think the best course of action here is to break this into its own issue and maybe fix it later since doing the wrong thing could break things subtly.

self.nb.send_addr(addr, false);
self.nb.send_addr(addr, read);
let ret = busy_wait_cycles!(wait_for_flag!(self.nb.i2c, addr), self.addr_timeout);
if ret == Err(Other(Error::Acknowledge)) {
self.nb.send_stop();
}
ret
}

busy_wait_cycles!(wait_for_flag!(self.nb.i2c, addr), self.addr_timeout)?;
fn write_bytes_and_wait(&mut self, bytes: &[u8]) -> NbResult<(), Error> {
self.nb.i2c.sr1.read();
self.nb.i2c.sr2.read();

Expand All @@ -455,6 +460,17 @@ where

Ok(())
}

fn write_without_stop(&mut self, addr: u8, bytes: &[u8]) -> NbResult<(), Error> {
self.send_start_and_wait()?;
self.send_addr_and_wait(addr, false)?;

let ret = self.write_bytes_and_wait(bytes);
if ret == Err(Other(Error::Acknowledge)) {
self.nb.send_stop();
}
ret
}
}

impl<I2C, PINS> Write for BlockingI2c<I2C, PINS>
Expand All @@ -480,9 +496,7 @@ where

fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
self.send_start_and_wait()?;
self.nb.i2c.sr1.read();
self.nb.send_addr(addr, true);
busy_wait_cycles!(wait_for_flag!(self.nb.i2c, addr), self.addr_timeout)?;
self.send_addr_and_wait(addr, true)?;

match buffer.len() {
1 => {
Expand Down