Skip to content

Commit

Permalink
generic: Implement the I2c trait from embedded-hal 1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
ghismary authored Feb 10, 2024
1 parent e312e6e commit fbb8495
Showing 1 changed file with 59 additions and 0 deletions.
59 changes: 59 additions & 0 deletions avr-hal-generic/src/i2c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
//!
//! Check the documentation of [`I2c`] for details.
use embedded_hal::i2c::SevenBitAddress;

use crate::port;
use core::marker::PhantomData;

Expand Down Expand Up @@ -118,6 +120,28 @@ pub enum Error {
Unknown,
}

impl embedded_hal::i2c::Error for Error {
fn kind(&self) -> embedded_hal::i2c::ErrorKind {
match *self {
Error::ArbitrationLost => embedded_hal::i2c::ErrorKind::ArbitrationLoss,
Error::AddressNack => embedded_hal::i2c::ErrorKind::NoAcknowledge(
embedded_hal::i2c::NoAcknowledgeSource::Address,
),
Error::DataNack => embedded_hal::i2c::ErrorKind::NoAcknowledge(
embedded_hal::i2c::NoAcknowledgeSource::Data,
),
Error::BusError => embedded_hal::i2c::ErrorKind::Bus,
Error::Unknown => embedded_hal::i2c::ErrorKind::Other,
}
}
}

impl<H, I2C: I2cOps<H, SDA, SCL>, SDA, SCL, CLOCK> embedded_hal::i2c::ErrorType
for I2c<H, I2C, SDA, SCL, CLOCK>
{
type Error = Error;
}

/// I2C Transfer Direction
#[derive(ufmt::derive::uDebug, Debug, Clone, Copy, Eq, PartialEq)]
#[repr(u8)]
Expand Down Expand Up @@ -388,6 +412,41 @@ impl<H, I2C: I2cOps<H, SDA, SCL>, SDA, SCL, CLOCK> embedded_hal_v0::blocking::i2
}
}

impl<H, I2C: I2cOps<H, SDA, SCL>, SDA, SCL, CLOCK> embedded_hal::i2c::I2c<SevenBitAddress>
for I2c<H, I2C, SDA, SCL, CLOCK>
{
fn transaction(
&mut self,
address: u8,
operations: &mut [embedded_hal::i2c::Operation<'_>],
) -> Result<(), Self::Error> {
let mut previous_direction = Direction::Read;
for (idx, operation) in operations.iter_mut().enumerate() {
match operation {
embedded_hal::i2c::Operation::Read(buffer) => {
if idx == 0 || previous_direction != Direction::Read {
self.p.raw_start(address, Direction::Read)?;
}
self.p.raw_read(buffer)?;
previous_direction = Direction::Read;
}
embedded_hal::i2c::Operation::Write(bytes) => {
if idx == 0 || previous_direction != Direction::Write {
self.p.raw_start(address, Direction::Write)?;
}
self.p.raw_write(bytes)?;
previous_direction = Direction::Write;
}
}
}
if operations.len() > 0 {
self.p.raw_stop()?;
}

Ok(())
}
}

#[macro_export]
macro_rules! impl_i2c_twi {
(
Expand Down

0 comments on commit fbb8495

Please sign in to comment.