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

make i2c hal methods inherent #431

Merged
merged 1 commit into from
Feb 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

### Changed

- Move `i2c` `embedded-hal` trait impls to `I2c` methods [#431]
- Reexport pins in `gpio` module
- Add channel events, make Event use bitflags (simplify interrupt handling) [#425]
- reexport `digital::v2::PinState` again [#428]
Expand All @@ -32,6 +33,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
[#428]: https://github.com/stm32-rs/stm32f4xx-hal/pull/428
[#425]: https://github.com/stm32-rs/stm32f4xx-hal/pull/425
[#429]: https://github.com/stm32-rs/stm32f4xx-hal/pull/429
[#431]: https://github.com/stm32-rs/stm32f4xx-hal/pull/431

### Changed

Expand Down
117 changes: 117 additions & 0 deletions src/fmpi2c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,4 +200,121 @@ where
let value = self.i2c.rxdr.read().bits() as u8;
Ok(value)
}

pub fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Error> {
// Set up current address for reading
self.i2c.cr2.modify(|_, w| {
w.sadd()
.bits(u16::from(addr) << 1)
.nbytes()
.bits(buffer.len() as u8)
.rd_wrn()
.set_bit()
});

// Send a START condition
self.i2c.cr2.modify(|_, w| w.start().set_bit());

// Send the autoend after setting the start to get a restart
self.i2c.cr2.modify(|_, w| w.autoend().set_bit());

// Now read in all bytes
for c in buffer.iter_mut() {
*c = self.recv_byte()?;
}

// Check and clear flags if they somehow ended up set
self.check_and_clear_error_flags(&self.i2c.isr.read())?;

Ok(())
}

pub fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error> {
// Set up current slave address for writing and enable autoending
self.i2c.cr2.modify(|_, w| {
w.sadd()
.bits(u16::from(addr) << 1)
.nbytes()
.bits(bytes.len() as u8)
.rd_wrn()
.clear_bit()
.autoend()
.set_bit()
});

// Send a START condition
self.i2c.cr2.modify(|_, w| w.start().set_bit());

// Send out all individual bytes
for c in bytes {
self.send_byte(*c)?;
}

// Check and clear flags if they somehow ended up set
self.check_and_clear_error_flags(&self.i2c.isr.read())?;

Ok(())
}

pub fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Error> {
// Set up current slave address for writing and disable autoending
self.i2c.cr2.modify(|_, w| {
w.sadd()
.bits(u16::from(addr) << 1)
.nbytes()
.bits(bytes.len() as u8)
.rd_wrn()
.clear_bit()
.autoend()
.clear_bit()
});

// Send a START condition
self.i2c.cr2.modify(|_, w| w.start().set_bit());

// Wait until the transmit buffer is empty and there hasn't been any error condition
while {
let isr = self.i2c.isr.read();
self.check_and_clear_error_flags(&isr)?;
isr.txis().bit_is_clear() && isr.tc().bit_is_clear()
} {}

// Send out all individual bytes
for c in bytes {
self.send_byte(*c)?;
}

// Wait until data was sent
while {
let isr = self.i2c.isr.read();
self.check_and_clear_error_flags(&isr)?;
isr.tc().bit_is_clear()
} {}

// Set up current address for reading
self.i2c.cr2.modify(|_, w| {
w.sadd()
.bits(u16::from(addr) << 1)
.nbytes()
.bits(buffer.len() as u8)
.rd_wrn()
.set_bit()
});

// Send another START condition
self.i2c.cr2.modify(|_, w| w.start().set_bit());

// Send the autoend after setting the start to get a restart
self.i2c.cr2.modify(|_, w| w.autoend().set_bit());

// Now read in all bytes
for c in buffer.iter_mut() {
*c = self.recv_byte()?;
}

// Check and clear flags if they somehow ended up set
self.check_and_clear_error_flags(&self.i2c.isr.read())?;

Ok(())
}
}
111 changes: 3 additions & 108 deletions src/fmpi2c/hal_02.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,65 +10,7 @@ mod blocking {
type Error = Error;

fn write_read(&mut self, addr: u8, bytes: &[u8], buffer: &mut [u8]) -> Result<(), Error> {
// Set up current slave address for writing and disable autoending
self.i2c.cr2.modify(|_, w| {
w.sadd()
.bits(u16::from(addr) << 1)
.nbytes()
.bits(bytes.len() as u8)
.rd_wrn()
.clear_bit()
.autoend()
.clear_bit()
});

// Send a START condition
self.i2c.cr2.modify(|_, w| w.start().set_bit());

// Wait until the transmit buffer is empty and there hasn't been any error condition
while {
let isr = self.i2c.isr.read();
self.check_and_clear_error_flags(&isr)?;
isr.txis().bit_is_clear() && isr.tc().bit_is_clear()
} {}

// Send out all individual bytes
for c in bytes {
self.send_byte(*c)?;
}

// Wait until data was sent
while {
let isr = self.i2c.isr.read();
self.check_and_clear_error_flags(&isr)?;
isr.tc().bit_is_clear()
} {}

// Set up current address for reading
self.i2c.cr2.modify(|_, w| {
w.sadd()
.bits(u16::from(addr) << 1)
.nbytes()
.bits(buffer.len() as u8)
.rd_wrn()
.set_bit()
});

// Send another START condition
self.i2c.cr2.modify(|_, w| w.start().set_bit());

// Send the autoend after setting the start to get a restart
self.i2c.cr2.modify(|_, w| w.autoend().set_bit());

// Now read in all bytes
for c in buffer.iter_mut() {
*c = self.recv_byte()?;
}

// Check and clear flags if they somehow ended up set
self.check_and_clear_error_flags(&self.i2c.isr.read())?;

Ok(())
self.write_read(addr, bytes, buffer)
}
}

Expand All @@ -79,31 +21,7 @@ mod blocking {
type Error = Error;

fn read(&mut self, addr: u8, buffer: &mut [u8]) -> Result<(), Error> {
// Set up current address for reading
self.i2c.cr2.modify(|_, w| {
w.sadd()
.bits(u16::from(addr) << 1)
.nbytes()
.bits(buffer.len() as u8)
.rd_wrn()
.set_bit()
});

// Send a START condition
self.i2c.cr2.modify(|_, w| w.start().set_bit());

// Send the autoend after setting the start to get a restart
self.i2c.cr2.modify(|_, w| w.autoend().set_bit());

// Now read in all bytes
for c in buffer.iter_mut() {
*c = self.recv_byte()?;
}

// Check and clear flags if they somehow ended up set
self.check_and_clear_error_flags(&self.i2c.isr.read())?;

Ok(())
self.read(addr, buffer)
}
}

Expand All @@ -114,30 +32,7 @@ mod blocking {
type Error = Error;

fn write(&mut self, addr: u8, bytes: &[u8]) -> Result<(), Error> {
// Set up current slave address for writing and enable autoending
self.i2c.cr2.modify(|_, w| {
w.sadd()
.bits(u16::from(addr) << 1)
.nbytes()
.bits(bytes.len() as u8)
.rd_wrn()
.clear_bit()
.autoend()
.set_bit()
});

// Send a START condition
self.i2c.cr2.modify(|_, w| w.start().set_bit());

// Send out all individual bytes
for c in bytes {
self.send_byte(*c)?;
}

// Check and clear flags if they somehow ended up set
self.check_and_clear_error_flags(&self.i2c.isr.read())?;

Ok(())
self.write(addr, bytes)
}
}
}
Loading